diff --git a/man/rustc.1 b/man/rustc.1 index 3ac79ecae64e5..56e3fe0515eb9 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -53,7 +53,9 @@ Comma separated list of types of crates for the compiler to emit. Specify the name of the crate being built. .TP \fB\-\-emit\fR [asm|llvm\-bc|llvm\-ir|obj|link|dep\-info] -Configure the output that \fBrustc\fR will produce. +Configure the output that \fBrustc\fR will produce. Each option may also be of +the form KIND=PATH to specify the explicit output location for that particular +emission kind. .TP \fB\-\-print\fR [crate\-name|file\-names|sysroot] Comma separated list of compiler information to print on stdout. @@ -66,7 +68,8 @@ Equivalent to \fI\-C\ opt\-level=2\fR. .TP \fB\-o\fR \fIFILENAME\fR Write output to \fIFILENAME\fR. -Ignored if multiple \fI\-\-emit\fR outputs are specified. +Ignored if multiple \fI\-\-emit\fR outputs are specified which don't have an +explicit path otherwise. .TP \fB\-\-out\-dir\fR \fIDIR\fR Write output to compiler\[hy]chosen filename in \fIDIR\fR. diff --git a/src/doc/reference.md b/src/doc/reference.md index db3f4b064b1fb..2fce37eccae1c 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -77,9 +77,12 @@ An identifier is any nonempty Unicode[^non_ascii_idents] string of the following gated. This is expected to improve soon. Either + * The first character has property `XID_start` * The remaining characters have property `XID_continue` + Or + * The first character is `_` * The identifier is more than one character, `_` alone is not an identifier * The remaining characters have property `XID_continue` diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md index 5afb9b7f868c8..1e1b2e2d4588b 100644 --- a/src/doc/trpl/documentation.md +++ b/src/doc/trpl/documentation.md @@ -279,6 +279,8 @@ println!("{}", x + y); Here's an explanation, rendered: +------------------------------------------------------------------------------- + First, we set `x` to five: ```rust @@ -303,8 +305,12 @@ Finally, we print the sum of `x` and `y`: println!("{}", x + y); ``` +------------------------------------------------------------------------------- + Here's the same explanation, in raw text: +------------------------------------------------------------------------------- + > First, we set `x` to five: > > ```text @@ -329,6 +335,8 @@ Here's the same explanation, in raw text: > println!("{}", x + y); > ``` +------------------------------------------------------------------------------- + By repeating all parts of the example, you can ensure that your example still compiles, while only showing the parts that are relevant to that part of your explanation. diff --git a/src/libcore/char.rs b/src/libcore/char.rs index dfcbfd476bc3f..ccce2ad22ddc2 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -185,9 +185,7 @@ impl CharExt for char { '\t' => EscapeDefaultState::Backslash('t'), '\r' => EscapeDefaultState::Backslash('r'), '\n' => EscapeDefaultState::Backslash('n'), - '\\' => EscapeDefaultState::Backslash('\\'), - '\'' => EscapeDefaultState::Backslash('\''), - '"' => EscapeDefaultState::Backslash('"'), + '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self), '\x20' ... '\x7e' => EscapeDefaultState::Char(self), _ => EscapeDefaultState::Unicode(self.escape_unicode()) }; @@ -344,6 +342,22 @@ impl Iterator for EscapeUnicode { EscapeUnicodeState::Done => None, } } + + fn size_hint(&self) -> (usize, Option) { + let mut n = 0; + while (self.c as usize) >> (4 * (n + 1)) != 0 { + n += 1; + } + let n = match self.state { + EscapeUnicodeState::Backslash => n + 5, + EscapeUnicodeState::Type => n + 4, + EscapeUnicodeState::LeftBrace => n + 3, + EscapeUnicodeState::Value(offset) => offset + 2, + EscapeUnicodeState::RightBrace => 1, + EscapeUnicodeState::Done => 0, + }; + (n, Some(n)) + } } /// An iterator over the characters that represent a `char`, escaped @@ -377,7 +391,16 @@ impl Iterator for EscapeDefault { Some(c) } EscapeDefaultState::Done => None, - EscapeDefaultState::Unicode(ref mut iter) => iter.next() + EscapeDefaultState::Unicode(ref mut iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self.state { + EscapeDefaultState::Char(_) => (1, Some(1)), + EscapeDefaultState::Backslash(_) => (2, Some(2)), + EscapeDefaultState::Unicode(ref iter) => iter.size_hint(), + EscapeDefaultState::Done => (0, Some(0)), } } } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 69fa0fa1609e3..f6053a75f1f90 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1332,11 +1332,21 @@ impl Display for bool { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for str { fn fmt(&self, f: &mut Formatter) -> Result { - try!(write!(f, "\"")); - for c in self.chars().flat_map(|c| c.escape_default()) { - try!(f.write_char(c)) + try!(f.write_char('"')); + let mut from = 0; + for (i, c) in self.char_indices() { + let esc = c.escape_default(); + // If char needs escaping, flush backlog so far and write, else skip + if esc.size_hint() != (1, Some(1)) { + try!(f.write_str(&self[from..i])); + for c in esc { + try!(f.write_char(c)); + } + from = i + c.len_utf8(); + } } - write!(f, "\"") + try!(f.write_str(&self[from..])); + f.write_char('"') } } @@ -1350,12 +1360,11 @@ impl Display for str { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for char { fn fmt(&self, f: &mut Formatter) -> Result { - use char::CharExt; - try!(write!(f, "'")); + try!(f.write_char('\'')); for c in self.escape_default() { try!(f.write_char(c)) } - write!(f, "'") + f.write_char('\'') } } diff --git a/src/librustc/front/check_attr.rs b/src/librustc/front/check_attr.rs new file mode 100644 index 0000000000000..cca14f1fbf2a3 --- /dev/null +++ b/src/librustc/front/check_attr.rs @@ -0,0 +1,110 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use session::Session; + +use syntax::ast; +use syntax::attr::AttrMetaMethods; +use syntax::visit; +use syntax::visit::Visitor; + +#[derive(Copy, Clone, PartialEq)] +enum Target { + Fn, + Struct, + Enum, + Other, +} + +impl Target { + fn from_item(item: &ast::Item) -> Target { + match item.node { + ast::ItemFn(..) => Target::Fn, + ast::ItemStruct(..) => Target::Struct, + ast::ItemEnum(..) => Target::Enum, + _ => Target::Other, + } + } +} + +struct CheckAttrVisitor<'a> { + sess: &'a Session, +} + +impl<'a> CheckAttrVisitor<'a> { + fn check_inline(&self, attr: &ast::Attribute, target: Target) { + if target != Target::Fn { + self.sess.span_err( + attr.span, + "attribute should be applied to function"); + } + } + + fn check_repr(&self, attr: &ast::Attribute, target: Target) { + let words = match attr.meta_item_list() { + Some(words) => words, + None => { + return; + } + }; + for word in words { + let word: &str = &word.name(); + match word { + "C" => { + if target != Target::Struct && target != Target::Enum { + self.sess.span_err( + attr.span, + "attribute should be applied to struct or enum"); + } + } + "packed" | + "simd" => { + if target != Target::Struct { + self.sess.span_err( + attr.span, + "attribute should be applied to struct"); + } + } + "i8" | "u8" | "i16" | "u16" | + "i32" | "u32" | "i64" | "u64" | + "isize" | "usize" => { + if target != Target::Enum { + self.sess.span_err( + attr.span, + "attribute should be applied to enum"); + } + } + _ => (), + } + } + } + + fn check_attribute(&self, attr: &ast::Attribute, target: Target) { + let name: &str = &attr.name(); + match name { + "inline" => self.check_inline(attr, target), + "repr" => self.check_repr(attr, target), + _ => (), + } + } +} + +impl<'a, 'v> Visitor<'v> for CheckAttrVisitor<'a> { + fn visit_item(&mut self, item: &ast::Item) { + let target = Target::from_item(item); + for attr in &item.attrs { + self.check_attribute(attr, target); + } + } +} + +pub fn check_crate(sess: &Session, krate: &ast::Crate) { + visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate); +} diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 0bbb57afc278e..e08dc2acbc088 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -101,6 +101,7 @@ pub mod back { } pub mod front { + pub mod check_attr; pub mod map; } diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 3b44dc12ac197..84673b010332f 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1394,9 +1394,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.resolve_type_vars_or_error(&ty) } + pub fn tables_are_tcx_tables(&self) -> bool { + let tables: &RefCell = &self.tables; + let tcx_tables: &RefCell = &self.tcx.tables; + tables as *const _ == tcx_tables as *const _ + } + pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { let ty = self.resolve_type_vars_if_possible(&ty); - if ty.needs_infer() { + if ty.needs_infer() || + (ty.has_closure_types() && !self.tables_are_tcx_tables()) { // this can get called from typeck (by euv), and moves_by_default // rightly refuses to work with inference variables, but // moves_by_default has a cache, which we want to use in other diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index dcc4ca137ead9..0739420ea4d68 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -15,7 +15,6 @@ pub use self::EntryFnType::*; pub use self::CrateType::*; pub use self::Passes::*; pub use self::OptLevel::*; -pub use self::OutputType::*; pub use self::DebugInfoLevel::*; use session::{early_error, early_warn, Session}; @@ -62,14 +61,14 @@ pub enum DebugInfoLevel { FullDebugInfo, } -#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub enum OutputType { - OutputTypeBitcode, - OutputTypeAssembly, - OutputTypeLlvmAssembly, - OutputTypeObject, - OutputTypeExe, - OutputTypeDepInfo, + Bitcode, + Assembly, + LlvmAssembly, + Object, + Exe, + DepInfo, } #[derive(Clone)] @@ -85,7 +84,7 @@ pub struct Options { pub lint_opts: Vec<(String, lint::Level)>, pub lint_cap: Option, pub describe_lints: bool, - pub output_types: Vec, + pub output_types: HashMap>, // This was mutable for rustpkg, which updates search paths based on the // parsed code. It remains mutable in case its replacements wants to use // this. @@ -105,8 +104,6 @@ pub struct Options { pub always_build_mir: bool, pub no_analysis: bool, pub debugging_opts: DebuggingOptions, - /// Whether to write dependency files. It's (enabled, optional filename). - pub write_dependency_info: (bool, Option), pub prints: Vec, pub cg: CodegenOptions, pub color: ColorConfig, @@ -151,26 +148,25 @@ pub struct OutputFilenames { pub out_filestem: String, pub single_output_file: Option, pub extra: String, + pub outputs: HashMap>, } impl OutputFilenames { pub fn path(&self, flavor: OutputType) -> PathBuf { - match self.single_output_file { - Some(ref path) => return path.clone(), - None => {} - } - self.temp_path(flavor) + self.outputs.get(&flavor).and_then(|p| p.to_owned()) + .or_else(|| self.single_output_file.clone()) + .unwrap_or_else(|| self.temp_path(flavor)) } pub fn temp_path(&self, flavor: OutputType) -> PathBuf { let base = self.out_directory.join(&self.filestem()); match flavor { - OutputTypeBitcode => base.with_extension("bc"), - OutputTypeAssembly => base.with_extension("s"), - OutputTypeLlvmAssembly => base.with_extension("ll"), - OutputTypeObject => base.with_extension("o"), - OutputTypeDepInfo => base.with_extension("d"), - OutputTypeExe => base, + OutputType::Bitcode => base.with_extension("bc"), + OutputType::Assembly => base.with_extension("s"), + OutputType::LlvmAssembly => base.with_extension("ll"), + OutputType::Object => base.with_extension("o"), + OutputType::DepInfo => base.with_extension("d"), + OutputType::Exe => base, } } @@ -206,7 +202,7 @@ pub fn basic_options() -> Options { lint_opts: Vec::new(), lint_cap: None, describe_lints: false, - output_types: Vec::new(), + output_types: HashMap::new(), search_paths: SearchPaths::new(), maybe_sysroot: None, target_triple: host_triple().to_string(), @@ -218,7 +214,6 @@ pub fn basic_options() -> Options { always_build_mir: false, no_analysis: false, debugging_opts: basic_debugging_options(), - write_dependency_info: (false, None), prints: Vec::new(), cg: basic_codegen_options(), color: Auto, @@ -907,31 +902,30 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { unsafe { llvm::LLVMSetDebug(1); } } - let mut output_types = Vec::new(); + let mut output_types = HashMap::new(); if !debugging_opts.parse_only && !no_trans { - let unparsed_output_types = matches.opt_strs("emit"); - for unparsed_output_type in &unparsed_output_types { - for part in unparsed_output_type.split(',') { - let output_type = match part { - "asm" => OutputTypeAssembly, - "llvm-ir" => OutputTypeLlvmAssembly, - "llvm-bc" => OutputTypeBitcode, - "obj" => OutputTypeObject, - "link" => OutputTypeExe, - "dep-info" => OutputTypeDepInfo, - _ => { + for list in matches.opt_strs("emit") { + for output_type in list.split(',') { + let mut parts = output_type.splitn(2, '='); + let output_type = match parts.next().unwrap() { + "asm" => OutputType::Assembly, + "llvm-ir" => OutputType::LlvmAssembly, + "llvm-bc" => OutputType::Bitcode, + "obj" => OutputType::Object, + "link" => OutputType::Exe, + "dep-info" => OutputType::DepInfo, + part => { early_error(color, &format!("unknown emission type: `{}`", part)) } }; - output_types.push(output_type) + let path = parts.next().map(PathBuf::from); + output_types.insert(output_type, path); } } }; - output_types.sort(); - output_types.dedup(); if output_types.is_empty() { - output_types.push(OutputTypeExe); + output_types.insert(OutputType::Exe, None); } let cg = build_codegen_options(matches, color); @@ -1004,7 +998,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let cfg = parse_cfgspecs(matches.opt_strs("cfg")); let test = matches.opt_present("test"); - let write_dependency_info = (output_types.contains(&OutputTypeDepInfo), None); let prints = matches.opt_strs("print").into_iter().map(|s| { match &*s { @@ -1059,7 +1052,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { always_build_mir: always_build_mir, no_analysis: no_analysis, debugging_opts: debugging_opts, - write_dependency_info: write_dependency_info, prints: prints, cg: cg, color: color, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d004d557856b7..97fb6c3d26fc9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -12,7 +12,7 @@ use rustc::front; use rustc::front::map as hir_map; use rustc_mir as mir; use rustc::session::Session; -use rustc::session::config::{self, Input, OutputFilenames}; +use rustc::session::config::{self, Input, OutputFilenames, OutputType}; use rustc::session::search_paths::PathKind; use rustc::lint; use rustc::metadata; @@ -36,6 +36,7 @@ use super::Compilation; use serialize::json; +use std::collections::HashMap; use std::env; use std::ffi::{OsString, OsStr}; use std::fs; @@ -117,7 +118,7 @@ pub fn compile_input(sess: Session, let arenas = ty::CtxtArenas::new(); let ast_map = make_map(&sess, &mut hir_forest); - write_out_deps(&sess, input, &outputs, &id[..]); + write_out_deps(&sess, &outputs, &id); controller_entry_point!(after_write_deps, sess, @@ -129,6 +130,10 @@ pub fn compile_input(sess: Session, &ast_map.krate(), &id[..])); + time(sess.time_passes(), "attribute checking", || { + front::check_attr::check_crate(&sess, &expanded_crate); + }); + time(sess.time_passes(), "early lint checks", || { lint::check_ast_crate(&sess, &expanded_crate) }); @@ -807,16 +812,16 @@ pub fn phase_5_run_llvm_passes(sess: &Session, trans: &trans::CrateTranslation, outputs: &OutputFilenames) { if sess.opts.cg.no_integrated_as { - let output_type = config::OutputTypeAssembly; - + let mut map = HashMap::new(); + map.insert(OutputType::Assembly, None); time(sess.time_passes(), "LLVM passes", || - write::run_passes(sess, trans, &[output_type], outputs)); + write::run_passes(sess, trans, &map, outputs)); write::run_assembler(sess, outputs); // Remove assembly source, unless --save-temps was specified if !sess.opts.cg.save_temps { - fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap(); + fs::remove_file(&outputs.temp_path(OutputType::Assembly)).unwrap(); } } else { time(sess.time_passes(), "LLVM passes", || @@ -847,16 +852,12 @@ fn escape_dep_filename(filename: &str) -> String { filename.replace(" ", "\\ ") } -fn write_out_deps(sess: &Session, - input: &Input, - outputs: &OutputFilenames, - id: &str) { - +fn write_out_deps(sess: &Session, outputs: &OutputFilenames, id: &str) { let mut out_filenames = Vec::new(); - for output_type in &sess.opts.output_types { + for output_type in sess.opts.output_types.keys() { let file = outputs.path(*output_type); match *output_type { - config::OutputTypeExe => { + OutputType::Exe => { for output in sess.crate_types.borrow().iter() { let p = link::filename_for_input(sess, *output, id, outputs); @@ -867,23 +868,11 @@ fn write_out_deps(sess: &Session, } } - // Write out dependency rules to the dep-info file if requested with - // --dep-info - let deps_filename = match sess.opts.write_dependency_info { - // Use filename from --dep-file argument if given - (true, Some(ref filename)) => filename.clone(), - // Use default filename: crate source filename with extension replaced - // by ".d" - (true, None) => match *input { - Input::File(..) => outputs.with_extension("d"), - Input::Str(..) => { - sess.warn("can not write --dep-info without a filename \ - when compiling stdin."); - return - }, - }, - _ => return, - }; + // Write out dependency rules to the dep-info file if requested + if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { + return + } + let deps_filename = outputs.path(OutputType::DepInfo); let result = (|| -> io::Result<()> { // Build a list of files used to compile the output and @@ -896,9 +885,16 @@ fn write_out_deps(sess: &Session, .collect(); let mut file = try!(fs::File::create(&deps_filename)); for path in &out_filenames { - try!(write!(&mut file, + try!(write!(file, "{}: {}\n\n", path.display(), files.join(" "))); } + + // Emit a fake target for each input file to the compilation. This + // prevents `make` from spitting out an error if a file is later + // deleted. For more info see #28735 + for path in files { + try!(writeln!(file, "{}:", path)); + } Ok(()) })(); @@ -1012,11 +1008,15 @@ pub fn build_output_filenames(input: &Input, out_filestem: stem, single_output_file: None, extra: sess.opts.cg.extra_filename.clone(), + outputs: sess.opts.output_types.clone(), } } Some(ref out_file) => { - let ofile = if sess.opts.output_types.len() > 1 { + let unnamed_output_types = sess.opts.output_types.values() + .filter(|a| a.is_none()) + .count(); + let ofile = if unnamed_output_types > 1 { sess.warn("ignoring specified output filename because multiple \ outputs were requested"); None @@ -1035,6 +1035,7 @@ pub fn build_output_filenames(input: &Input, .to_str().unwrap().to_string(), single_output_file: ofile, extra: sess.opts.cg.extra_filename.clone(), + outputs: sess.opts.output_types.clone(), } } } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 7d9c74fe48702..d5644d49e1ea4 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -63,7 +63,7 @@ use rustc_resolve as resolve; use rustc_trans::back::link; use rustc_trans::save; use rustc::session::{config, Session, build_session}; -use rustc::session::config::{Input, PrintRequest}; +use rustc::session::config::{Input, PrintRequest, OutputType}; use rustc::lint::Lint; use rustc::lint; use rustc::metadata; @@ -382,7 +382,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { control.after_analysis.stop = Compilation::Stop; } - if !sess.opts.output_types.iter().any(|&i| i == config::OutputTypeExe) { + if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) { control.after_llvm.stop = Compilation::Stop; } diff --git a/src/librustc_front/attr.rs b/src/librustc_front/attr.rs index 9e1e3c0e293ac..1a564eb28a3a0 100644 --- a/src/librustc_front/attr.rs +++ b/src/librustc_front/attr.rs @@ -300,7 +300,6 @@ pub enum InlineAttr { /// Determine what `#[inline]` attribute is present in `attrs`, if any. pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr { - // FIXME (#2809)---validate the usage of #[inline] and #[inline] attrs.iter().fold(InlineAttr::None, |ia,attr| { match attr.node.value.node { MetaWord(ref n) if *n == "inline" => { diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index eaa947150b04e..512f2a9c59f6b 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -16,7 +16,7 @@ use super::msvc; use super::svh::Svh; use session::config; use session::config::NoDebugInfo; -use session::config::{OutputFilenames, Input, OutputTypeBitcode, OutputTypeExe, OutputTypeObject}; +use session::config::{OutputFilenames, Input, OutputType}; use session::search_paths::PathKind; use session::Session; use metadata::common::LinkMeta; @@ -491,7 +491,7 @@ pub fn filename_for_input(sess: &Session, } config::CrateTypeExecutable => { let suffix = &sess.target.target.options.exe_suffix; - let out_filename = outputs.path(OutputTypeExe); + let out_filename = outputs.path(OutputType::Exe); if suffix.is_empty() { out_filename.to_path_buf() } else { @@ -532,10 +532,12 @@ fn link_binary_output(sess: &Session, outputs: &OutputFilenames, crate_name: &str) -> PathBuf { let objects = object_filenames(sess, outputs); - let out_filename = match outputs.single_output_file { - Some(ref file) => file.clone(), - None => filename_for_input(sess, crate_type, crate_name, outputs), - }; + let default_filename = filename_for_input(sess, crate_type, crate_name, + outputs); + let out_filename = outputs.outputs.get(&OutputType::Exe) + .and_then(|s| s.to_owned()) + .or_else(|| outputs.single_output_file.clone()) + .unwrap_or(default_filename); // Make sure files are writeable. Mac, FreeBSD, and Windows system linkers // check this already -- however, the Linux linker will happily overwrite a @@ -576,7 +578,7 @@ fn link_binary_output(sess: &Session, fn object_filenames(sess: &Session, outputs: &OutputFilenames) -> Vec { (0..sess.opts.cg.codegen_units).map(|i| { let ext = format!("{}.o", i); - outputs.temp_path(OutputTypeObject).with_extension(&ext) + outputs.temp_path(OutputType::Object).with_extension(&ext) }).collect() } @@ -723,7 +725,7 @@ fn link_rlib<'a>(sess: &'a Session, // See the bottom of back::write::run_passes for an explanation // of when we do and don't keep .0.bc files around. let user_wants_numbered_bitcode = - sess.opts.output_types.contains(&OutputTypeBitcode) && + sess.opts.output_types.contains_key(&OutputType::Bitcode) && sess.opts.cg.codegen_units > 1; if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode { remove(sess, &bc_filename); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 94e2891f40fa0..1fbbf82ba38e4 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -12,7 +12,7 @@ use back::lto; use back::link::{get_linker, remove}; use session::config::{OutputFilenames, Passes, SomePasses, AllPasses}; use session::Session; -use session::config; +use session::config::{self, OutputType}; use llvm; use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef}; use llvm::SMDiagnosticRef; @@ -23,9 +23,10 @@ use syntax::codemap; use syntax::diagnostic; use syntax::diagnostic::{Emitter, Handler, Level}; +use std::collections::HashMap; use std::ffi::{CStr, CString}; use std::fs; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::ptr; use std::str; use std::sync::{Arc, Mutex}; @@ -33,15 +34,6 @@ use std::sync::mpsc::channel; use std::thread; use libc::{self, c_uint, c_int, c_void}; -#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)] -pub enum OutputType { - OutputTypeBitcode, - OutputTypeAssembly, - OutputTypeLlvmAssembly, - OutputTypeObject, - OutputTypeExe, -} - pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! { unsafe { let cstr = llvm::LLVMRustGetLastError(); @@ -571,7 +563,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, pub fn run_passes(sess: &Session, trans: &CrateTranslation, - output_types: &[config::OutputType], + output_types: &HashMap>, crate_output: &OutputFilenames) { // It's possible that we have `codegen_units > 1` but only one item in // `trans.modules`. We could theoretically proceed and do LTO in that @@ -611,32 +603,32 @@ pub fn run_passes(sess: &Session, // archive in order to allow LTO against it. let needs_crate_bitcode = sess.crate_types.borrow().contains(&config::CrateTypeRlib) && - sess.opts.output_types.contains(&config::OutputTypeExe); + sess.opts.output_types.contains_key(&OutputType::Exe); let needs_crate_object = - sess.opts.output_types.contains(&config::OutputTypeExe); + sess.opts.output_types.contains_key(&OutputType::Exe); if needs_crate_bitcode { modules_config.emit_bc = true; } - for output_type in output_types { + for output_type in output_types.keys() { match *output_type { - config::OutputTypeBitcode => { modules_config.emit_bc = true; }, - config::OutputTypeLlvmAssembly => { modules_config.emit_ir = true; }, - config::OutputTypeAssembly => { + OutputType::Bitcode => { modules_config.emit_bc = true; }, + OutputType::LlvmAssembly => { modules_config.emit_ir = true; }, + OutputType::Assembly => { modules_config.emit_asm = true; // If we're not using the LLVM assembler, this function // could be invoked specially with output_type_assembly, so // in this case we still want the metadata object file. - if !sess.opts.output_types.contains(&config::OutputTypeAssembly) { + if !sess.opts.output_types.contains_key(&OutputType::Assembly) { metadata_config.emit_obj = true; } }, - config::OutputTypeObject => { modules_config.emit_obj = true; }, - config::OutputTypeExe => { + OutputType::Object => { modules_config.emit_obj = true; }, + OutputType::Exe => { modules_config.emit_obj = true; metadata_config.emit_obj = true; }, - config::OutputTypeDepInfo => {} + OutputType::DepInfo => {} } } @@ -686,8 +678,9 @@ pub fn run_passes(sess: &Session, } }; - let copy_if_one_unit = |ext: &str, output_type: config::OutputType, keep_numbered: bool| { - // Three cases: + let copy_if_one_unit = |ext: &str, + output_type: OutputType, + keep_numbered: bool| { if sess.opts.cg.codegen_units == 1 { // 1) Only one codegen unit. In this case it's no difficulty // to copy `foo.0.x` to `foo.x`. @@ -697,17 +690,20 @@ pub fn run_passes(sess: &Session, // The user just wants `foo.x`, not `foo.0.x`. remove(sess, &crate_output.with_extension(ext)); } + } else if crate_output.outputs.contains_key(&output_type) { + // 2) Multiple codegen units, with `--emit foo=some_name`. We have + // no good solution for this case, so warn the user. + sess.warn(&format!("ignoring emit path because multiple .{} files \ + were produced", ext)); + } else if crate_output.single_output_file.is_some() { + // 3) Multiple codegen units, with `-o some_name`. We have + // no good solution for this case, so warn the user. + sess.warn(&format!("ignoring -o because multiple .{} files \ + were produced", ext)); } else { - if crate_output.single_output_file.is_some() { - // 2) Multiple codegen units, with `-o some_name`. We have - // no good solution for this case, so warn the user. - sess.warn(&format!("ignoring -o because multiple .{} files were produced", - ext)); - } else { - // 3) Multiple codegen units, but no `-o some_name`. We - // just leave the `foo.0.x` files in place. - // (We don't have to do any work in this case.) - } + // 4) Multiple codegen units, but no explicit name. We + // just leave the `foo.0.x` files in place. + // (We don't have to do any work in this case.) } }; @@ -716,27 +712,27 @@ pub fn run_passes(sess: &Session, // to get rid of it. let mut user_wants_bitcode = false; let mut user_wants_objects = false; - for output_type in output_types { + for output_type in output_types.keys() { match *output_type { - config::OutputTypeBitcode => { + OutputType::Bitcode => { user_wants_bitcode = true; // Copy to .bc, but always keep the .0.bc. There is a later // check to figure out if we should delete .0.bc files, or keep // them for making an rlib. - copy_if_one_unit("0.bc", config::OutputTypeBitcode, true); + copy_if_one_unit("0.bc", OutputType::Bitcode, true); } - config::OutputTypeLlvmAssembly => { - copy_if_one_unit("0.ll", config::OutputTypeLlvmAssembly, false); + OutputType::LlvmAssembly => { + copy_if_one_unit("0.ll", OutputType::LlvmAssembly, false); } - config::OutputTypeAssembly => { - copy_if_one_unit("0.s", config::OutputTypeAssembly, false); + OutputType::Assembly => { + copy_if_one_unit("0.s", OutputType::Assembly, false); } - config::OutputTypeObject => { + OutputType::Object => { user_wants_objects = true; - copy_if_one_unit("0.o", config::OutputTypeObject, true); + copy_if_one_unit("0.o", OutputType::Object, true); } - config::OutputTypeExe | - config::OutputTypeDepInfo => {} + OutputType::Exe | + OutputType::DepInfo => {} } } let user_wants_bitcode = user_wants_bitcode; @@ -913,8 +909,8 @@ fn run_work_multithreaded(sess: &Session, pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) { let (pname, mut cmd) = get_linker(sess); - cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject)) - .arg(&outputs.temp_path(config::OutputTypeAssembly)); + cmd.arg("-c").arg("-o").arg(&outputs.path(OutputType::Object)) + .arg(&outputs.temp_path(OutputType::Assembly)); debug!("{:?}", cmd); match cmd.output() { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 9a13d20854623..5a6d761683224 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -133,7 +133,7 @@ $(document).on("keypress", handleShortcut); $(document).on("keydown", handleShortcut); $(document).on("click", function(ev) { - if (!$(e.target).closest("#help > div").length) { + if (!$(ev.target).closest("#help > div").length) { $("#help").addClass("hidden"); $("body").removeClass("blur"); } @@ -515,7 +515,6 @@ var $active = $results.filter('.highlighted'); if (e.which === 38) { // up - e.preventDefault(); if (!$active.length || !$active.prev()) { return; } @@ -523,7 +522,6 @@ $active.prev().addClass('highlighted'); $active.removeClass('highlighted'); } else if (e.which === 40) { // down - e.preventDefault(); if (!$active.length) { $results.first().addClass('highlighted'); } else if ($active.next().length) { @@ -531,7 +529,6 @@ $active.removeClass('highlighted'); } } else if (e.which === 13) { // return - e.preventDefault(); if ($active.length) { document.location.href = $active.find('a').prop('href'); } @@ -722,20 +719,29 @@ } function startSearch() { - - $(".search-input").on("keyup",function() { + var searchTimeout; + $(".search-input").on("keyup input",function() { + clearTimeout(searchTimeout); if ($(this).val().length === 0) { window.history.replaceState("", "std - Rust", "?search="); $('#main.content').removeClass('hidden'); $('#search.content').addClass('hidden'); + } else { + searchTimeout = setTimeout(search, 500); } }); - - var keyUpTimeout; - $('.do-search').on('click', search); - $('.search-input').on('keyup', function() { - clearTimeout(keyUpTimeout); - keyUpTimeout = setTimeout(search, 500); + $('.search-form').on('submit', function(e){ + e.preventDefault(); + clearTimeout(searchTimeout); + search(); + }); + $('.search-input').on('change paste', function(e) { + // Do NOT e.preventDefault() here. It will prevent pasting. + clearTimeout(searchTimeout); + // zero-timeout necessary here because at the time of event handler execution the + // pasted content is not in the input field yet. Shouldn’t make any difference for + // change, though. + setTimeout(search, 0); }); // Push and pop states are used to add search results to the browser diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 387e1a8cc0727..37669d5a9b145 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -24,7 +24,7 @@ use testing; use rustc_lint; use rustc::front::map as hir_map; use rustc::session::{self, config}; -use rustc::session::config::get_unstable_features_setting; +use rustc::session::config::{get_unstable_features_setting, OutputType}; use rustc::session::search_paths::{SearchPaths, PathKind}; use rustc_front::lowering::lower_crate; use rustc_back::tempdir::TempDir; @@ -167,13 +167,15 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, // never wrap the test in `fn main() { ... }` let test = maketest(test, Some(cratename), as_test_harness, opts); let input = config::Input::Str(test.to_string()); + let mut outputs = HashMap::new(); + outputs.insert(OutputType::Exe, None); let sessopts = config::Options { maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap() .parent().unwrap().to_path_buf()), search_paths: libs, crate_types: vec!(config::CrateTypeExecutable), - output_types: vec!(config::OutputTypeExe), + output_types: outputs, externs: externs, cg: config::CodegenOptions { prefer_dynamic: true, diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 5fe4220bd99ba..bd99d33222db1 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -323,7 +323,6 @@ pub enum InlineAttr { /// Determine what `#[inline]` attribute is present in `attrs`, if any. pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr { - // FIXME (#2809)---validate the usage of #[inline] and #[inline] attrs.iter().fold(InlineAttr::None, |ia,attr| { match attr.node.value.node { MetaWord(ref n) if *n == "inline" => { diff --git a/src/test/auxiliary/sepcomp_cci_lib.rs b/src/test/auxiliary/sepcomp_cci_lib.rs index d62b98714026b..c57d161d8f574 100644 --- a/src/test/auxiliary/sepcomp_cci_lib.rs +++ b/src/test/auxiliary/sepcomp_cci_lib.rs @@ -13,5 +13,4 @@ pub fn cci_fn() -> usize { 1200 } -#[inline] -pub static CCI_STATIC: usize = 34; +pub const CCI_CONST: usize = 34; diff --git a/src/test/auxiliary/xcrate_static_addresses.rs b/src/test/auxiliary/xcrate_static_addresses.rs index 652f11a71ec6f..d0da80e31b913 100644 --- a/src/test/auxiliary/xcrate_static_addresses.rs +++ b/src/test/auxiliary/xcrate_static_addresses.rs @@ -8,13 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[inline(never)] pub static global: isize = 3; -#[inline(never)] static global0: isize = 4; -#[inline(never)] pub static global2: &'static isize = &global0; pub fn verify_same(a: &'static isize) { diff --git a/src/test/compile-fail/attr-usage-inline.rs b/src/test/compile-fail/attr-usage-inline.rs new file mode 100644 index 0000000000000..c6b9b016331aa --- /dev/null +++ b/src/test/compile-fail/attr-usage-inline.rs @@ -0,0 +1,19 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] + +#[inline] +fn f() {} + +#[inline] //~ ERROR: attribute should be applied to function +struct S; + +fn main() {} diff --git a/src/test/compile-fail/attr-usage-repr.rs b/src/test/compile-fail/attr-usage-repr.rs new file mode 100644 index 0000000000000..9bad6a8389a5d --- /dev/null +++ b/src/test/compile-fail/attr-usage-repr.rs @@ -0,0 +1,41 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(dead_code)] +#![feature(repr_simd)] + +#[repr(C)] //~ ERROR: attribute should be applied to struct or enum +fn f() {} + +#[repr(C)] +struct SExtern(f64, f64); + +#[repr(packed)] +struct SPacked(f64, f64); + +#[repr(simd)] +struct SSimd(f64, f64); + +#[repr(i8)] //~ ERROR: attribute should be applied to enum +struct SInt(f64, f64); + +#[repr(C)] +enum EExtern { A, B } + +#[repr(packed)] //~ ERROR: attribute should be applied to struct +enum EPacked { A, B } + +#[repr(simd)] //~ ERROR: attribute should be applied to struct +enum ESimd { A, B } + +#[repr(i8)] +enum EInt { A, B } + +fn main() {} diff --git a/src/test/run-make/compile-stdin/Makefile b/src/test/run-make/compile-stdin/Makefile new file mode 100644 index 0000000000000..1442224cf9a76 --- /dev/null +++ b/src/test/run-make/compile-stdin/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +all: + echo 'fn main(){}' | $(RUSTC) - + $(call RUN,rust_out) diff --git a/src/test/run-make/dep-info/Makefile b/src/test/run-make/dep-info/Makefile index a1828cd1f5d73..9b79d1af52181 100644 --- a/src/test/run-make/dep-info/Makefile +++ b/src/test/run-make/dep-info/Makefile @@ -7,9 +7,10 @@ ifneq ($(shell uname),FreeBSD) ifndef IS_WINDOWS all: - $(RUSTC) --emit dep-info,link --crate-type=lib lib.rs + cp *.rs $(TMPDIR) + $(RUSTC) --emit dep-info,link --crate-type=lib $(TMPDIR)/lib.rs sleep 2 - touch foo.rs + touch $(TMPDIR)/foo.rs -rm -f $(TMPDIR)/done $(MAKE) -drf Makefile.foo sleep 2 @@ -17,6 +18,11 @@ all: pwd $(MAKE) -drf Makefile.foo rm $(TMPDIR)/done && exit 1 || exit 0 + + # When a source file is deleted `make` should still work + rm $(TMPDIR)/bar.rs + cp $(TMPDIR)/lib2.rs $(TMPDIR)/lib.rs + $(MAKE) -drf Makefile.foo else all: diff --git a/src/test/run-make/dep-info/lib2.rs b/src/test/run-make/dep-info/lib2.rs new file mode 100644 index 0000000000000..1b70fb4eb4b47 --- /dev/null +++ b/src/test/run-make/dep-info/lib2.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +pub mod foo; diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index 8745cbecf9137..bd8c735df31a9 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rustc_private, path, convert)] +#![feature(rustc_private)] extern crate rustc; extern crate rustc_driver; @@ -16,7 +16,7 @@ extern crate rustc_lint; extern crate syntax; use rustc::session::{build_session, Session}; -use rustc::session::config::{basic_options, build_configuration, Input, OutputTypeExe}; +use rustc::session::config::{basic_options, build_configuration, Input, OutputType}; use rustc_driver::driver::{compile_input, CompileController}; use syntax::diagnostics::registry::Registry; @@ -46,7 +46,7 @@ fn main() { fn basic_sess(sysroot: PathBuf) -> Session { let mut opts = basic_options(); - opts.output_types = vec![OutputTypeExe]; + opts.output_types.insert(OutputType::Exe, None); opts.maybe_sysroot = Some(sysroot); let descriptions = Registry::new(&rustc::DIAGNOSTICS); diff --git a/src/test/run-make/output-type-permutations/Makefile b/src/test/run-make/output-type-permutations/Makefile index a785e916cf733..b4b2e827e947e 100644 --- a/src/test/run-make/output-type-permutations/Makefile +++ b/src/test/run-make/output-type-permutations/Makefile @@ -23,45 +23,83 @@ all: rm -f $(TMPDIR)/bar.pdb [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - $(RUSTC) foo.rs --emit=asm -o $(TMPDIR)/foo + $(RUSTC) foo.rs --emit asm -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit asm=$(TMPDIR)/foo rm $(TMPDIR)/foo [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - $(RUSTC) foo.rs --emit=llvm-bc -o $(TMPDIR)/foo + $(RUSTC) foo.rs --emit llvm-bc -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit llvm-bc=$(TMPDIR)/foo rm $(TMPDIR)/foo [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - $(RUSTC) foo.rs --emit=llvm-ir -o $(TMPDIR)/foo + $(RUSTC) foo.rs --emit llvm-ir -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/foo rm $(TMPDIR)/foo [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - $(RUSTC) foo.rs --emit=obj -o $(TMPDIR)/foo + $(RUSTC) foo.rs --emit obj -o $(TMPDIR)/foo + rm $(TMPDIR)/foo + $(RUSTC) foo.rs --emit obj=$(TMPDIR)/foo rm $(TMPDIR)/foo [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] - $(RUSTC) foo.rs --emit=link -o $(TMPDIR)/$(call BIN,foo) + $(RUSTC) foo.rs --emit link -o $(TMPDIR)/$(call BIN,foo) + rm $(TMPDIR)/$(call BIN,foo) + $(RUSTC) foo.rs --emit link=$(TMPDIR)/$(call BIN,foo) rm $(TMPDIR)/$(call BIN,foo) rm -f $(TMPDIR)/foo.pdb [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] $(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo rm $(TMPDIR)/foo + $(RUSTC) foo.rs --crate-type=rlib --emit link=$(TMPDIR)/foo + rm $(TMPDIR)/foo [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] $(RUSTC) foo.rs --crate-type=dylib -o $(TMPDIR)/$(call BIN,foo) rm $(TMPDIR)/$(call BIN,foo) + $(RUSTC) foo.rs --crate-type=dylib --emit link=$(TMPDIR)/$(call BIN,foo) + rm $(TMPDIR)/$(call BIN,foo) rm -f $(TMPDIR)/foo.{exp,lib,pdb} [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] $(RUSTC) foo.rs --crate-type=staticlib -o $(TMPDIR)/foo rm $(TMPDIR)/foo + $(RUSTC) foo.rs --crate-type=staticlib --emit link=$(TMPDIR)/foo + rm $(TMPDIR)/foo [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] $(RUSTC) foo.rs --crate-type=bin -o $(TMPDIR)/$(call BIN,foo) rm $(TMPDIR)/$(call BIN,foo) + $(RUSTC) foo.rs --crate-type=bin --emit link=$(TMPDIR)/$(call BIN,foo) + rm $(TMPDIR)/$(call BIN,foo) rm -f $(TMPDIR)/foo.pdb [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] + $(RUSTC) foo.rs --emit llvm-ir=$(TMPDIR)/ir \ + --emit link \ + --crate-type=rlib + rm $(TMPDIR)/ir + rm $(TMPDIR)/libbar.rlib + [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] + + $(RUSTC) foo.rs --emit asm=$(TMPDIR)/asm \ + --emit llvm-ir=$(TMPDIR)/ir \ + --emit llvm-bc=$(TMPDIR)/bc \ + --emit obj=$(TMPDIR)/obj \ + --emit link=$(TMPDIR)/link \ + --crate-type=staticlib + rm $(TMPDIR)/asm + rm $(TMPDIR)/ir + rm $(TMPDIR)/bc + rm $(TMPDIR)/obj + rm $(TMPDIR)/link + [ "$$(ls -1 $(TMPDIR) | wc -l)" -eq "0" ] + $(RUSTC) foo.rs --emit=asm,llvm-ir,llvm-bc,obj,link --crate-type=staticlib rm $(TMPDIR)/bar.ll rm $(TMPDIR)/bar.s diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index c8adb6ccc0ab8..2cc033b8a46e1 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -74,6 +74,10 @@ pub fn main() { t!(format!("{:?}", 10_usize), "10"); t!(format!("{:?}", "true"), "\"true\""); t!(format!("{:?}", "foo\nbar"), "\"foo\\nbar\""); + t!(format!("{:?}", "foo\n\"bar\"\r\n\'baz\'\t\\qux\\"), + r#""foo\n\"bar\"\r\n\'baz\'\t\\qux\\""#); + t!(format!("{:?}", "foo\0bar\x01baz\u{3b1}q\u{75}x"), + r#""foo\u{0}bar\u{1}baz\u{3b1}qux""#); t!(format!("{:o}", 10_usize), "12"); t!(format!("{:x}", 10_usize), "a"); t!(format!("{:X}", 10_usize), "A"); diff --git a/src/test/run-pass/issue-28550.rs b/src/test/run-pass/issue-28550.rs new file mode 100644 index 0000000000000..f44a535e8176e --- /dev/null +++ b/src/test/run-pass/issue-28550.rs @@ -0,0 +1,25 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct AT,T>(F::Output); +struct BT,T>(A); + +// Removing Option causes it to compile. +fn fooT>(f: F) -> Option> { + Some(B(A(f()))) +} + +fn main() { + let v = (|| foo(||4))(); + match v { + Some(B(A(4))) => {}, + _ => unreachable!() + } +} diff --git a/src/test/run-pass/sepcomp-cci.rs b/src/test/run-pass/sepcomp-cci.rs index a1c5ad113c76d..d3d3de0e2c0cb 100644 --- a/src/test/run-pass/sepcomp-cci.rs +++ b/src/test/run-pass/sepcomp-cci.rs @@ -16,23 +16,23 @@ extern crate sepcomp_cci_lib; -use sepcomp_cci_lib::{cci_fn, CCI_STATIC}; +use sepcomp_cci_lib::{cci_fn, CCI_CONST}; fn call1() -> usize { - cci_fn() + CCI_STATIC + cci_fn() + CCI_CONST } mod a { - use sepcomp_cci_lib::{cci_fn, CCI_STATIC}; + use sepcomp_cci_lib::{cci_fn, CCI_CONST}; pub fn call2() -> usize { - cci_fn() + CCI_STATIC + cci_fn() + CCI_CONST } } mod b { - use sepcomp_cci_lib::{cci_fn, CCI_STATIC}; + use sepcomp_cci_lib::{cci_fn, CCI_CONST}; pub fn call3() -> usize { - cci_fn() + CCI_STATIC + cci_fn() + CCI_CONST } }