From d6238bd8d4fe283968abbf46357c8e56f283b65b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 15 Feb 2020 22:21:00 +0100 Subject: [PATCH] reject assoc statics & extern consts during parsing --- src/librustc_ast_passes/ast_validation.rs | 28 +------ src/librustc_parse/parser/item.rs | 27 ++++++- src/test/ui/extern/extern-const.stderr | 2 - .../parser/assoc-static-semantic-fail.stderr | 48 ++++++------ .../ui/parser/assoc-static-syntactic-fail.rs | 27 +++++++ .../parser/assoc-static-syntactic-fail.stderr | 74 +++++++++++++++++++ .../ui/parser/assoc-static-syntactic-pass.rs | 29 -------- .../parser/foreign-const-semantic-fail.stderr | 5 -- .../ui/parser/foreign-const-syntactic-fail.rs | 9 +++ .../foreign-const-syntactic-fail.stderr | 22 ++++++ .../ui/parser/foreign-const-syntactic-pass.rs | 11 --- 11 files changed, 185 insertions(+), 97 deletions(-) create mode 100644 src/test/ui/parser/assoc-static-syntactic-fail.rs create mode 100644 src/test/ui/parser/assoc-static-syntactic-fail.stderr delete mode 100644 src/test/ui/parser/assoc-static-syntactic-pass.rs create mode 100644 src/test/ui/parser/foreign-const-syntactic-fail.rs create mode 100644 src/test/ui/parser/foreign-const-syntactic-fail.stderr delete mode 100644 src/test/ui/parser/foreign-const-syntactic-pass.rs diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 8efd50ad0987..d3fcb589fd0f 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -533,20 +533,6 @@ impl<'a> AstValidator<'a> { } } - fn error_foreign_const(&self, ident: Ident, span: Span) { - self.err_handler() - .struct_span_err(ident.span, "extern items cannot be `const`") - .span_suggestion( - span.with_hi(ident.span.lo()), - "try using a static value", - "static ".to_string(), - Applicability::MachineApplicable, - ) - .span_label(self.current_extern_span(), "in this `extern` block") - .note(MORE_EXTERN) - .emit(); - } - /// Reject C-varadic type unless the function is foreign, /// or free and `unsafe extern "C"` semantically. fn check_c_varadic_type(&self, fk: FnKind<'a>) { @@ -1003,10 +989,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ForeignItemKind::Static(_, _, body) => { self.check_foreign_kind_bodyless(fi.ident, "static", body.as_ref().map(|b| b.span)); } - ForeignItemKind::Const(..) => { - self.error_foreign_const(fi.ident, fi.span); - } - ForeignItemKind::Macro(..) => {} + ForeignItemKind::Const(..) | ForeignItemKind::Macro(..) => {} } visit::walk_foreign_item(self, fi) @@ -1267,13 +1250,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } - match item.kind { - AssocItemKind::Const(..) => self.check_item_named(item.ident, "const"), - AssocItemKind::Static(..) => self - .err_handler() - .struct_span_err(item.span, "associated `static` items are not allowed") - .emit(), - _ => {} + if let AssocItemKind::Const(..) = item.kind { + self.check_item_named(item.ident, "const"); } self.with_in_trait_impl(false, |this| visit::walk_assoc_item(this, item, ctxt)); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 20d6182ddc19..da72da043650 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -643,9 +643,16 @@ impl<'a> Parser<'a> { if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) { item.tokens = Some(tokens); } + self.error_on_assoc_static(&item); Ok(P(item)) } + fn error_on_assoc_static(&self, item: &AssocItem) { + if let AssocItemKind::Static(..) = item.kind { + self.struct_span_err(item.span, "associated `static` items are not allowed").emit(); + } + } + fn parse_assoc_item_( &mut self, at_end: &mut bool, @@ -868,7 +875,25 @@ impl<'a> Parser<'a> { let lo = self.token.span; let vis = self.parse_visibility(FollowedByType::No)?; let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, |_| true, &vis)?; - Ok(P(self.mk_item(lo, ident, kind, vis, attrs))) + let item = self.mk_item(lo, ident, kind, vis, attrs); + self.error_on_foreign_const(&item); + Ok(P(item)) + } + + fn error_on_foreign_const(&self, item: &ForeignItem) { + if let AssocItemKind::Const(..) = item.kind { + self.struct_span_err(item.ident.span, "extern items cannot be `const`") + .span_suggestion( + item.span.with_hi(item.ident.span.lo()), + "try using a static value", + "static ".to_string(), + Applicability::MachineApplicable, + ) + .note( + "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html", + ) + .emit(); + } } fn is_static_global(&mut self) -> bool { diff --git a/src/test/ui/extern/extern-const.stderr b/src/test/ui/extern/extern-const.stderr index 97e11381c6f7..7f67adbdb19c 100644 --- a/src/test/ui/extern/extern-const.stderr +++ b/src/test/ui/extern/extern-const.stderr @@ -1,8 +1,6 @@ error: extern items cannot be `const` --> $DIR/extern-const.rs:16:11 | -LL | extern "C" { - | ---------- in this `extern` block LL | const rust_dbg_static_mut: libc::c_int; | ------^^^^^^^^^^^^^^^^^^^ | | diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr index d5a02c9bebcf..d02e2855c7e6 100644 --- a/src/test/ui/parser/assoc-static-semantic-fail.stderr +++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr @@ -34,30 +34,12 @@ error: associated `static` items are not allowed LL | static TB: u8; | ^^^^^^^^^^^^^^ -error: `default` is only allowed on items in `impl` definitions - --> $DIR/assoc-static-semantic-fail.rs:24:5 - | -LL | default static TC: u8 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: associated `static` items are not allowed --> $DIR/assoc-static-semantic-fail.rs:24:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `default` is only allowed on items in `impl` definitions - --> $DIR/assoc-static-semantic-fail.rs:27:5 - | -LL | pub(crate) default static TD: u8; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0449]: unnecessary visibility qualifier - --> $DIR/assoc-static-semantic-fail.rs:27:5 - | -LL | pub(crate) default static TD: u8; - | ^^^^^^^^^^ - error: associated `static` items are not allowed --> $DIR/assoc-static-semantic-fail.rs:27:5 | @@ -82,18 +64,36 @@ error: associated `static` items are not allowed LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0449]: unnecessary visibility qualifier - --> $DIR/assoc-static-semantic-fail.rs:40:5 - | -LL | pub default static TD: u8; - | ^^^ `pub` not permitted here because it's implied - error: associated `static` items are not allowed --> $DIR/assoc-static-semantic-fail.rs:40:5 | LL | pub default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: `default` is only allowed on items in `impl` definitions + --> $DIR/assoc-static-semantic-fail.rs:24:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `default` is only allowed on items in `impl` definitions + --> $DIR/assoc-static-semantic-fail.rs:27:5 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0449]: unnecessary visibility qualifier + --> $DIR/assoc-static-semantic-fail.rs:27:5 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^ + +error[E0449]: unnecessary visibility qualifier + --> $DIR/assoc-static-semantic-fail.rs:40:5 + | +LL | pub default static TD: u8; + | ^^^ `pub` not permitted here because it's implied + error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0449`. diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.rs b/src/test/ui/parser/assoc-static-syntactic-fail.rs new file mode 100644 index 000000000000..8f042767e550 --- /dev/null +++ b/src/test/ui/parser/assoc-static-syntactic-fail.rs @@ -0,0 +1,27 @@ +// Syntactically, we do allow e.g., `static X: u8 = 0;` as an associated item. + +fn main() {} + +#[cfg(FALSE)] +impl S { + static IA: u8 = 0; //~ ERROR associated `static` items are not allowed + static IB: u8; //~ ERROR associated `static` items are not allowed + default static IC: u8 = 0; //~ ERROR associated `static` items are not allowed + pub(crate) default static ID: u8; //~ ERROR associated `static` items are not allowed +} + +#[cfg(FALSE)] +trait T { + static TA: u8 = 0; //~ ERROR associated `static` items are not allowed + static TB: u8; //~ ERROR associated `static` items are not allowed + default static TC: u8 = 0; //~ ERROR associated `static` items are not allowed + pub(crate) default static TD: u8; //~ ERROR associated `static` items are not allowed +} + +#[cfg(FALSE)] +impl T for S { + static TA: u8 = 0; //~ ERROR associated `static` items are not allowed + static TB: u8; //~ ERROR associated `static` items are not allowed + default static TC: u8 = 0; //~ ERROR associated `static` items are not allowed + pub default static TD: u8; //~ ERROR associated `static` items are not allowed +} diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.stderr b/src/test/ui/parser/assoc-static-syntactic-fail.stderr new file mode 100644 index 000000000000..bb1e5c4be2e9 --- /dev/null +++ b/src/test/ui/parser/assoc-static-syntactic-fail.stderr @@ -0,0 +1,74 @@ +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:7:5 + | +LL | static IA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:8:5 + | +LL | static IB: u8; + | ^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:9:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:10:5 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:15:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:16:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:17:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:18:5 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:23:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:24:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:25:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-syntactic-fail.rs:26:5 + | +LL | pub default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + diff --git a/src/test/ui/parser/assoc-static-syntactic-pass.rs b/src/test/ui/parser/assoc-static-syntactic-pass.rs deleted file mode 100644 index 7f5b9f793356..000000000000 --- a/src/test/ui/parser/assoc-static-syntactic-pass.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Syntactically, we do allow e.g., `static X: u8 = 0;` as an associated item. - -// check-pass - -fn main() {} - -#[cfg(FALSE)] -impl S { - static IA: u8 = 0; - static IB: u8; - default static IC: u8 = 0; - pub(crate) default static ID: u8; -} - -#[cfg(FALSE)] -trait T { - static TA: u8 = 0; - static TB: u8; - default static TC: u8 = 0; - pub(crate) default static TD: u8; -} - -#[cfg(FALSE)] -impl T for S { - static TA: u8 = 0; - static TB: u8; - default static TC: u8 = 0; - pub default static TD: u8; -} diff --git a/src/test/ui/parser/foreign-const-semantic-fail.stderr b/src/test/ui/parser/foreign-const-semantic-fail.stderr index 799a795c5939..f364f11bb038 100644 --- a/src/test/ui/parser/foreign-const-semantic-fail.stderr +++ b/src/test/ui/parser/foreign-const-semantic-fail.stderr @@ -1,8 +1,6 @@ error: extern items cannot be `const` --> $DIR/foreign-const-semantic-fail.rs:4:11 | -LL | extern { - | ------ in this `extern` block LL | const A: isize; | ------^ | | @@ -13,9 +11,6 @@ LL | const A: isize; error: extern items cannot be `const` --> $DIR/foreign-const-semantic-fail.rs:6:11 | -LL | extern { - | ------ in this `extern` block -... LL | const B: isize = 42; | ------^ | | diff --git a/src/test/ui/parser/foreign-const-syntactic-fail.rs b/src/test/ui/parser/foreign-const-syntactic-fail.rs new file mode 100644 index 000000000000..a78f8b1623a8 --- /dev/null +++ b/src/test/ui/parser/foreign-const-syntactic-fail.rs @@ -0,0 +1,9 @@ +// Syntactically, a `const` item inside an `extern { ... }` block is not allowed. + +fn main() {} + +#[cfg(FALSE)] +extern { + const A: isize; //~ ERROR extern items cannot be `const` + const B: isize = 42; //~ ERROR extern items cannot be `const` +} diff --git a/src/test/ui/parser/foreign-const-syntactic-fail.stderr b/src/test/ui/parser/foreign-const-syntactic-fail.stderr new file mode 100644 index 000000000000..9cf58fa95fb2 --- /dev/null +++ b/src/test/ui/parser/foreign-const-syntactic-fail.stderr @@ -0,0 +1,22 @@ +error: extern items cannot be `const` + --> $DIR/foreign-const-syntactic-fail.rs:7:11 + | +LL | const A: isize; + | ------^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: extern items cannot be `const` + --> $DIR/foreign-const-syntactic-fail.rs:8:11 + | +LL | const B: isize = 42; + | ------^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/foreign-const-syntactic-pass.rs b/src/test/ui/parser/foreign-const-syntactic-pass.rs deleted file mode 100644 index bacef8e71d62..000000000000 --- a/src/test/ui/parser/foreign-const-syntactic-pass.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Syntactically, a `const` item inside an `extern { ... }` block is allowed. - -// check-pass - -fn main() {} - -#[cfg(FALSE)] -extern { - const A: isize; - const B: isize = 42; -}