From 2aff5b81f4344287acf9db36762aa90b3406c301 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 9 Jan 2020 23:00:28 +0100 Subject: [PATCH 1/7] expect `fn` after `const unsafe` / `const extern` (cherry picked from commit 915db7ae6430baef99f186ba40f08e105b7694fe) --- src/librustc_parse/parser/item.rs | 2 +- ...onst-extern-fns-dont-need-fn-specifier-2.rs | 7 +++++++ ...-extern-fns-dont-need-fn-specifier-2.stderr | 8 ++++++++ ...-const-extern-fns-dont-need-fn-specifier.rs | 8 ++++++++ ...st-extern-fns-dont-need-fn-specifier.stderr | 18 ++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs create mode 100644 src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 34ef12e818c57..88aee15ff111a 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -144,7 +144,7 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span)); } let ext = self.parse_extern()?; - self.bump(); // `fn` + self.expect_keyword(kw::Fn)?; let header = FnHeader { unsafety, diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs new file mode 100644 index 0000000000000..7ced24808bf6e --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs @@ -0,0 +1,7 @@ +fn main() {} + +#[cfg(FALSE)] +fn container() { + const unsafe WhereIsFerris Now() {} + //~^ ERROR expected one of `extern` or `fn` +} diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr new file mode 100644 index 0000000000000..5ec9e2a91f1dc --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.stderr @@ -0,0 +1,8 @@ +error: expected one of `extern` or `fn`, found `WhereIsFerris` + --> $DIR/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs:5:18 + | +LL | const unsafe WhereIsFerris Now() {} + | ^^^^^^^^^^^^^ expected one of `extern` or `fn` + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs new file mode 100644 index 0000000000000..1886bfccb4e3e --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs @@ -0,0 +1,8 @@ +fn main() {} + +#[cfg(FALSE)] +fn container() { + const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } + //~^ ERROR expected `fn` + //~| ERROR `const extern fn` definitions are unstable +} diff --git a/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr new file mode 100644 index 0000000000000..cf71ed4d59765 --- /dev/null +++ b/src/test/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.stderr @@ -0,0 +1,18 @@ +error: expected `fn`, found `PUT_ANYTHING_YOU_WANT_HERE` + --> $DIR/issue-68062-const-extern-fns-dont-need-fn-specifier.rs:5:25 + | +LL | const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `fn` + +error[E0658]: `const extern fn` definitions are unstable + --> $DIR/issue-68062-const-extern-fns-dont-need-fn-specifier.rs:5:5 + | +LL | const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/64926 + = help: add `#![feature(const_extern_fn)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From 9b23f7cfc0dd88203f447e40ae0ac63356d5c991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jan 2020 22:10:18 -0800 Subject: [PATCH 2/7] Do not ICE on unicode next point Use `shrink_to_hi` instead of `next_point` Fix #68000. (cherry picked from commit fcd850fc5db2501d14b2e0cbfac8aa890d700e55) --- src/librustc_parse/parser/item.rs | 2 +- ...e-68000-unicode-ident-after-missing-comma.rs | 6 ++++++ ...000-unicode-ident-after-missing-comma.stderr | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs create mode 100644 src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 88aee15ff111a..b842fec29c074 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1572,7 +1572,7 @@ impl<'a> Parser<'a> { } } _ => { - let sp = self.sess.source_map().next_point(self.prev_span); + let sp = self.prev_span.shrink_to_hi(); let mut err = self.struct_span_err(sp, &format!("expected `,`, or `}}`, found {}", self.this_token_descr())); if self.token.is_ident() { diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs new file mode 100644 index 0000000000000..3c49a5a975209 --- /dev/null +++ b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs @@ -0,0 +1,6 @@ +pub struct Foo { + pub bar: Vecö + //~^ ERROR expected `,`, or `}`, found `ö` +} //~ ERROR expected `:`, found `}` + +fn main() {} diff --git a/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr new file mode 100644 index 0000000000000..ef365a616437b --- /dev/null +++ b/src/test/ui/issues/issue-68000-unicode-ident-after-missing-comma.stderr @@ -0,0 +1,17 @@ +error: expected `,`, or `}`, found `ö` + --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:2:22 + | +LL | pub bar: Vecö + | ^ help: try adding a comma: `,` + +error: expected `:`, found `}` + --> $DIR/issue-68000-unicode-ident-after-missing-comma.rs:4:1 + | +LL | pub bar: Vecö + | - expected `:` +LL | +LL | } + | ^ unexpected token + +error: aborting due to 2 previous errors + From 28e0b42fd445ad7a552569478f3c30adbc9127ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:02:47 -0800 Subject: [PATCH 3/7] Fix `next_point` to be unicode aware (cherry picked from commit 3250057da983fa4d5bfd0799adaa41cb038f0e25) --- src/libsyntax_pos/source_map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax_pos/source_map.rs b/src/libsyntax_pos/source_map.rs index b597fad080fa0..b252dabfa3cf9 100644 --- a/src/libsyntax_pos/source_map.rs +++ b/src/libsyntax_pos/source_map.rs @@ -739,7 +739,7 @@ impl SourceMap { pub fn next_point(&self, sp: Span) -> Span { let start_of_next_point = sp.hi().0; - let width = self.find_width_of_character_at_span(sp, true); + let width = self.find_width_of_character_at_span(sp.shrink_to_hi(), true); // If the width is 1, then the next span should point to the same `lo` and `hi`. However, // in the case of a multibyte character, where the width != 1, the next span should // span multiple bytes to include the whole character. From 89c526a6b711d6af9192946911d9701ff9075f8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:03:26 -0800 Subject: [PATCH 4/7] Fix invalid bounding box (cherry picked from commit d558f6a570a782cd1c2e54de790f4f968b0de5f1) --- src/librustc_errors/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index ae5876848185b..c2c9f0374ee6d 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -181,7 +181,7 @@ impl CodeSuggestion { // Find the bounding span. let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap(); - let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap(); + let hi = substitution.parts.iter().map(|part| part.span.hi()).max().unwrap(); let bounding_span = Span::with_root_ctxt(lo, hi); let lines = cm.span_to_lines(bounding_span).unwrap(); assert!(!lines.lines.is_empty()); From ec4a464d153f9e663712a8f1f62d9ca75890655a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:22:33 -0800 Subject: [PATCH 5/7] Change `next_point` when `shrink_to_hi` is more appropriate (cherry picked from commit b93ef68245807bac97cd17ea9eaa13169380d815) --- src/librustc_parse/parser/diagnostics.rs | 10 ++++------ src/librustc_parse/parser/expr.rs | 2 +- src/librustc_parse/parser/item.rs | 4 ++-- src/librustc_parse/parser/mod.rs | 2 +- src/librustc_typeck/check/callee.rs | 5 ++--- src/librustc_typeck/check/mod.rs | 3 +-- src/libsyntax_expand/mbe/macro_parser.rs | 2 +- src/libsyntax_ext/assert.rs | 2 +- 8 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index ba125cacab48b..60a6fc5ed7bbf 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -300,15 +300,13 @@ impl<'a> Parser<'a> { expect.clone() }; (format!("expected one of {}, found {}", expect, actual), - (self.sess.source_map().next_point(self.prev_span), - format!("expected one of {}", short_expect))) + (self.prev_span.shrink_to_hi(), format!("expected one of {}", short_expect))) } else if expected.is_empty() { (format!("unexpected token: {}", actual), (self.prev_span, "unexpected token after this".to_string())) } else { (format!("expected {}, found {}", expect, actual), - (self.sess.source_map().next_point(self.prev_span), - format!("expected {}", expect))) + (self.prev_span.shrink_to_hi(), format!("expected {}", expect))) }; self.last_unexpected_token_span = Some(self.token.span); let mut err = self.fatal(&msg_exp); @@ -871,7 +869,7 @@ impl<'a> Parser<'a> { _ if self.prev_span == DUMMY_SP => (self.token.span, self.token.span), // EOF, don't want to point at the following char, but rather the last token. (token::Eof, None) => (self.prev_span, self.token.span), - _ => (self.sess.source_map().next_point(self.prev_span), self.token.span), + _ => (self.prev_span.shrink_to_hi(), self.token.span), }; let msg = format!( "expected `{}`, found {}", @@ -1179,7 +1177,7 @@ impl<'a> Parser<'a> { err.span_label(sp, "unclosed delimiter"); } err.span_suggestion_short( - self.sess.source_map().next_point(self.prev_span), + self.prev_span.shrink_to_hi(), &format!("{} may belong here", delim.to_string()), delim.to_string(), Applicability::MaybeIncorrect, diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 3cd4988ce0be5..b84e9cab5f4e1 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1647,7 +1647,7 @@ impl<'a> Parser<'a> { // | | // | parsed until here as `"y" & X` err.span_suggestion_short( - cm.next_point(arm_start_span), + arm_start_span.shrink_to_hi(), "missing a comma here to end this `match` arm", ",".to_owned(), Applicability::MachineApplicable diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index b842fec29c074..130ce1348229c 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -1706,7 +1706,7 @@ impl<'a> Parser<'a> { // it's safe to peel off one character only when it has the close delim self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)) } else { - self.sess.source_map().next_point(self.prev_span) + self.prev_span.shrink_to_hi() }; self.struct_span_err( @@ -1720,7 +1720,7 @@ impl<'a> Parser<'a> { ], Applicability::MaybeIncorrect, ).span_suggestion( - self.sess.source_map().next_point(self.prev_span), + self.prev_span.shrink_to_hi(), "add a semicolon", ';'.to_string(), Applicability::MaybeIncorrect, diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 07e99cfe01292..d6878411073ab 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -803,7 +803,7 @@ impl<'a> Parser<'a> { break; } Err(mut expect_err) => { - let sp = self.sess.source_map().next_point(self.prev_span); + let sp = self.prev_span.shrink_to_hi(); let token_str = pprust::token_kind_to_string(t); // Attempt to keep parsing if it was a similar separator. diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 1b3af48ea83bf..bfc615639486f 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -254,7 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::ExprKind::Block(..), ) = (parent_node, callee_node) { let start = sp.shrink_to_lo(); - let end = self.tcx.sess.source_map().next_point(callee_span); + let end = callee_span.shrink_to_hi(); err.multipart_suggestion( "if you meant to create this closure and immediately call it, surround the \ closure with parenthesis", @@ -332,9 +332,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span); if call_is_multiline { - let span = self.tcx.sess.source_map().next_point(callee.span); err.span_suggestion( - span, + callee.span.shrink_to_hi(), "try adding a semicolon", ";".to_owned(), Applicability::MaybeIncorrect, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 09771bb762536..8fb0858bfec3a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4834,9 +4834,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::Block(..) => { - let sp = self.tcx.sess.source_map().next_point(cause_span); err.span_suggestion( - sp, + cause_span.shrink_to_hi(), "try adding a semicolon", ";".to_string(), Applicability::MachineApplicable); diff --git a/src/libsyntax_expand/mbe/macro_parser.rs b/src/libsyntax_expand/mbe/macro_parser.rs index 1e2f3f9d1e53e..50718d51be901 100644 --- a/src/libsyntax_expand/mbe/macro_parser.rs +++ b/src/libsyntax_expand/mbe/macro_parser.rs @@ -708,7 +708,7 @@ pub(super) fn parse( Token::new(token::Eof, if parser.token.span.is_dummy() { parser.token.span } else { - sess.source_map().next_point(parser.token.span) + parser.token.span.shrink_to_hi() }), "missing tokens in macro arguments", ); diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index c788d06299405..1bae4743320f1 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -105,7 +105,7 @@ fn parse_assert<'a>( let custom_message = if let token::Literal(token::Lit { kind: token::Str, .. }) = parser.token.kind { let mut err = cx.struct_span_warn(parser.token.span, "unexpected string literal"); - let comma_span = cx.source_map().next_point(parser.prev_span); + let comma_span = parser.prev_span.shrink_to_hi(); err.span_suggestion_short( comma_span, "try adding a comma", From 84eb3b27bfe540375b16c93bda0dd552661a27d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Jan 2020 11:22:57 -0800 Subject: [PATCH 6/7] Add ICE regression tests (cherry picked from commit f6e9fd037a7b55f8f4fe78694b77d9788b18dfeb) --- src/test/ui/issues/issue-68091-unicode-ident-after-if.rs | 9 +++++++++ .../ui/issues/issue-68091-unicode-ident-after-if.stderr | 8 ++++++++ .../issue-68092-unicode-ident-after-incomplete-expr.rs | 9 +++++++++ ...ssue-68092-unicode-ident-after-incomplete-expr.stderr | 8 ++++++++ 4 files changed, 34 insertions(+) create mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.rs create mode 100644 src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr create mode 100644 src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs create mode 100644 src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs b/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs new file mode 100644 index 0000000000000..99d69d2199596 --- /dev/null +++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.rs @@ -0,0 +1,9 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* {} //~ ERROR missing condition for `if` expression + }; +} + +fn main() { + x!(if); +} diff --git a/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr new file mode 100644 index 0000000000000..aac04f4b747bc --- /dev/null +++ b/src/test/ui/issues/issue-68091-unicode-ident-after-if.stderr @@ -0,0 +1,8 @@ +error: missing condition for `if` expression + --> $DIR/issue-68091-unicode-ident-after-if.rs:3:14 + | +LL | $($c)ö* {} + | ^ expected if condition here + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs new file mode 100644 index 0000000000000..1a90b4724d49d --- /dev/null +++ b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs @@ -0,0 +1,9 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression + }; +} + +fn main() { + x!(!); +} diff --git a/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr new file mode 100644 index 0000000000000..0b9c364f1f1fb --- /dev/null +++ b/src/test/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.stderr @@ -0,0 +1,8 @@ +error: macro expansion ends with an incomplete expression: expected expression + --> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:14 + | +LL | $($c)ö* + | ^ expected expression + +error: aborting due to previous error + From 076095b04907091f20ed6a915dbdbb23652d1520 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Tue, 7 Jan 2020 23:21:24 +0000 Subject: [PATCH 7/7] rustdoc: Don't allow `#![feature(...)]` on stable or beta (cherry picked from commit 40571995984a0f2c466f77955e7d147887c2179b) --- src/librustdoc/core.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index a524801bea6bf..dd2e1144301ec 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -318,8 +318,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt cg: codegen_options, externs, target_triple: target, - // Ensure that rustdoc works even if rustc is feature-staged - unstable_features: UnstableFeatures::Allow, + unstable_features: UnstableFeatures::from_environment(), actually_rustdoc: true, debugging_opts: debugging_options, error_format,