diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 813af18c401..b465fd79c8f 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -760,7 +760,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let trait_item_def_id = self.resolver.definitions().local_def_id(i.id); let (generics, kind) = match i.kind { - AssocItemKind::Const(ref ty, ref default) => { + AssocItemKind::Static(ref ty, _, ref default) // Let's pretend this is a `const`. + | AssocItemKind::Const(ref ty, ref default) => { let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body)) @@ -802,7 +803,10 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { let (kind, has_default) = match &i.kind { - AssocItemKind::Const(_, default) => (hir::AssocItemKind::Const, default.is_some()), + AssocItemKind::Static(_, _, default) // Let's pretend this is a `const` for recovery. + | AssocItemKind::Const(_, default) => { + (hir::AssocItemKind::Const, default.is_some()) + } AssocItemKind::TyAlias(_, _, default) => (hir::AssocItemKind::Type, default.is_some()), AssocItemKind::Fn(sig, _, default) => { (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some()) @@ -827,7 +831,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let impl_item_def_id = self.resolver.definitions().local_def_id(i.id); let (generics, kind) = match i.kind { - AssocItemKind::Const(ref ty, ref expr) => { + AssocItemKind::Static(ref ty, _, ref expr) | AssocItemKind::Const(ref ty, ref expr) => { let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); ( hir::Generics::empty(), @@ -895,7 +899,8 @@ impl<'hir> LoweringContext<'_, 'hir> { vis: self.lower_visibility(&i.vis, Some(i.id)), defaultness: self.lower_defaultness(i.defaultness, true /* [1] */), kind: match &i.kind { - AssocItemKind::Const(..) => hir::AssocItemKind::Const, + AssocItemKind::Static(..) // Let's pretend this is a `const` for recovery. + | AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::TyAlias(_, _, ty) => { match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { None => hir::AssocItemKind::Type, diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index fd65750367e..72cffdd750a 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -1250,8 +1250,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } - if let AssocItemKind::Const(..) = item.kind { - self.check_item_named(item.ident, "const"); + 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(), + _ => {} } self.with_in_trait_impl(false, |this| visit::walk_assoc_item(this, item, ctxt)); diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index e9dacfec23c..ee1a829da1a 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1441,6 +1441,9 @@ impl<'a> State<'a> { self.print_outer_attributes(&item.attrs); self.print_defaultness(item.defaultness); match &item.kind { + ast::AssocItemKind::Static(ty, mutbl, expr) => { + self.print_item_const(item.ident, Some(*mutbl), ty, expr.as_deref(), &item.vis); + } ast::AssocItemKind::Const(ty, expr) => { self.print_item_const(item.ident, None, ty, expr.as_deref(), &item.vis); } diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index ab915802395..9b7728f27d0 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -546,6 +546,7 @@ impl<'a> Parser<'a> { 1, &[ kw::Impl, + kw::Static, kw::Const, kw::Async, kw::Fn, @@ -670,8 +671,14 @@ impl<'a> Parser<'a> { } else if self.check_fn_front_matter() { let (ident, sig, generics, body) = self.parse_fn(at_end, &mut attrs, req_name)?; (ident, AssocItemKind::Fn(sig, generics, body)) + } else if self.is_static_global() { + self.bump(); // `static` + let mutbl = self.parse_mutability(); + let (ident, ty, expr) = self.parse_item_const_common(Some(mutbl))?; + (ident, AssocItemKind::Static(ty, mutbl, expr)) } else if self.eat_keyword(kw::Const) { - self.parse_assoc_const()? + let (ident, ty, expr) = self.parse_item_const_common(None)?; + (ident, AssocItemKind::Const(ty, expr)) } else if self.isnt_macro_invocation() { return Err(self.missing_assoc_item_kind_err("associated", self.prev_span)); } else if self.token.is_path_start() { @@ -688,15 +695,6 @@ impl<'a> Parser<'a> { Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None }) } - /// This parses the grammar: - /// - /// AssocConst = "const" Ident ":" Ty "=" Expr ";" - fn parse_assoc_const(&mut self) -> PResult<'a, (Ident, AssocItemKind)> { - self.expect_keyword(kw::Const)?; - let (ident, ty, expr) = self.parse_item_const_common(None)?; - Ok((ident, AssocItemKind::Const(ty, expr))) - } - /// Parses the following grammar: /// /// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty] diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index f5e64443dda..7c541928e6f 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1251,7 +1251,8 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { // Add the item to the trait info. let item_def_id = self.r.definitions.local_def_id(item.id); let (res, ns) = match item.kind { - AssocItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), + AssocItemKind::Static(..) // Let's pretend it's a `const` for recovery. + | AssocItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), AssocItemKind::Fn(ref sig, _, _) => { if sig.decl.has_self() { self.r.has_self.insert(item_def_id); diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 256b5ff4b9a..60cba555121 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -228,7 +228,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { body.as_deref(), ); } - AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident.name), + AssocItemKind::Fn(..) | AssocItemKind::Const(..) | AssocItemKind::Static(..) => { + DefPathData::ValueNs(i.ident.name) + } AssocItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), AssocItemKind::Macro(..) => return self.visit_macro_invoc(i.id), }; diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 36667e1d6ff..7b445fcc035 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -836,7 +836,8 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { for item in trait_items { this.with_trait_items(trait_items, |this| { match &item.kind { - AssocItemKind::Const(ty, default) => { + AssocItemKind::Static(ty, _, default) + | AssocItemKind::Const(ty, default) => { this.visit_ty(ty); // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. @@ -1109,7 +1110,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { for item in impl_items { use crate::ResolutionError::*; match &item.kind { - AssocItemKind::Const(..) => { + AssocItemKind::Static(..) | AssocItemKind::Const(..) => { debug!("resolve_implementation AssocItemKind::Const",); // If this is a trait impl, ensure the const // exists in trait diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 574689be491..001f2f09854 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1004,7 +1004,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.process_macro_use(trait_item.span); let vis_span = trait_item.span.shrink_to_lo(); match trait_item.kind { - ast::AssocItemKind::Const(ref ty, ref expr) => { + ast::AssocItemKind::Static(ref ty, _, ref expr) + | ast::AssocItemKind::Const(ref ty, ref expr) => { self.process_assoc_const( trait_item.id, trait_item.ident, @@ -1074,7 +1075,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { fn process_impl_item(&mut self, impl_item: &'l ast::AssocItem, impl_id: DefId) { self.process_macro_use(impl_item.span); match impl_item.kind { - ast::AssocItemKind::Const(ref ty, ref expr) => { + ast::AssocItemKind::Static(ref ty, _, ref expr) + | ast::AssocItemKind::Const(ref ty, ref expr) => { self.process_assoc_const( impl_item.id, impl_item.ident, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bbb629012a9..ca39fbd6c5d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2654,6 +2654,8 @@ pub enum AssocItemKind { /// A constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`. /// If `def` is parsed, then the constant is provided, and otherwise required. Const(P, Option>), + /// A static item (`static FOO: u8`). + Static(P, Mutability, Option>), /// A function. Fn(FnSig, Generics, Option>), /// A type. diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 62f640f0bfa..91db6158689 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -954,7 +954,7 @@ pub fn noop_flat_map_assoc_item( visitor.visit_vis(vis); visit_attrs(attrs, visitor); match kind { - AssocItemKind::Const(ty, expr) => { + AssocItemKind::Const(ty, expr) | AssocItemKind::Static(ty, _, expr) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 0dd21cdf12f..f5763ecf573 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -633,7 +633,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, visitor.visit_ident(item.ident); walk_list!(visitor, visit_attribute, &item.attrs); match item.kind { - AssocItemKind::Const(ref ty, ref expr) => { + AssocItemKind::Const(ref ty, ref expr) | AssocItemKind::Static(ref ty, _, ref expr) => { visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } diff --git a/src/test/ui/issues/issue-58856-2.stderr b/src/test/ui/issues/issue-58856-2.stderr index 6221b90b31d..f4ca3c46ea2 100644 --- a/src/test/ui/issues/issue-58856-2.stderr +++ b/src/test/ui/issues/issue-58856-2.stderr @@ -7,11 +7,11 @@ LL | fn how_are_you(&self -> Empty { | | help: `)` may belong here | unclosed delimiter -error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, `}`, or identifier, found `)` +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `static`, `type`, `unsafe`, `}`, or identifier, found `)` --> $DIR/issue-58856-2.rs:11:1 | LL | } - | - expected one of 11 possible tokens + | - expected one of 12 possible tokens LL | } | ^ unexpected token diff --git a/src/test/ui/issues/issue-60075.stderr b/src/test/ui/issues/issue-60075.stderr index b2beb73503b..bab50a53b1a 100644 --- a/src/test/ui/issues/issue-60075.stderr +++ b/src/test/ui/issues/issue-60075.stderr @@ -4,7 +4,7 @@ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}` LL | }); | ^ expected one of `.`, `;`, `?`, `else`, or an operator -error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, `}`, or identifier, found `;` +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `static`, `type`, `unsafe`, `}`, or identifier, found `;` --> $DIR/issue-60075.rs:6:11 | LL | fn qux() -> Option { diff --git a/src/test/ui/parser/assoc-static-semantic-fail.rs b/src/test/ui/parser/assoc-static-semantic-fail.rs new file mode 100644 index 00000000000..cf3debd77cb --- /dev/null +++ b/src/test/ui/parser/assoc-static-semantic-fail.rs @@ -0,0 +1,43 @@ +// Semantically, we do not allow e.g., `static X: u8 = 0;` as an associated item. + +#![feature(specialization)] + +fn main() {} + +struct S; +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 +} + +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 + //~| ERROR `default` is only allowed on items in + pub(crate) default static TD: u8; + //~^ ERROR associated `static` items are not allowed + //~| ERROR `default` is only allowed on items in + //~| ERROR unnecessary visibility qualifier +} + +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 + //~| ERROR unnecessary visibility qualifier +} diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr new file mode 100644 index 00000000000..d5a02c9bebc --- /dev/null +++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr @@ -0,0 +1,99 @@ +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:9:5 + | +LL | static IA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:11:5 + | +LL | static IB: u8; + | ^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:13:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:15:5 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:20:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:22:5 + | +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 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:34:5 + | +LL | static TA: u8 = 0; + | ^^^^^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:36:5 + | +LL | static TB: u8; + | ^^^^^^^^^^^^^^ + +error: associated `static` items are not allowed + --> $DIR/assoc-static-semantic-fail.rs:38:5 + | +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: 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-pass.rs b/src/test/ui/parser/assoc-static-syntactic-pass.rs new file mode 100644 index 00000000000..7f5b9f79335 --- /dev/null +++ b/src/test/ui/parser/assoc-static-syntactic-pass.rs @@ -0,0 +1,29 @@ +// 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/issue-32446.stderr b/src/test/ui/parser/issue-32446.stderr index 25c1efe35ae..d25828da0b9 100644 --- a/src/test/ui/parser/issue-32446.stderr +++ b/src/test/ui/parser/issue-32446.stderr @@ -1,8 +1,8 @@ -error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, `}`, or identifier, found `...` +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `static`, `type`, `unsafe`, `}`, or identifier, found `...` --> $DIR/issue-32446.rs:4:11 | LL | trait T { ... } - | ^^^ expected one of 11 possible tokens + | ^^^ expected one of 12 possible tokens error: aborting due to previous error diff --git a/src/test/ui/parser/issue-41155.stderr b/src/test/ui/parser/issue-41155.stderr index 327bc65818f..a91ef6c67e8 100644 --- a/src/test/ui/parser/issue-41155.stderr +++ b/src/test/ui/parser/issue-41155.stderr @@ -1,8 +1,8 @@ -error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `type`, `unsafe`, or identifier, found `}` +error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `static`, `type`, `unsafe`, or identifier, found `}` --> $DIR/issue-41155.rs:5:1 | LL | pub - | - expected one of 9 possible tokens + | - expected one of 10 possible tokens LL | } | ^ unexpected token diff --git a/src/test/ui/parser/macro/trait-non-item-macros.stderr b/src/test/ui/parser/macro/trait-non-item-macros.stderr index 9d05e85bcc0..c76b096a1eb 100644 --- a/src/test/ui/parser/macro/trait-non-item-macros.stderr +++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr @@ -1,8 +1,8 @@ -error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or identifier, found `2` +error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `static`, `type`, `unsafe`, or identifier, found `2` --> $DIR/trait-non-item-macros.rs:2:19 | LL | ($a:expr) => ($a) - | ^^ expected one of 10 possible tokens + | ^^ expected one of 11 possible tokens ... LL | bah!(2); | -------- in this macro invocation diff --git a/src/test/ui/parser/removed-syntax-static-fn.rs b/src/test/ui/parser/removed-syntax-static-fn.rs index 9e12222f3fd..cd643b874db 100644 --- a/src/test/ui/parser/removed-syntax-static-fn.rs +++ b/src/test/ui/parser/removed-syntax-static-fn.rs @@ -1,8 +1,10 @@ struct S; impl S { - //~^ ERROR missing `fn`, `type`, or `const` for associated-item declaration static fn f() {} + //~^ ERROR expected identifier, found keyword `fn` + //~| ERROR expected one of `:`, `;`, or `=` + //~| ERROR missing type for `static` item } fn main() {} diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr index 5edf88026fb..dc5625bdade 100644 --- a/src/test/ui/parser/removed-syntax-static-fn.stderr +++ b/src/test/ui/parser/removed-syntax-static-fn.stderr @@ -1,11 +1,20 @@ -error: missing `fn`, `type`, or `const` for associated-item declaration - --> $DIR/removed-syntax-static-fn.rs:3:9 +error: expected identifier, found keyword `fn` + --> $DIR/removed-syntax-static-fn.rs:4:12 | -LL | impl S { - | _________^ -LL | | -LL | | static fn f() {} - | |____^ missing `fn`, `type`, or `const` +LL | static fn f() {} + | ^^ expected identifier, found keyword -error: aborting due to previous error +error: expected one of `:`, `;`, or `=`, found `f` + --> $DIR/removed-syntax-static-fn.rs:4:15 + | +LL | static fn f() {} + | ^ expected one of `:`, `;`, or `=` + +error: missing type for `static` item + --> $DIR/removed-syntax-static-fn.rs:4:12 + | +LL | static fn f() {} + | ^^ help: provide a type for the item: `r#fn: ` + +error: aborting due to 3 previous errors