From ff0513c6973523b65f59b8b508ca85dc2944c988 Mon Sep 17 00:00:00 2001 From: Kornel Date: Mon, 7 Aug 2017 18:23:15 +0100 Subject: [PATCH 1/3] Hint correct extern constant syntax --- src/libsyntax/parse/parser.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ca362ec93683d..c34317e649d8c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6007,7 +6007,9 @@ impl<'a> Parser<'a> { } if self.check_keyword(keywords::Const) { - return Err(self.span_fatal(self.span, "extern items cannot be `const`")); + let mut err = self.span_fatal(self.span, "extern items cannot be `const`"); + err.help("use `static` instead"); + return Err(err); } // FIXME #5668: this will occur for a macro invocation: From a965beef8f362e1db47eadd0ff701ec57cc23cfe Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 10 Aug 2017 01:43:06 +0300 Subject: [PATCH 2/3] Better diagnostics and recovery for `const` in extern blocks --- src/libsyntax/parse/parser.rs | 24 ++++++++++++------------ src/test/ui/extern-const.rs | 19 +++++++++++++++++++ src/test/ui/extern-const.stderr | 8 ++++++++ 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/extern-const.rs create mode 100644 src/test/ui/extern-const.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c34317e649d8c..cb28f356fe6fb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5518,12 +5518,11 @@ impl<'a> Parser<'a> { }) } - /// Parse a static item from a foreign module + /// Parse a static item from a foreign module. + /// Assumes that the `static` keyword is already parsed. fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec) -> PResult<'a, ForeignItem> { - self.expect_keyword(keywords::Static)?; let mutbl = self.eat_keyword(keywords::Mut); - let ident = self.parse_ident()?; self.expect(&token::Colon)?; let ty = self.parse_ty()?; @@ -5997,21 +5996,22 @@ impl<'a> Parser<'a> { let lo = self.span; let visibility = self.parse_visibility(false)?; - if self.check_keyword(keywords::Static) { - // FOREIGN STATIC ITEM + // FOREIGN STATIC ITEM + // Treat `const` as `static` for error recovery, but don't add it to expected tokens. + if self.check_keyword(keywords::Static) || self.token.is_keyword(keywords::Const) { + if self.token.is_keyword(keywords::Const) { + self.diagnostic() + .struct_span_err(self.span, "extern items cannot be `const`") + .span_label(self.span, "use `static` instead").emit(); + } + self.bump(); // `static` or `const` return Ok(Some(self.parse_item_foreign_static(visibility, lo, attrs)?)); } + // FOREIGN FUNCTION ITEM if self.check_keyword(keywords::Fn) { - // FOREIGN FUNCTION ITEM return Ok(Some(self.parse_item_foreign_fn(visibility, lo, attrs)?)); } - if self.check_keyword(keywords::Const) { - let mut err = self.span_fatal(self.span, "extern items cannot be `const`"); - err.help("use `static` instead"); - return Err(err); - } - // FIXME #5668: this will occur for a macro invocation: match self.parse_macro_use_or_failure(attrs, true, false, lo, visibility)? { Some(item) => { diff --git a/src/test/ui/extern-const.rs b/src/test/ui/extern-const.rs new file mode 100644 index 0000000000000..a77d7b1189566 --- /dev/null +++ b/src/test/ui/extern-const.rs @@ -0,0 +1,19 @@ +// Copyright 2017 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. + +// compile-flags: -Z continue-parse-after-error + +extern "C" { + const C: u8; //~ ERROR extern items cannot be `const` +} + +fn main() { + let x = C; +} diff --git a/src/test/ui/extern-const.stderr b/src/test/ui/extern-const.stderr new file mode 100644 index 0000000000000..e6c41a05594e2 --- /dev/null +++ b/src/test/ui/extern-const.stderr @@ -0,0 +1,8 @@ +error: extern items cannot be `const` + --> $DIR/extern-const.rs:14:5 + | +14 | const C: u8; //~ ERROR extern items cannot be `const` + | ^^^^^ use `static` instead + +error: aborting due to previous error + From cabc9be9e2057c5197db273ba0c750aad5ff3366 Mon Sep 17 00:00:00 2001 From: Kornel Date: Thu, 10 Aug 2017 12:16:01 +0100 Subject: [PATCH 3/3] Reword error hint --- src/libsyntax/parse/parser.rs | 3 ++- src/test/ui/extern-const.stderr | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cb28f356fe6fb..7bf4c6799b3cb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6002,7 +6002,8 @@ impl<'a> Parser<'a> { if self.token.is_keyword(keywords::Const) { self.diagnostic() .struct_span_err(self.span, "extern items cannot be `const`") - .span_label(self.span, "use `static` instead").emit(); + .span_suggestion(self.span, "instead try using", "static".to_owned()) + .emit(); } self.bump(); // `static` or `const` return Ok(Some(self.parse_item_foreign_static(visibility, lo, attrs)?)); diff --git a/src/test/ui/extern-const.stderr b/src/test/ui/extern-const.stderr index e6c41a05594e2..c5a3149e85a7a 100644 --- a/src/test/ui/extern-const.stderr +++ b/src/test/ui/extern-const.stderr @@ -2,7 +2,7 @@ error: extern items cannot be `const` --> $DIR/extern-const.rs:14:5 | 14 | const C: u8; //~ ERROR extern items cannot be `const` - | ^^^^^ use `static` instead + | ^^^^^ help: instead try using: `static` error: aborting due to previous error