diff --git a/.gitmodules b/.gitmodules index fc2f8bbc8a350..5b7fd48129929 100644 --- a/.gitmodules +++ b/.gitmodules @@ -50,3 +50,6 @@ [submodule "src/llvm-emscripten"] path = src/llvm-emscripten url = https://github.com/rust-lang/llvm +[submodule "src/stdsimd"] + path = src/stdsimd + url = https://github.com/rust-lang-nursery/stdsimd diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5966bb65df9c8..77df372d4fa33 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -314,7 +314,6 @@ def __init__(self): self.build_dir = os.path.join(os.getcwd(), "build") self.clean = False self.config_toml = '' - self.printed = False self.rust_root = os.path.abspath(os.path.join(__file__, '../../..')) self.use_locked_deps = '' self.use_vendored_sources = '' @@ -336,7 +335,6 @@ def download_stage0(self): if self.rustc().startswith(self.bin_root()) and \ (not os.path.exists(self.rustc()) or self.program_out_of_date(self.rustc_stamp())): - self.print_what_bootstrap_means() if os.path.exists(self.bin_root()): shutil.rmtree(self.bin_root()) filename = "rust-std-{}-{}.tar.gz".format( @@ -351,10 +349,17 @@ def download_stage0(self): with open(self.rustc_stamp(), 'w') as rust_stamp: rust_stamp.write(self.date) + # This is required so that we don't mix incompatible MinGW + # libraries/binaries that are included in rust-std with + # the system MinGW ones. + if "pc-windows-gnu" in self.build: + filename = "rust-mingw-{}-{}.tar.gz".format( + rustc_channel, self.build) + self._download_stage0_helper(filename, "rust-mingw") + if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): - self.print_what_bootstrap_means() filename = "cargo-{}-{}.tar.gz".format(cargo_channel, self.build) self._download_stage0_helper(filename, "cargo") self.fix_executable("{}/bin/cargo".format(self.bin_root())) @@ -555,23 +560,6 @@ def exe_suffix(): return '.exe' return '' - def print_what_bootstrap_means(self): - """Prints more information about the build system""" - if hasattr(self, 'printed'): - return - self.printed = True - if os.path.exists(self.bootstrap_binary()): - return - if '--help' not in sys.argv or len(sys.argv) == 1: - return - - print('info: the build system for Rust is written in Rust, so this') - print(' script is now going to download a stage0 rust compiler') - print(' and then compile the build system itself') - print('') - print('info: in the meantime you can read more about rustbuild at') - print(' src/bootstrap/README.md before the download finishes') - def bootstrap_binary(self): """Return the path of the boostrap binary @@ -585,7 +573,6 @@ def bootstrap_binary(self): def build_bootstrap(self): """Build bootstrap""" - self.print_what_bootstrap_means() build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) @@ -670,8 +657,16 @@ def set_dev_environment(self): self._download_url = 'https://dev-static.rust-lang.org' -def bootstrap(): +def bootstrap(help_triggered): """Configure, fetch, build and run the initial bootstrap""" + + # If the user is asking for help, let them know that the whole download-and-build + # process has to happen before anything is printed out. + if help_triggered: + print("info: Downloading and building bootstrap before processing --help") + print(" command. See src/bootstrap/README.md for help with common") + print(" commands.") + parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') parser.add_argument('--build') @@ -708,7 +703,7 @@ def bootstrap(): print(' and so in order to preserve your $HOME this will now') print(' use vendored sources by default. Note that if this') print(' does not work you should run a normal build first') - print(' before running a command like `sudo make install`') + print(' before running a command like `sudo ./x.py install`') if build.use_vendored_sources: if not os.path.exists('.cargo'): @@ -734,7 +729,10 @@ def bootstrap(): if 'dev' in data: build.set_dev_environment() - build.update_submodules() + # No help text depends on submodules. This check saves ~1 minute of git commands, even if + # all the submodules are present and downloaded! + if not help_triggered: + build.update_submodules() # Fetch/build the bootstrap build.build = args.build or build.build_triple() @@ -760,7 +758,7 @@ def main(): help_triggered = ( '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: - bootstrap() + bootstrap(help_triggered) if not help_triggered: print("Build completed successfully in {}".format( format_build_time(time() - start_time))) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 3dd30ee1c69e2..1efd605112dc2 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -68,16 +68,21 @@ #![feature(allow_internal_unstable)] #![feature(asm)] #![feature(associated_type_defaults)] +#![feature(attr_literals)] #![feature(cfg_target_feature)] #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] #![feature(const_fn)] #![feature(custom_attribute)] +#![feature(doc_spotlight)] #![feature(fundamental)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] #![feature(intrinsics)] +#![feature(iterator_flatten)] +#![feature(iterator_repeat_with)] #![feature(lang_items)] +#![feature(link_llvm_intrinsics)] #![feature(never_type)] #![feature(no_core)] #![feature(on_unimplemented)] @@ -85,15 +90,17 @@ #![feature(prelude_import)] #![feature(repr_simd, platform_intrinsics)] #![feature(rustc_attrs)] +#![feature(rustc_const_unstable)] +#![feature(simd_ffi)] #![feature(specialization)] #![feature(staged_api)] +#![feature(stmt_expr_attributes)] +#![feature(target_feature)] #![feature(unboxed_closures)] #![feature(untagged_unions)] #![feature(unwind_attributes)] -#![feature(doc_spotlight)] -#![feature(rustc_const_unstable)] -#![feature(iterator_repeat_with)] -#![feature(iterator_flatten)] + +#![cfg_attr(stage0, allow(unused_attributes))] #[prelude_import] #[allow(unused)] @@ -179,3 +186,21 @@ mod char_private; mod iter_private; mod tuple; mod unit; + +// Pull in the the `coresimd` crate directly into libcore. This is where all the +// architecture-specific (and vendor-specific) intrinsics are defined. AKA +// things like SIMD and such. Note that the actual source for all this lies in a +// different repository, rust-lang-nursery/stdsimd. That's why the setup here is +// a bit wonky. +#[path = "../stdsimd/coresimd/mod.rs"] +#[allow(missing_docs, missing_debug_implementations, dead_code)] +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(not(stage0))] // allow changes to how stdsimd works in stage0 +mod coresimd; + +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(not(stage0))] +pub use coresimd::simd; +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(not(stage0))] +pub use coresimd::arch; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b69f5d6c8bdd7..4d094f8b3a3f3 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -420,10 +420,7 @@ top_level_options!( lint_cap: Option [TRACKED], describe_lints: bool [UNTRACKED], output_types: OutputTypes [TRACKED], - // FIXME(mw): We track this for now but it actually doesn't make too - // much sense: The search path can stay the same while the - // things discovered there might have changed on disk. - search_paths: SearchPaths [TRACKED], + search_paths: SearchPaths [UNTRACKED], libs: Vec<(String, Option, Option)> [TRACKED], maybe_sysroot: Option [TRACKED], @@ -442,10 +439,7 @@ top_level_options!( // version of `debugging_opts.borrowck`, which is just a plain string. borrowck_mode: BorrowckMode [UNTRACKED], cg: CodegenOptions [TRACKED], - // FIXME(mw): We track this for now but it actually doesn't make too - // much sense: The value of this option can stay the same - // while the files they refer to might have changed on disk. - externs: Externs [TRACKED], + externs: Externs [UNTRACKED], crate_name: Option [TRACKED], // An optional name to use as the crate for std during std injection, // written `extern crate std = "name"`. Default to "std". Used by @@ -2141,13 +2135,12 @@ impl fmt::Display for CrateType { mod dep_tracking { use lint; use middle::cstore; - use session::search_paths::{PathKind, SearchPaths}; use std::collections::BTreeMap; use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto, - OutputTypes, Externs, ErrorOutputType, Sanitizer, Epoch}; + OutputTypes, ErrorOutputType, Sanitizer, Epoch}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2204,7 +2197,6 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Lto); impl_dep_tracking_hash_via_hash!(DebugInfoLevel); impl_dep_tracking_hash_via_hash!(UnstableFeatures); - impl_dep_tracking_hash_via_hash!(Externs); impl_dep_tracking_hash_via_hash!(OutputTypes); impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind); impl_dep_tracking_hash_via_hash!(Sanitizer); @@ -2218,15 +2210,6 @@ mod dep_tracking { impl_dep_tracking_hash_for_sortable_vec_of!((String, Option, Option)); impl_dep_tracking_hash_for_sortable_vec_of!((String, u64)); - impl DepTrackingHash for SearchPaths { - fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) { - let mut elems: Vec<_> = self - .iter(PathKind::All) - .collect(); - elems.sort(); - Hash::hash(&elems, hasher); - } - } impl DepTrackingHash for (T1, T2) where T1: DepTrackingHash, @@ -2413,43 +2396,6 @@ mod tests { assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash()); } - #[test] - fn test_externs_tracking_hash_different_values() { - let mut v1 = super::basic_options(); - let mut v2 = super::basic_options(); - let mut v3 = super::basic_options(); - - v1.externs = Externs::new(mk_map(vec![ - (String::from("a"), mk_set(vec![String::from("b"), - String::from("c")])), - (String::from("d"), mk_set(vec![String::from("e"), - String::from("f")])), - ])); - - v2.externs = Externs::new(mk_map(vec![ - (String::from("a"), mk_set(vec![String::from("b"), - String::from("c")])), - (String::from("X"), mk_set(vec![String::from("e"), - String::from("f")])), - ])); - - v3.externs = Externs::new(mk_map(vec![ - (String::from("a"), mk_set(vec![String::from("b"), - String::from("c")])), - (String::from("d"), mk_set(vec![String::from("X"), - String::from("f")])), - ])); - - assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); - assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash()); - assert!(v2.dep_tracking_hash() != v3.dep_tracking_hash()); - - // Check clone - assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash()); - assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash()); - assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash()); - } - #[test] fn test_externs_tracking_hash_different_construction_order() { let mut v1 = super::basic_options(); @@ -2540,69 +2486,6 @@ mod tests { assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash()); } - #[test] - fn test_search_paths_tracking_hash_different_values() { - let mut v1 = super::basic_options(); - let mut v2 = super::basic_options(); - let mut v3 = super::basic_options(); - let mut v4 = super::basic_options(); - let mut v5 = super::basic_options(); - - // Reference - v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - // Native changed - v2.search_paths.add_path("native=XXX", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - // Crate changed - v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("crate=XXX", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - // Dependency changed - v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("dependency=XXX", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - // Framework changed - v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("framework=XXX", super::ErrorOutputType::Json(false)); - v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false)); - - // All changed - v5.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false)); - v5.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false)); - v5.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false)); - v5.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false)); - v5.search_paths.add_path("all=XXX", super::ErrorOutputType::Json(false)); - - assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); - assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash()); - assert!(v1.dep_tracking_hash() != v4.dep_tracking_hash()); - assert!(v1.dep_tracking_hash() != v5.dep_tracking_hash()); - - // Check clone - assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash()); - assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash()); - assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash()); - assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash()); - assert_eq!(v5.dep_tracking_hash(), v5.clone().dep_tracking_hash()); - } - #[test] fn test_search_paths_tracking_hash_different_order() { let mut v1 = super::basic_options(); diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index a36e26c0b7d5f..88f2b59675186 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -12,13 +12,7 @@ use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::linux_musl_base::opts(); - - // Most of these settings are copied from the armv7_unknown_linux_gnueabihf - // target. - base.features = "+v7,+vfp3,+neon".to_string(); - base.cpu = "cortex-a8".to_string(); - base.max_atomic_width = Some(64); + let base = super::linux_musl_base::opts(); Ok(Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM // uses it to determine the calling convention and float ABI, and LLVM @@ -33,9 +27,15 @@ pub fn target() -> TargetResult { target_env: "musl".to_string(), target_vendor: "unknown".to_string(), linker_flavor: LinkerFlavor::Gcc, + + // Most of these settings are copied from the armv7_unknown_linux_gnueabihf + // target. options: TargetOptions { + features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(), + cpu: "generic".to_string(), + max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), .. base - }, + } }) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index d7d856fe3ad06..56852540730f9 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -299,6 +299,7 @@ #![feature(rand)] #![feature(raw)] #![feature(rustc_attrs)] +#![feature(stdsimd)] #![feature(sip_hash_13)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] @@ -501,6 +502,35 @@ mod memchr; // compiler pub mod rt; +// Pull in the the `stdsimd` crate directly into libstd. This is the same as +// libcore's arch/simd modules where the source of truth here is in a different +// repository, but we pull things in here manually to get it into libstd. +// +// Note that the #[cfg] here is intended to do two things. First it allows us to +// change the rustc implementation of intrinsics in stage0 by not compiling simd +// intrinsics in stage0. Next it doesn't compile anything in test mode as +// stdsimd has tons of its own tests which we don't want to run. +#[path = "../stdsimd/stdsimd/mod.rs"] +#[allow(missing_debug_implementations, missing_docs)] +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(all(not(stage0), not(test)))] +mod stdsimd; + +// A "fake" module needed by the `stdsimd` module to compile, not actually +// exported though. +#[cfg(not(stage0))] +mod coresimd { + pub use core::arch; + pub use core::simd; +} + +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(all(not(stage0), not(test)))] +pub use stdsimd::simd; +#[unstable(feature = "stdsimd", issue = "48556")] +#[cfg(all(not(stage0), not(test)))] +pub use stdsimd::arch; + // Include a number of private modules that exist solely to provide // the rustdoc documentation for primitive types. Using `include!` // because rustdoc only looks for these modules at the crate level. diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index 844ff7a3c1252..5dd9c62775097 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -59,7 +59,7 @@ pub use version::UnicodeVersion; /// [`to_lowercase`]: ../../std/primitive.char.html#method.to_lowercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ToLowercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -81,7 +81,7 @@ impl FusedIterator for ToLowercase {} /// [`to_uppercase`]: ../../std/primitive.char.html#method.to_uppercase /// [`char`]: ../../std/primitive.char.html #[stable(feature = "rust1", since = "1.0.0")] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ToUppercase(CaseMappingIter); #[stable(feature = "rust1", since = "1.0.0")] @@ -95,7 +95,7 @@ impl Iterator for ToUppercase { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for ToUppercase {} -#[derive(Debug)] +#[derive(Debug, Clone)] enum CaseMappingIter { Three(char, char, char), Two(char, char), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 881e3e412d4eb..92584f5b51946 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -652,9 +652,11 @@ impl<'a> Parser<'a> { } else { let token_str = Parser::token_to_string(t); let this_token_str = self.this_token_to_string(); - Err(self.fatal(&format!("expected `{}`, found `{}`", - token_str, - this_token_str))) + let mut err = self.fatal(&format!("expected `{}`, found `{}`", + token_str, + this_token_str)); + err.span_label(self.span, format!("expected `{}`", token_str)); + Err(err) } } else { self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[]) @@ -1172,7 +1174,7 @@ impl<'a> Parser<'a> { sep: SeqSep, f: F) -> PResult<'a, Vec> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { self.expect(bra)?; let result = self.parse_seq_to_before_end(ket, sep, f)?; @@ -1190,7 +1192,7 @@ impl<'a> Parser<'a> { sep: SeqSep, f: F) -> PResult<'a, Spanned>> where - F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, + F: FnMut(&mut Parser<'a>) -> PResult<'a, T>, { let lo = self.span; self.expect(bra)?; @@ -1485,7 +1487,10 @@ impl<'a> Parser<'a> { } _ => { let token_str = self.this_token_to_string(); - return Err(self.fatal(&format!("expected `;` or `{{`, found `{}`", token_str))); + let mut err = self.fatal(&format!("expected `;` or `{{`, found `{}`", + token_str)); + err.span_label(self.span, "expected `;` or `{`"); + return Err(err); } }; (ident, ast::TraitItemKind::Method(sig, body), generics) @@ -2216,7 +2221,12 @@ impl<'a> Parser<'a> { TokenTree::Delimited(_, delimited) => Ok((delim, delimited.stream().into())), _ => unreachable!(), }, - _ => Err(self.fatal("expected open delimiter")), + _ => { + let msg = "expected open delimiter"; + let mut err = self.fatal(msg); + err.span_label(self.span, msg); + Err(err) + } } } @@ -2349,7 +2359,10 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Loop) { return self.parse_loop_expr(Some(label), lo, attrs) } - return Err(self.fatal("expected `while`, `for`, or `loop` after a label")) + let msg = "expected `while`, `for`, or `loop` after a label"; + let mut err = self.fatal(msg); + err.span_label(self.span, msg); + return Err(err); } if self.eat_keyword(keywords::Loop) { let lo = self.prev_span; @@ -2408,6 +2421,7 @@ impl<'a> Parser<'a> { // Catch this syntax error here, instead of in `parse_ident`, so // that we can explicitly mention that let is not to be used as an expression let mut db = self.fatal("expected expression, found statement (`let`)"); + db.span_label(self.span, "expected expression"); db.note("variable declaration using `let` is a statement"); return Err(db); } else if self.token.is_path_start() { @@ -2443,7 +2457,9 @@ impl<'a> Parser<'a> { self.cancel(&mut err); let msg = format!("expected expression, found {}", self.this_token_descr()); - return Err(self.fatal(&msg)); + let mut err = self.fatal(&msg); + err.span_label(self.span, "expected expression"); + return Err(err); } } } @@ -2733,7 +2749,9 @@ impl<'a> Parser<'a> { self.look_ahead(1, |t| t.is_ident()) => { self.bump(); let name = match self.token { token::Ident(ident) => ident, _ => unreachable!() }; - self.fatal(&format!("unknown macro variable `{}`", name)).emit(); + let mut err = self.fatal(&format!("unknown macro variable `{}`", name)); + err.span_label(self.span, "unknown macro variable"); + err.emit(); return } token::Interpolated(ref nt) => { @@ -3212,7 +3230,13 @@ impl<'a> Parser<'a> { err.span_label(sp, "expected if condition here"); return Err(err) } - let thn = self.parse_block()?; + let not_block = self.token != token::OpenDelim(token::Brace); + let thn = self.parse_block().map_err(|mut err| { + if not_block { + err.span_label(lo, "this `if` statement has a condition, but no block"); + } + err + })?; let mut els: Option> = None; let mut hi = thn.span; if self.eat_keyword(keywords::Else) { @@ -3404,14 +3428,52 @@ impl<'a> Parser<'a> { } else { None }; + let arrow_span = self.span; self.expect(&token::FatArrow)?; - let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)?; + let arm_start_span = self.span; + + let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None) + .map_err(|mut err| { + err.span_label(arrow_span, "while parsing the `match` arm starting here"); + err + })?; let require_comma = classify::expr_requires_semi_to_be_stmt(&expr) && self.token != token::CloseDelim(token::Brace); if require_comma { - self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])?; + let cm = self.sess.codemap(); + self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) + .map_err(|mut err| { + match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) { + (Ok(ref expr_lines), Ok(ref arm_start_lines)) + if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col + && expr_lines.lines.len() == 2 + && self.token == token::FatArrow => { + // We check wether there's any trailing code in the parse span, if there + // isn't, we very likely have the following: + // + // X | &Y => "y" + // | -- - missing comma + // | | + // | arrow_span + // X | &X => "x" + // | - ^^ self.span + // | | + // | parsed until here as `"y" & X` + err.span_suggestion_short( + cm.next_point(arm_start_span), + "missing a comma here to end this `match` arm", + ",".to_owned() + ); + } + _ => { + err.span_label(arrow_span, + "while parsing the `match` arm starting here"); + } + } + err + })?; } else { self.eat(&token::Comma); } @@ -3609,8 +3671,9 @@ impl<'a> Parser<'a> { self.bump(); if self.token != token::CloseDelim(token::Brace) { let token_str = self.this_token_to_string(); - return Err(self.fatal(&format!("expected `{}`, found `{}`", "}", - token_str))) + let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str)); + err.span_label(self.span, "expected `}`"); + return Err(err); } etc = true; break; @@ -3721,7 +3784,10 @@ impl<'a> Parser<'a> { self.expect_and()?; let mutbl = self.parse_mutability(); if let token::Lifetime(ident) = self.token { - return Err(self.fatal(&format!("unexpected lifetime `{}` in pattern", ident))); + let mut err = self.fatal(&format!("unexpected lifetime `{}` in pattern", + ident)); + err.span_label(self.span, "unexpected lifetime"); + return Err(err); } let subpat = self.parse_pat()?; pat = PatKind::Ref(subpat, mutbl); @@ -3806,7 +3872,10 @@ impl<'a> Parser<'a> { } token::OpenDelim(token::Brace) => { if qself.is_some() { - return Err(self.fatal("unexpected `{` after qualified path")); + let msg = "unexpected `{` after qualified path"; + let mut err = self.fatal(msg); + err.span_label(self.span, msg); + return Err(err); } // Parse struct pattern self.bump(); @@ -3820,7 +3889,10 @@ impl<'a> Parser<'a> { } token::OpenDelim(token::Paren) => { if qself.is_some() { - return Err(self.fatal("unexpected `(` after qualified path")); + let msg = "unexpected `(` after qualified path"; + let mut err = self.fatal(msg); + err.span_label(self.span, msg); + return Err(err); } // Parse tuple struct or enum pattern let (fields, ddpos, _) = self.parse_parenthesized_pat_list()?; @@ -3850,7 +3922,9 @@ impl<'a> Parser<'a> { Err(mut err) => { self.cancel(&mut err); let msg = format!("expected pattern, found {}", self.this_token_descr()); - return Err(self.fatal(&msg)); + let mut err = self.fatal(&msg); + err.span_label(self.span, "expected pattern"); + return Err(err); } } } @@ -4250,9 +4324,11 @@ impl<'a> Parser<'a> { "" }; let tok_str = self.this_token_to_string(); - return Err(self.fatal(&format!("expected {}`(` or `{{`, found `{}`", - ident_str, - tok_str))) + let mut err = self.fatal(&format!("expected {}`(` or `{{`, found `{}`", + ident_str, + tok_str)); + err.span_label(self.span, format!("expected {}`(` or `{{`", ident_str)); + return Err(err) }, }; @@ -5559,8 +5635,12 @@ impl<'a> Parser<'a> { body } else { let token_str = self.this_token_to_string(); - return Err(self.fatal(&format!("expected `where`, `{{`, `(`, or `;` after struct \ - name, found `{}`", token_str))) + let mut err = self.fatal(&format!( + "expected `where`, `{{`, `(`, or `;` after struct name, found `{}`", + token_str + )); + err.span_label(self.span, "expected `where`, `{`, `(`, or `;` after struct name"); + return Err(err); }; Ok((class_name, ItemKind::Struct(vdata, generics), None)) @@ -5579,8 +5659,10 @@ impl<'a> Parser<'a> { VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID) } else { let token_str = self.this_token_to_string(); - return Err(self.fatal(&format!("expected `where` or `{{` after union \ - name, found `{}`", token_str))) + let mut err = self.fatal(&format!( + "expected `where` or `{{` after union name, found `{}`", token_str)); + err.span_label(self.span, "expected `where` or `{` after union name"); + return Err(err); }; Ok((class_name, ItemKind::Union(vdata, generics), None)) @@ -5627,9 +5709,10 @@ impl<'a> Parser<'a> { self.eat(&token::CloseDelim(token::Brace)); } else { let token_str = self.this_token_to_string(); - return Err(self.fatal(&format!("expected `where`, or `{{` after struct \ - name, found `{}`", - token_str))); + let mut err = self.fatal(&format!( + "expected `where`, or `{{` after struct name, found `{}`", token_str)); + err.span_label(self.span, "expected `where`, or `{` after struct name"); + return Err(err); } Ok(fields) @@ -5802,9 +5885,11 @@ impl<'a> Parser<'a> { if !self.eat(term) { let token_str = self.this_token_to_string(); let mut err = self.fatal(&format!("expected item, found `{}`", token_str)); - let msg = "consider removing this semicolon"; if token_str == ";" { + let msg = "consider removing this semicolon"; err.span_suggestion_short(self.span, msg, "".to_string()); + } else { + err.span_label(self.span, "expected item"); } return Err(err); } @@ -6961,7 +7046,12 @@ impl<'a> Parser<'a> { self.expect_no_suffix(sp, "string literal", suf); Ok((s, style)) } - _ => Err(self.fatal("expected string literal")) + _ => { + let msg = "expected string literal"; + let mut err = self.fatal(msg); + err.span_label(self.span, msg); + Err(err) + } } } } diff --git a/src/stdsimd b/src/stdsimd new file mode 160000 index 0000000000000..678cbd325c840 --- /dev/null +++ b/src/stdsimd @@ -0,0 +1 @@ +Subproject commit 678cbd325c84070c9dbe4303969fbd2734c0b4ee diff --git a/src/test/run-make/reproducible-build/Makefile b/src/test/run-make/reproducible-build/Makefile index 8e799ca1a4303..629e618505129 100644 --- a/src/test/run-make/reproducible-build/Makefile +++ b/src/test/run-make/reproducible-build/Makefile @@ -1,20 +1,78 @@ -include ../tools.mk -all: +all: \ + smoke \ + debug \ + opt \ + link_paths \ + remap_paths \ + different_source_dirs \ + extern_flags + +smoke: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) reproducible-build-aux.rs $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" + $(B2) nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1.nm" nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2.nm" cmp "$(TMPDIR)/reproducible-build1.nm" "$(TMPDIR)/reproducible-build2.nm" || exit 1 + +debug: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) reproducible-build-aux.rs -g - $(RUSTC) reproducible-build.rs -g -o"$(TMPDIR)/reproducible-build1-debug" - $(RUSTC) reproducible-build.rs -g -o"$(TMPDIR)/reproducible-build2-debug" - nm "$(TMPDIR)/reproducible-build1-debug" | sort > "$(TMPDIR)/reproducible-build1-debug.nm" - nm "$(TMPDIR)/reproducible-build2-debug" | sort > "$(TMPDIR)/reproducible-build2-debug.nm" + $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" -g + $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" -g + nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1-debug.nm" + nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2-debug.nm" cmp "$(TMPDIR)/reproducible-build1-debug.nm" "$(TMPDIR)/reproducible-build2-debug.nm" || exit 1 + +opt: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) reproducible-build-aux.rs -O - $(RUSTC) reproducible-build.rs -O -o"$(TMPDIR)/reproducible-build1-opt" - $(RUSTC) reproducible-build.rs -O -o"$(TMPDIR)/reproducible-build2-opt" - nm "$(TMPDIR)/reproducible-build1-opt" | sort > "$(TMPDIR)/reproducible-build1-opt.nm" - nm "$(TMPDIR)/reproducible-build2-opt" | sort > "$(TMPDIR)/reproducible-build2-opt.nm" + $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" -O + $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" -O + nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1-opt.nm" + nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2-opt.nm" cmp "$(TMPDIR)/reproducible-build1-opt.nm" "$(TMPDIR)/reproducible-build2-opt.nm" || exit 1 + +link_paths: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) reproducible-build-aux.rs + $(RUSTC) reproducible-build.rs --crate-type rlib -L /b + cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib + $(RUSTC) reproducible-build.rs --crate-type rlib -L /a + cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 + +remap_paths: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) reproducible-build-aux.rs + $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/a=/c + cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib + $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/b=/c + cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 + +different_source_dirs: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) reproducible-build-aux.rs + mkdir $(TMPDIR)/test + cp reproducible-build.rs $(TMPDIR)/test + $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=$$PWD=/b + cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib + (cd $(TMPDIR)/test && $(RUSTC) reproducible-build.rs \ + --remap-path-prefix=$(TMPDIR)/test=/b \ + --crate-type rlib) + cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 + +extern_flags: + rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) reproducible-build-aux.rs + $(RUSTC) reproducible-build.rs \ + --extern reproducible_build_aux=$(TMPDIR)/libreproducible_build_aux.rlib \ + --crate-type rlib + cp $(TMPDIR)/libreproducible_build_aux.rlib $(TMPDIR)/libbar.rlib + cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib + $(RUSTC) reproducible-build.rs \ + --extern reproducible_build_aux=$(TMPDIR)/libbar.rlib \ + --crate-type rlib + cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 diff --git a/src/test/run-make/reproducible-build/reproducible-build.rs b/src/test/run-make/reproducible-build/reproducible-build.rs index b47d780e52984..a040c0f858d78 100644 --- a/src/test/run-make/reproducible-build/reproducible-build.rs +++ b/src/test/run-make/reproducible-build/reproducible-build.rs @@ -28,7 +28,7 @@ // - Trait object shims // - Fn Pointer shims -#![allow(dead_code)] +#![allow(dead_code, warnings)] extern crate reproducible_build_aux; diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr index 9eeea28be8fec..a9db5214e6a2e 100644 --- a/src/test/ui/cross-file-errors/main.stderr +++ b/src/test/ui/cross-file-errors/main.stderr @@ -2,7 +2,7 @@ error: expected expression, found `_` --> $DIR/underscore.rs:18:9 | LL | _ - | ^ + | ^ expected expression | ::: $DIR/main.rs:15:5 | diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index 301441c5622f9..e576393500fea 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -19,7 +19,7 @@ error: expected `[`, found `#` --> $DIR/issue-40006.rs:20:17 | LL | fn xxx() { ### } //~ ERROR missing - | ^ + | ^ expected `[` error: missing `fn`, `type`, or `const` for trait-item declaration --> $DIR/issue-40006.rs:20:21 diff --git a/src/test/ui/if-without-block.rs b/src/test/ui/if-without-block.rs new file mode 100644 index 0000000000000..ce3de3b302dd3 --- /dev/null +++ b/src/test/ui/if-without-block.rs @@ -0,0 +1,18 @@ +// Copyright 2018 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. + +fn main() { + let n = 1; + if 5 == { + //~^ NOTE this `if` statement has a condition, but no block + println!("five"); + } +} +//~^ ERROR expected `{`, found `}` diff --git a/src/test/ui/if-without-block.stderr b/src/test/ui/if-without-block.stderr new file mode 100644 index 0000000000000..bc8e7310ce371 --- /dev/null +++ b/src/test/ui/if-without-block.stderr @@ -0,0 +1,11 @@ +error: expected `{`, found `}` + --> $DIR/if-without-block.rs:17:1 + | +LL | if 5 == { + | -- this `if` statement has a condition, but no block +... +LL | } + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/macro-context.stderr b/src/test/ui/macro-context.stderr index 65bbe09a212da..4dc6bbe4d656c 100644 --- a/src/test/ui/macro-context.stderr +++ b/src/test/ui/macro-context.stderr @@ -38,7 +38,7 @@ error: expected expression, found reserved keyword `typeof` --> $DIR/macro-context.rs:13:17 | LL | () => ( i ; typeof ); //~ ERROR expected expression, found reserved keyword `typeof` - | ^^^^^^ + | ^^^^^^ expected expression ... LL | m!(); | ----- in this macro invocation diff --git a/src/test/ui/missing-block-hint.stderr b/src/test/ui/missing-block-hint.stderr index 54f394a4220dd..a48eff890b331 100644 --- a/src/test/ui/missing-block-hint.stderr +++ b/src/test/ui/missing-block-hint.stderr @@ -2,11 +2,15 @@ error: expected `{`, found `=>` --> $DIR/missing-block-hint.rs:13:18 | LL | if (foo) => {} //~ ERROR expected `{`, found `=>` - | ^^ + | -- ^^ + | | + | this `if` statement has a condition, but no block error: expected `{`, found `bar` --> $DIR/missing-block-hint.rs:17:13 | +LL | if (foo) + | -- this `if` statement has a condition, but no block LL | bar; //~ ERROR expected `{`, found `bar` | ^^^- | | diff --git a/src/test/ui/resolve/token-error-correct.stderr b/src/test/ui/resolve/token-error-correct.stderr index 344c288b596e0..c6d32c6726ea5 100644 --- a/src/test/ui/resolve/token-error-correct.stderr +++ b/src/test/ui/resolve/token-error-correct.stderr @@ -26,7 +26,7 @@ error: expected expression, found `;` --> $DIR/token-error-correct.rs:14:13 | LL | foo(bar(; - | ^ + | ^ expected expression error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/missing-comma-in-match.rs b/src/test/ui/suggestions/missing-comma-in-match.rs new file mode 100644 index 0000000000000..6f86cdea3cf5e --- /dev/null +++ b/src/test/ui/suggestions/missing-comma-in-match.rs @@ -0,0 +1,19 @@ +// Copyright 2018 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. + +fn main() { + match &Some(3) { + &None => 1 + &Some(2) => { 3 } + //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` + //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here + _ => 2 + }; +} diff --git a/src/test/ui/suggestions/missing-comma-in-match.stderr b/src/test/ui/suggestions/missing-comma-in-match.stderr new file mode 100644 index 0000000000000..b71a50b66318e --- /dev/null +++ b/src/test/ui/suggestions/missing-comma-in-match.stderr @@ -0,0 +1,10 @@ +error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` + --> $DIR/missing-comma-in-match.rs:14:18 + | +LL | &None => 1 + | - help: missing a comma here to end this `match` arm +LL | &Some(2) => { 3 } + | ^^ expected one of `,`, `.`, `?`, `}`, or an operator here + +error: aborting due to previous error + diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr index fcd2c10594a3c..26816ca0ca22a 100644 --- a/src/test/ui/token/issue-10636-2.stderr +++ b/src/test/ui/token/issue-10636-2.stderr @@ -20,7 +20,7 @@ error: expected expression, found `)` --> $DIR/issue-10636-2.rs:18:1 | LL | } //~ ERROR: incorrect close delimiter - | ^ + | ^ expected expression error[E0601]: main function not found diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 4d89008d5ca54..1def3048ce071 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -71,6 +71,7 @@ fn filter_dirs(path: &Path) -> bool { "src/librustc/mir/interpret", "src/librustc_mir/interpret", "src/target", + "src/stdsimd", ]; skip.iter().any(|p| path.ends_with(p)) }