From 8e4ad29cb9cc74bf44486f4507f36df70d495187 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 23 Feb 2018 21:48:41 +0900 Subject: [PATCH 01/13] Disable NEON on musl ARMv7 --- .../target/armv7_unknown_linux_musleabihf.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 - }, + } }) } From ffb6291cd032e3b0577bf67a2b6d932d6ba0787c Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 26 Feb 2018 20:45:52 -0500 Subject: [PATCH 02/13] Improve --help performance for x.py Since compiling the bootstrap command doesn't require any submodules, we can skip updating submodules when a --help command is passed in. On my machine, this saves 1 minute if the submodules are already downloaded, and 10 minutes if run on a clean repo. This commit also adds a message before compiling/downloading anything when a --help command is passed in, to tell the user WHY --help takes so long to complete. It also points the user to the bootstrap README.md for faster help. Finally, this fixes one warning message that still referenced using make instead of x.py, even though x.py is now the standard way of building rust. --- src/bootstrap/bootstrap.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 603a97ddfd412..f5fcf4ba0f560 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -670,7 +670,7 @@ 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""" parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') @@ -708,7 +708,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 +734,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 +763,13 @@ def main(): help_triggered = ( '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: - 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("NOTE: Downloading and compiling bootstrap requirements before processing") + print(" --help command. See src/bootstrap/README.md for help with common") + print(" commands.") + bootstrap(help_triggered) if not help_triggered: print("Build completed successfully in {}".format( format_build_time(time() - start_time))) From 0c9afa87ba8145d09a2c4af7b15a9a23ad470fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Feb 2018 14:36:35 -0800 Subject: [PATCH 03/13] Provide missing comma in match arm suggestion When finding: ```rust match &Some(3) { &None => 1 &Some(2) => { 3 } _ => 2 } ``` provide the following diagnostic: ``` error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` --> $DIR/missing-comma-in-match.rs:15:18 | X | &None => 1 | -- - help: missing comma | | | while parsing the match arm starting here X | &Some(2) => { 3 } | ^^ expected one of `,`, `.`, `?`, `}`, or an operator here ``` --- src/libsyntax/parse/parser.rs | 38 ++++++++++++++++++- .../ui/suggestions/missing-comma-in-match.rs | 20 ++++++++++ .../suggestions/missing-comma-in-match.stderr | 12 ++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/missing-comma-in-match.rs create mode 100644 src/test/ui/suggestions/missing-comma-in-match.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 09dd00fa5fa3a..2046bbfa713a5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3404,14 +3404,48 @@ 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| { + err.span_label(arrow_span, "while parsing the match arm starting here"); + 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 + })?; } else { self.eat(&token::Comma); } 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..e02a8df3343b3 --- /dev/null +++ b/src/test/ui/suggestions/missing-comma-in-match.rs @@ -0,0 +1,20 @@ +// 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 + //~^^^^ NOTE while parsing the match arm starting 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..864fde49a5e51 --- /dev/null +++ b/src/test/ui/suggestions/missing-comma-in-match.stderr @@ -0,0 +1,12 @@ +error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` + --> $DIR/missing-comma-in-match.rs:14:18 + | +13 | &None => 1 + | -- - help: missing a comma here to end this match arm + | | + | while parsing the match arm starting here +14 | &Some(2) => { 3 } + | ^^ expected one of `,`, `.`, `?`, `}`, or an operator here + +error: aborting due to previous error + From ba7039cfd6331fb532c8a68aa79e6af4ef9b62df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Feb 2018 16:59:33 -0800 Subject: [PATCH 04/13] Detect missing `if` blocks When unnecessarily using a fat arrow after an if condition, suggest the removal of it. When finding an if statement with no block, point at the `if` keyword to provide more context. --- src/libsyntax/parse/parser.rs | 35 ++++++++++++++++----- src/test/ui/did_you_mean/issue-40006.stderr | 2 +- src/test/ui/if-without-block.rs | 18 +++++++++++ src/test/ui/if-without-block.stderr | 11 +++++++ src/test/ui/missing-block-hint.stderr | 4 ++- 5 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/if-without-block.rs create mode 100644 src/test/ui/if-without-block.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2046bbfa713a5..9aba2e9d52322 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)?; @@ -3212,7 +3214,23 @@ 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 fat_arrow_sp = if self.token == token::FatArrow { + Some(self.span) + } else { + None + }; + let thn = self.parse_block().map_err(|mut err| { + if let Some(sp) = fat_arrow_sp { + // if cond => expr + err.span_suggestion(sp, + "only necessary in match arms, not before if blocks", + "".to_string()); + } else 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) { @@ -3629,8 +3647,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; 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..8f6e53bd28bf3 --- /dev/null +++ b/src/test/ui/if-without-block.stderr @@ -0,0 +1,11 @@ +error: expected `{`, found `}` + --> $DIR/if-without-block.rs:17:1 + | +13 | if 5 == { + | -- this `if` statement has a condition, but no block +... +17 | } + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/missing-block-hint.stderr b/src/test/ui/missing-block-hint.stderr index 54f394a4220dd..ae583d0d4ba4d 100644 --- a/src/test/ui/missing-block-hint.stderr +++ b/src/test/ui/missing-block-hint.stderr @@ -2,11 +2,13 @@ error: expected `{`, found `=>` --> $DIR/missing-block-hint.rs:13:18 | LL | if (foo) => {} //~ ERROR expected `{`, found `=>` - | ^^ + | ^^ help: only necessary in match arms, not before if blocks 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` | ^^^- | | From 36baa81be9f430329f5ea7b6bbb539e41105bfe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Feb 2018 23:08:23 -0800 Subject: [PATCH 05/13] Add label to primary span in some parse errors --- src/libsyntax/parse/parser.rs | 85 ++++++++++++++----- src/test/ui/cross-file-errors/main.stderr | 2 +- src/test/ui/macro-context.stderr | 2 +- .../ui/resolve/token-error-correct.stderr | 2 +- src/test/ui/token/issue-10636-2.stderr | 2 +- 5 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9aba2e9d52322..6653e6672183e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1487,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) @@ -2218,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) + } } } @@ -2351,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; @@ -2410,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() { @@ -2445,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); } } } @@ -2735,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) => { @@ -3760,7 +3776,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); @@ -3843,7 +3862,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(); @@ -3857,7 +3879,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 self.bump(); @@ -3889,7 +3914,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); } } } @@ -4289,9 +4316,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) }, }; @@ -5598,8 +5627,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)) @@ -5618,8 +5651,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)) @@ -5666,9 +5701,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) @@ -5841,9 +5877,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); } @@ -7000,7 +7038,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/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/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/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/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 From d63d363ef9d6627dc9649477b337a3f915d0660e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Feb 2018 19:38:36 -0800 Subject: [PATCH 06/13] Diagnostic tweaks (review) --- src/libsyntax/parse/parser.rs | 28 ++++++++----------- src/test/ui/missing-block-hint.stderr | 4 ++- .../ui/suggestions/missing-comma-in-match.rs | 1 - .../suggestions/missing-comma-in-match.stderr | 4 +-- 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6653e6672183e..69b2723449849 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3231,18 +3231,8 @@ impl<'a> Parser<'a> { return Err(err) } let not_block = self.token != token::OpenDelim(token::Brace); - let fat_arrow_sp = if self.token == token::FatArrow { - Some(self.span) - } else { - None - }; let thn = self.parse_block().map_err(|mut err| { - if let Some(sp) = fat_arrow_sp { - // if cond => expr - err.span_suggestion(sp, - "only necessary in match arms, not before if blocks", - "".to_string()); - } else if not_block { + if not_block { err.span_label(lo, "this `if` statement has a condition, but no block"); } err @@ -3444,7 +3434,7 @@ impl<'a> Parser<'a> { 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.span_label(arrow_span, "while parsing the `match` arm starting here"); err })?; @@ -3455,7 +3445,6 @@ impl<'a> Parser<'a> { let cm = self.sess.codemap(); self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]) .map_err(|mut err| { - err.span_label(arrow_span, "while parsing the match arm starting here"); 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 @@ -3472,11 +3461,16 @@ impl<'a> Parser<'a> { // | - ^^ 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_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 })?; diff --git a/src/test/ui/missing-block-hint.stderr b/src/test/ui/missing-block-hint.stderr index ae583d0d4ba4d..a48eff890b331 100644 --- a/src/test/ui/missing-block-hint.stderr +++ b/src/test/ui/missing-block-hint.stderr @@ -2,7 +2,9 @@ error: expected `{`, found `=>` --> $DIR/missing-block-hint.rs:13:18 | LL | if (foo) => {} //~ ERROR expected `{`, found `=>` - | ^^ help: only necessary in match arms, not before if blocks + | -- ^^ + | | + | this `if` statement has a condition, but no block error: expected `{`, found `bar` --> $DIR/missing-block-hint.rs:17:13 diff --git a/src/test/ui/suggestions/missing-comma-in-match.rs b/src/test/ui/suggestions/missing-comma-in-match.rs index e02a8df3343b3..6f86cdea3cf5e 100644 --- a/src/test/ui/suggestions/missing-comma-in-match.rs +++ b/src/test/ui/suggestions/missing-comma-in-match.rs @@ -14,7 +14,6 @@ fn main() { &Some(2) => { 3 } //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here - //~^^^^ NOTE while parsing the match arm starting here _ => 2 }; } diff --git a/src/test/ui/suggestions/missing-comma-in-match.stderr b/src/test/ui/suggestions/missing-comma-in-match.stderr index 864fde49a5e51..71123a160a5f8 100644 --- a/src/test/ui/suggestions/missing-comma-in-match.stderr +++ b/src/test/ui/suggestions/missing-comma-in-match.stderr @@ -2,9 +2,7 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` --> $DIR/missing-comma-in-match.rs:14:18 | 13 | &None => 1 - | -- - help: missing a comma here to end this match arm - | | - | while parsing the match arm starting here + | - help: missing a comma here to end this `match` arm 14 | &Some(2) => { 3 } | ^^ expected one of `,`, `.`, `?`, `}`, or an operator here From 24be75d420bf316cb09c179781d6c1c63636fbc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 28 Feb 2018 10:56:07 -0800 Subject: [PATCH 07/13] fix rebase --- src/test/ui/if-without-block.stderr | 4 ++-- src/test/ui/suggestions/missing-comma-in-match.stderr | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui/if-without-block.stderr b/src/test/ui/if-without-block.stderr index 8f6e53bd28bf3..bc8e7310ce371 100644 --- a/src/test/ui/if-without-block.stderr +++ b/src/test/ui/if-without-block.stderr @@ -1,10 +1,10 @@ error: expected `{`, found `}` --> $DIR/if-without-block.rs:17:1 | -13 | if 5 == { +LL | if 5 == { | -- this `if` statement has a condition, but no block ... -17 | } +LL | } | ^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/missing-comma-in-match.stderr b/src/test/ui/suggestions/missing-comma-in-match.stderr index 71123a160a5f8..b71a50b66318e 100644 --- a/src/test/ui/suggestions/missing-comma-in-match.stderr +++ b/src/test/ui/suggestions/missing-comma-in-match.stderr @@ -1,9 +1,9 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>` --> $DIR/missing-comma-in-match.rs:14:18 | -13 | &None => 1 +LL | &None => 1 | - help: missing a comma here to end this `match` arm -14 | &Some(2) => { 3 } +LL | &Some(2) => { 3 } | ^^ expected one of `,`, `.`, `?`, `}`, or an operator here error: aborting due to previous error From 5ac4f62f3832f2a4ed26ab95567c96a38a9f4f15 Mon Sep 17 00:00:00 2001 From: M Farkas-Dyck Date: Wed, 28 Feb 2018 20:57:56 -0800 Subject: [PATCH 08/13] impl Clone for ::std_unicode::char::{ToLowercase, ToUppercase} --- src/libstd_unicode/char.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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), From 39d0b054cea73614a0c1dd06cd98d3d22eea6b10 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Thu, 1 Mar 2018 14:47:20 +0200 Subject: [PATCH 09/13] Restore the download of rust-mingw The build might otherwise break due to mixing MinGW object files from rust-std and the local MinGW which might be newer/older than the version used to build rust-std. Fixes #48272 --- src/bootstrap/bootstrap.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5966bb65df9c8..761cc94c8c66f 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -351,6 +351,11 @@ def download_stage0(self): with open(self.rustc_stamp(), 'w') as rust_stamp: rust_stamp.write(self.date) + 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())): From 5332d9a8e8a66e22b8c81f3f302ce72734ba137f Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Thu, 1 Mar 2018 18:33:14 +0200 Subject: [PATCH 10/13] Document why we download rust-mingw --- src/bootstrap/bootstrap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 761cc94c8c66f..5d297570bc12c 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -351,6 +351,9 @@ 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) From 2e9d9d48d5b93fdb800eead15f658f47100e2d3c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 1 Mar 2018 07:51:00 -0800 Subject: [PATCH 11/13] rustc: More stable hashes of command line arguments Currently rustc isn't always the best at producing deterministic builds of a crate when the source directory of a crate is changed. This is happening due to what appears two different sources: * First the `-L` paths passed to rustc are hashed into the crate hash. These paths through Cargo are typically absolute paths that can vary if the build directory changes. * Next the paths passed to `--extern` are also hashed which like `-L` can change if the build directory changes. This commit fixes these two sources of nondeterminism by ensuring that avoiding tracking the hashes of these arguments on the command line. For `-L` paths they're either related to loading crates (whose hashes are tracked elsewhere) or native librarise used in the linking phase (which isn't incremental). The `--extern` paths are similar in that they're related to crate resolution which is already tracked independently of the command line arguments. Closes #48019 --- src/librustc/session/config.rs | 123 +----------------- src/test/run-make/reproducible-build/Makefile | 76 +++++++++-- .../reproducible-build/reproducible-build.rs | 2 +- 3 files changed, 71 insertions(+), 130 deletions(-) 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/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; From 2269ff521fe2a945e462d5156799011c5fce2966 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Fri, 2 Mar 2018 03:29:35 -0500 Subject: [PATCH 12/13] Remove print_what_bootstrap_means It was an existing solution to tell the user why a --help command takes a long time to process. However, it would only print if the stage0 rust compiler needed to be downloaded, it came after update_submodules (which took a long time), and it was immediately followed by download messages and loading bars, meaning users could easily gloss over the message. This commit also moves the help message out of main(), and instead puts it at the top of bootstrap(). main() is intended to be minimal, only handling error messages. --- src/bootstrap/bootstrap.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index f5fcf4ba0f560..327ae0cb65c88 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( @@ -354,7 +352,6 @@ def download_stage0(self): 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 +552,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 +565,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) @@ -672,6 +651,14 @@ def set_dev_environment(self): 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') @@ -763,12 +750,6 @@ def main(): help_triggered = ( '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: - # 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("NOTE: Downloading and compiling bootstrap requirements before processing") - print(" --help command. See src/bootstrap/README.md for help with common") - print(" commands.") bootstrap(help_triggered) if not help_triggered: print("Build completed successfully in {}".format( From 4d63f8161b832f9c30f1c9815ceb6b5226eb85fa Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 17 Feb 2018 17:23:19 -0800 Subject: [PATCH 13/13] std: Add `arch` and `simd` modules This commit imports the `stdsimd` crate into the standard library, creating an `arch` and `simd` module inside of both libcore and libstd. Both of these modules are **unstable** and will continue to be so until RFC 2335 is stabilized. As a brief recap, the modules are organized as so: * `arch` contains all current architectures with intrinsics, for example `std::arch::x86`, `std::arch::x86_64`, `std::arch::arm`, etc. These modules contain all of the intrinsics defined for the platform, like `_mm_set1_epi8`. * In the standard library, the `arch` module also exports a `is_target_feature_detected` macro which performs runtime detection to determine whether a target feature is available at runtime. * The `simd` module contains experimental versions of strongly-typed lane-aware SIMD primitives, to be fully fleshed out in a future RFC. The main purpose of this commit is to start pulling in all these intrinsics and such into the standard library on nightly and allow testing and such. This'll help allow users to easily kick the tires and see if intrinsics work as well as allow us to test out all the infrastructure for moving the intrinsics into the standard library. --- .gitmodules | 3 +++ src/libcore/lib.rs | 33 +++++++++++++++++++++++++++++---- src/libstd/lib.rs | 30 ++++++++++++++++++++++++++++++ src/stdsimd | 1 + src/tools/tidy/src/lib.rs | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) create mode 160000 src/stdsimd 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/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/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/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/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)) }