diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 1a19fab0265e6..b5e4fe90d0dce 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -173,7 +173,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ids } - ItemKind::Const(ref ty, ..) => { + ItemKind::Const(_, ref ty, ..) => { let mut ids = smallvec![i.id]; if self.sess.features_untracked().impl_trait_in_bindings { let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids }; @@ -264,11 +264,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); hir::ItemKind::Static(ty, m, body_id) } - ItemKind::Const(ref t, ref e) => { + ItemKind::Const(_, ref t, ref e) => { let (ty, body_id) = self.lower_const_item(t, span, e.as_deref()); hir::ItemKind::Const(ty, body_id) } - ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => { + ItemKind::Fn(_, FnSig { ref decl, header }, ref generics, ref body) => { let fn_def_id = self.resolver.definitions().local_def_id(id); self.with_new_scopes(|this| { this.current_item = Some(ident.span); @@ -297,16 +297,16 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)), ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)), ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)), - ItemKind::TyAlias(ref generics, _, Some(ref ty)) => match ty.kind.opaque_top_hack() { + ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => match ty.kind.opaque_top_hack() { None => { let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); - let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); + let generics = self.lower_generics(gen, ImplTraitContext::disallowed()); hir::ItemKind::TyAlias(ty, generics) } Some(bounds) => { let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc); let ty = hir::OpaqueTy { - generics: self.lower_generics(generics, ctx()), + generics: self.lower_generics(gen, ctx()), bounds: self.lower_param_bounds(bounds, ctx()), impl_trait_fn: None, origin: hir::OpaqueTyOrigin::TypeAlias, @@ -314,7 +314,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::OpaqueTy(ty) } }, - ItemKind::TyAlias(ref generics, _, None) => { + ItemKind::TyAlias(_, ref generics, _, None) => { let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err)); let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); hir::ItemKind::TyAlias(ty, generics) @@ -654,7 +654,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ident: i.ident, attrs: self.lower_attrs(&i.attrs), kind: match i.kind { - ForeignItemKind::Fn(ref sig, ref generics, _) => { + ForeignItemKind::Fn(_, ref sig, ref generics, _) => { let fdec = &sig.decl; let (generics, (fn_dec, fn_args)) = self.add_in_band_defs( generics, @@ -675,7 +675,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let ty = self.lower_ty(t, ImplTraitContext::disallowed()); hir::ForeignItemKind::Static(ty, m) } - ForeignItemKind::Const(ref t, _) => { + ForeignItemKind::Const(_, ref t, _) => { // For recovery purposes. let ty = self.lower_ty(t, ImplTraitContext::disallowed()); hir::ForeignItemKind::Static(ty, Mutability::Not) @@ -758,24 +758,24 @@ impl<'hir> LoweringContext<'_, 'hir> { let (generics, kind) = match i.kind { AssocItemKind::Static(ref ty, _, ref default) // Let's pretend this is a `const`. - | AssocItemKind::Const(ref ty, ref default) => { + | 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)) } - AssocItemKind::Fn(ref sig, ref generics, None) => { + AssocItemKind::Fn(_, ref sig, ref generics, None) => { let names = self.lower_fn_params_to_names(&sig.decl); let (generics, sig) = self.lower_method_sig(generics, sig, trait_item_def_id, false, None); (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names))) } - AssocItemKind::Fn(ref sig, ref generics, Some(ref body)) => { + AssocItemKind::Fn(_, ref sig, ref generics, Some(ref body)) => { let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body)); let (generics, sig) = self.lower_method_sig(generics, sig, trait_item_def_id, false, None); (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id))) } - AssocItemKind::TyAlias(ref generics, ref bounds, ref default) => { + AssocItemKind::TyAlias(_, ref generics, ref bounds, ref default) => { let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed())); let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); let kind = hir::TraitItemKind::Type( @@ -801,22 +801,18 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { let (kind, has_default) = match &i.kind { AssocItemKind::Static(_, _, default) // Let's pretend this is a `const` for recovery. - | AssocItemKind::Const(_, default) => { + | AssocItemKind::Const(_, _, default) => { (hir::AssocItemKind::Const, default.is_some()) } - AssocItemKind::TyAlias(_, _, default) => (hir::AssocItemKind::Type, default.is_some()), - AssocItemKind::Fn(sig, _, default) => { + 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()) } AssocItemKind::Macro(..) => unimplemented!(), }; - hir::TraitItemRef { - id: hir::TraitItemId { hir_id: self.lower_node_id(i.id) }, - ident: i.ident, - span: i.span, - defaultness: self.lower_defaultness(Defaultness::Default, has_default), - kind, - } + let id = hir::TraitItemId { hir_id: self.lower_node_id(i.id) }; + let defaultness = hir::Defaultness::Default { has_value: has_default }; + hir::TraitItemRef { id, ident: i.ident, span: i.span, defaultness, kind } } /// Construct `ExprKind::Err` for the given `span`. @@ -827,15 +823,15 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> { let impl_item_def_id = self.resolver.definitions().local_def_id(i.id); - let (generics, kind) = match i.kind { - AssocItemKind::Static(ref ty, _, ref expr) | AssocItemKind::Const(ref ty, ref expr) => { + let (generics, kind) = match &i.kind { + AssocItemKind::Static(ty, _, expr) | AssocItemKind::Const(_, ty, expr) => { let ty = self.lower_ty(ty, ImplTraitContext::disallowed()); ( hir::Generics::empty(), hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())), ) } - AssocItemKind::Fn(ref sig, ref generics, ref body) => { + AssocItemKind::Fn(_, sig, generics, body) => { self.current_item = Some(i.span); let asyncness = sig.header.asyncness; let body_id = @@ -851,7 +847,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (generics, hir::ImplItemKind::Method(sig, body_id)) } - AssocItemKind::TyAlias(ref generics, _, ref ty) => { + AssocItemKind::TyAlias(_, generics, _, ty) => { let generics = self.lower_generics(generics, ImplTraitContext::disallowed()); let kind = match ty { None => { @@ -880,7 +876,7 @@ impl<'hir> LoweringContext<'_, 'hir> { attrs: self.lower_attrs(&i.attrs), generics, vis: self.lower_visibility(&i.vis, None), - defaultness: self.lower_defaultness(i.defaultness, true /* [1] */), + defaultness: self.lower_defaultness(i.kind.defaultness(), true /* [1] */), kind, span: i.span, } @@ -894,17 +890,17 @@ impl<'hir> LoweringContext<'_, 'hir> { ident: i.ident, span: i.span, vis: self.lower_visibility(&i.vis, Some(i.id)), - defaultness: self.lower_defaultness(i.defaultness, true /* [1] */), + defaultness: self.lower_defaultness(i.kind.defaultness(), true /* [1] */), kind: match &i.kind { AssocItemKind::Static(..) // Let's pretend this is a `const` for recovery. | AssocItemKind::Const(..) => hir::AssocItemKind::Const, - AssocItemKind::TyAlias(_, _, ty) => { + AssocItemKind::TyAlias(.., ty) => { match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { None => hir::AssocItemKind::Type, Some(_) => hir::AssocItemKind::OpaqueTy, } } - AssocItemKind::Fn(sig, _, _) => { + AssocItemKind::Fn(_, sig, ..) => { hir::AssocItemKind::Method { has_self: sig.decl.has_self() } } AssocItemKind::Macro(..) => unimplemented!(), @@ -948,7 +944,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_defaultness(&self, d: Defaultness, has_value: bool) -> hir::Defaultness { match d { - Defaultness::Default => hir::Defaultness::Default { has_value: has_value }, + Defaultness::Default(_) => hir::Defaultness::Default { has_value }, Defaultness::Final => { assert!(has_value); hir::Defaultness::Final diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 9bb46009fe64b..8bf9311bfc798 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -462,7 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) | ItemKind::Enum(_, ref generics) - | ItemKind::TyAlias(ref generics, ..) + | ItemKind::TyAlias(_, ref generics, ..) | ItemKind::Trait(_, _, ref generics, ..) => { let def_id = self.lctx.resolver.definitions().local_def_id(item.id); let count = generics @@ -490,7 +490,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lctx.allocate_hir_id_counter(item.id); let owner = match (&item.kind, ctxt) { // Ignore patterns in trait methods without bodies. - (AssocItemKind::Fn(_, _, None), AssocCtxt::Trait) => None, + (AssocItemKind::Fn(_, _, _, None), AssocCtxt::Trait) => None, _ => Some(item.id), }; self.with_hir_id_owner(owner, |this| visit::walk_assoc_item(this, item, ctxt)); diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index a9844a7059e55..44fed6dee6628 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -400,9 +400,11 @@ impl<'a> AstValidator<'a> { } fn check_defaultness(&self, span: Span, defaultness: Defaultness) { - if let Defaultness::Default = defaultness { + if let Defaultness::Default(def_span) = defaultness { + let span = self.session.source_map().def_span(span); self.err_handler() .struct_span_err(span, "`default` is only allowed on items in `impl` definitions") + .span_label(def_span, "`default` because of this") .emit(); } } @@ -863,10 +865,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if polarity == ImplPolarity::Negative { self.err_handler().span_err(item.span, "inherent impls cannot be negative"); } - if defaultness == Defaultness::Default { + if let Defaultness::Default(def_span) = defaultness { + let span = self.session.source_map().def_span(item.span); self.err_handler() - .struct_span_err(item.span, "inherent impls cannot be default") - .note("only trait implementations may be annotated with default") + .struct_span_err(span, "inherent impls cannot be `default`") + .span_label(def_span, "`default` because of this") + .note("only trait implementations may be annotated with `default`") .emit(); } if let Const::Yes(span) = constness { @@ -877,7 +881,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .emit(); } } - ItemKind::Fn(ref sig, ref generics, ref body) => { + ItemKind::Fn(def, ref sig, ref generics, ref body) => { + self.check_defaultness(item.span, def); self.check_const_fn_const_generic(item.span, sig, generics); if body.is_none() { @@ -961,7 +966,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.err_handler().span_err(item.span, "unions cannot have zero fields"); } } - ItemKind::Const(.., None) => { + ItemKind::Const(def, .., None) => { + self.check_defaultness(item.span, def); let msg = "free constant item without body"; self.error_item_without_body(item.span, "constant", msg, " = ;"); } @@ -969,7 +975,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { let msg = "free static item without body"; self.error_item_without_body(item.span, "static", msg, " = ;"); } - ItemKind::TyAlias(_, ref bounds, ref body) => { + ItemKind::TyAlias(def, _, ref bounds, ref body) => { + self.check_defaultness(item.span, def); if body.is_none() { let msg = "free type alias without body"; self.error_item_without_body(item.span, "type", msg, " = ;"); @@ -984,11 +991,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { match &fi.kind { - ForeignItemKind::Fn(sig, _, body) => { + ForeignItemKind::Fn(def, sig, _, body) => { + self.check_defaultness(fi.span, *def); self.check_foreign_fn_bodyless(fi.ident, body.as_deref()); self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header); } - ForeignItemKind::TyAlias(generics, bounds, body) => { + ForeignItemKind::TyAlias(def, generics, bounds, body) => { + self.check_defaultness(fi.span, *def); self.check_foreign_kind_bodyless(fi.ident, "type", body.as_ref().map(|b| b.span)); self.check_type_no_bounds(bounds, "`extern` blocks"); self.check_foreign_ty_genericless(generics); @@ -1229,19 +1238,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { - if ctxt == AssocCtxt::Trait { - self.check_defaultness(item.span, item.defaultness); + if ctxt == AssocCtxt::Trait || !self.in_trait_impl { + self.check_defaultness(item.span, item.kind.defaultness()); } if ctxt == AssocCtxt::Impl { match &item.kind { - AssocItemKind::Const(_, body) => { + AssocItemKind::Const(_, _, body) => { self.check_impl_item_provided(item.span, body, "constant", " = ;"); } - AssocItemKind::Fn(_, _, body) => { + AssocItemKind::Fn(_, _, _, body) => { self.check_impl_item_provided(item.span, body, "function", " { }"); } - AssocItemKind::TyAlias(_, bounds, body) => { + AssocItemKind::TyAlias(_, _, bounds, body) => { self.check_impl_item_provided(item.span, body, "type", " = ;"); self.check_type_no_bounds(bounds, "`impl`s"); } @@ -1251,7 +1260,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if ctxt == AssocCtxt::Trait || self.in_trait_impl { self.invalid_visibility(&item.vis, None); - if let AssocItemKind::Fn(sig, _, _) = &item.kind { + if let AssocItemKind::Fn(_, sig, _, _) = &item.kind { self.check_trait_fn_not_const(sig.header.constness); self.check_trait_fn_not_async(item.span, sig.header.asyncness); } diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 5bddae0d49e7d..33ff0bc451b32 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -349,7 +349,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ); } - if let ast::Defaultness::Default = defaultness { + if let ast::Defaultness::Default(_) = defaultness { gate_feature_post!(&self, specialization, i.span, "specialization is unstable"); } } @@ -372,7 +372,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, decl_macro, i.span, msg); } - ast::ItemKind::TyAlias(_, _, Some(ref ty)) => self.check_impl_trait(&ty), + ast::ItemKind::TyAlias(_, _, _, Some(ref ty)) => self.check_impl_trait(&ty), _ => {} } @@ -543,17 +543,17 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { - if i.defaultness == ast::Defaultness::Default { + if let ast::Defaultness::Default(_) = i.kind.defaultness() { gate_feature_post!(&self, specialization, i.span, "specialization is unstable"); } match i.kind { - ast::AssocItemKind::Fn(ref sig, _, _) => { + ast::AssocItemKind::Fn(_, ref sig, _, _) => { if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) { gate_feature_post!(&self, const_fn, i.span, "const fn is unstable"); } } - ast::AssocItemKind::TyAlias(ref generics, _, ref ty) => { + ast::AssocItemKind::TyAlias(_, ref generics, _, ref ty) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate_feature_post!( &self, diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 548ae6e7e63c4..2b223d92ff198 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -1016,8 +1016,8 @@ impl<'a> State<'a> { } crate fn print_foreign_item(&mut self, item: &ast::ForeignItem) { - let ast::ForeignItem { id, span, ident, attrs, kind, vis, tokens: _ } = item; - self.print_nested_item_kind(*id, *span, *ident, attrs, ast::Defaultness::Final, kind, vis); + let ast::Item { id, span, ident, attrs, kind, vis, tokens: _ } = item; + self.print_nested_item_kind(*id, *span, *ident, attrs, kind, vis); } fn print_nested_item_kind( @@ -1026,7 +1026,6 @@ impl<'a> State<'a> { span: Span, ident: ast::Ident, attrs: &[Attribute], - def: ast::Defaultness, kind: &ast::AssocItemKind, vis: &ast::Visibility, ) { @@ -1035,17 +1034,18 @@ impl<'a> State<'a> { self.maybe_print_comment(span.lo()); self.print_outer_attributes(attrs); match kind { - ast::ForeignItemKind::Fn(sig, gen, body) => { - self.print_fn_full(sig, ident, gen, vis, def, body.as_deref(), attrs); + ast::ForeignItemKind::Fn(def, sig, gen, body) => { + self.print_fn_full(sig, ident, gen, vis, *def, body.as_deref(), attrs); } - ast::ForeignItemKind::Const(ty, body) => { - self.print_item_const(ident, None, ty, body.as_deref(), vis, def); + ast::ForeignItemKind::Const(def, ty, body) => { + self.print_item_const(ident, None, ty, body.as_deref(), vis, *def); } ast::ForeignItemKind::Static(ty, mutbl, body) => { + let def = ast::Defaultness::Final; self.print_item_const(ident, Some(*mutbl), ty, body.as_deref(), vis, def); } - ast::ForeignItemKind::TyAlias(generics, bounds, ty) => { - self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, def); + ast::ForeignItemKind::TyAlias(def, generics, bounds, ty) => { + self.print_associated_type(ident, generics, bounds, ty.as_deref(), vis, *def); } ast::ForeignItemKind::Macro(m) => { self.print_mac(m); @@ -1146,12 +1146,10 @@ impl<'a> State<'a> { let def = ast::Defaultness::Final; self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def); } - ast::ItemKind::Const(ref ty, ref body) => { - let def = ast::Defaultness::Final; + ast::ItemKind::Const(def, ref ty, ref body) => { self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def); } - ast::ItemKind::Fn(ref sig, ref gen, ref body) => { - let def = ast::Defaultness::Final; + ast::ItemKind::Fn(def, ref sig, ref gen, ref body) => { let body = body.as_deref(); self.print_fn_full(sig, item.ident, gen, &item.vis, def, body, &item.attrs); } @@ -1185,8 +1183,7 @@ impl<'a> State<'a> { self.s.word(ga.asm.to_string()); self.end(); } - ast::ItemKind::TyAlias(ref generics, ref bounds, ref ty) => { - let def = ast::Defaultness::Final; + ast::ItemKind::TyAlias(def, ref generics, ref bounds, ref ty) => { let ty = ty.as_deref(); self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def); } @@ -1389,7 +1386,7 @@ impl<'a> State<'a> { } crate fn print_defaultness(&mut self, defaultness: ast::Defaultness) { - if let ast::Defaultness::Default = defaultness { + if let ast::Defaultness::Default(_) = defaultness { self.word_nbsp("default"); } } @@ -1461,8 +1458,8 @@ impl<'a> State<'a> { } crate fn print_assoc_item(&mut self, item: &ast::AssocItem) { - let ast::AssocItem { id, span, ident, attrs, defaultness, kind, vis, tokens: _ } = item; - self.print_nested_item_kind(*id, *span, *ident, attrs, *defaultness, kind, vis); + let ast::Item { id, span, ident, attrs, kind, vis, tokens: _ } = item; + self.print_nested_item_kind(*id, *span, *ident, attrs, kind, vis); } crate fn print_stmt(&mut self, st: &ast::Stmt) { diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 294b7463916b8..00ed05608b50b 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -542,9 +542,9 @@ impl<'a> TraitDef<'a> { span: self.span, ident, vis: respan(self.span.shrink_to_lo(), ast::VisibilityKind::Inherited), - defaultness: ast::Defaultness::Final, attrs: Vec::new(), kind: ast::AssocItemKind::TyAlias( + ast::Defaultness::Final, Generics::default(), Vec::new(), Some(type_def.to_ty(cx, self.span, type_ident, generics)), @@ -968,6 +968,7 @@ impl<'a> MethodDef<'a> { header: ast::FnHeader { unsafety, ext: ast::Extern::None, ..ast::FnHeader::default() }, decl: fn_decl, }; + let def = ast::Defaultness::Final; // Create the method. P(ast::AssocItem { @@ -975,9 +976,8 @@ impl<'a> MethodDef<'a> { attrs: self.attributes.clone(), span: trait_.span, vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited), - defaultness: ast::Defaultness::Final, ident: method_ident, - kind: ast::AssocItemKind::Fn(sig, fn_generics, Some(body_block)), + kind: ast::AssocItemKind::Fn(def, sig, fn_generics, Some(body_block)), tokens: None, }) } diff --git a/src/librustc_builtin_macros/global_allocator.rs b/src/librustc_builtin_macros/global_allocator.rs index 3ffb1d2206a5e..5a0b1a6b88542 100644 --- a/src/librustc_builtin_macros/global_allocator.rs +++ b/src/librustc_builtin_macros/global_allocator.rs @@ -66,7 +66,8 @@ impl AllocFnFactory<'_, '_> { let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty)); let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() }; let sig = FnSig { decl, header }; - let kind = ItemKind::Fn(sig, Generics::default(), Some(self.cx.block_expr(output_expr))); + let block = Some(self.cx.block_expr(output_expr)); + let kind = ItemKind::Fn(ast::Defaultness::Final, sig, Generics::default(), block); let item = self.cx.item( self.span, self.cx.ident_of(&self.kind.fn_name(method.name), self.span), diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index e15405e1f0dfc..8407352f57714 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -184,6 +184,7 @@ pub fn expand_test_or_bench( ], // const $ident: test::TestDescAndFn = ast::ItemKind::Const( + ast::Defaultness::Final, cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), // test::TestDescAndFn { Some( @@ -378,7 +379,7 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType { fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); let ref sd = cx.parse_sess.span_diagnostic; - if let ast::ItemKind::Fn(ref sig, ref generics, _) = i.kind { + if let ast::ItemKind::Fn(_, ref sig, ref generics, _) = i.kind { if let ast::Unsafe::Yes(span) = sig.header.unsafety { sd.struct_span_err(i.span, "unsafe functions cannot be used for tests") .span_label(span, "`unsafe` because of this") @@ -427,7 +428,7 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { } fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { - let has_sig = if let ast::ItemKind::Fn(ref sig, _, _) = i.kind { + let has_sig = if let ast::ItemKind::Fn(_, ref sig, _, _) = i.kind { // N.B., inadequate check, but we're running // well before resolve, can't get too deep. sig.decl.inputs.len() == 1 diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs index f0ea256cf2bf3..4bbab0d257489 100644 --- a/src/librustc_builtin_macros/test_harness.rs +++ b/src/librustc_builtin_macros/test_harness.rs @@ -170,22 +170,13 @@ impl MutVisitor for EntryPointCleaner { )); let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]); let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item); + let attrs = attrs + .into_iter() + .filter(|attr| !attr.check_name(sym::main) && !attr.check_name(sym::start)) + .chain(iter::once(allow_dead_code)) + .collect(); - ast::Item { - id, - ident, - attrs: attrs - .into_iter() - .filter(|attr| { - !attr.check_name(sym::main) && !attr.check_name(sym::start) - }) - .chain(iter::once(allow_dead_code)) - .collect(), - kind, - vis, - span, - tokens, - } + ast::Item { id, ident, attrs, kind, vis, span, tokens } }), EntryPointType::None | EntryPointType::OtherMain => item, }; @@ -307,7 +298,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty)); let sig = ast::FnSig { decl, header: ast::FnHeader::default() }; - let main = ast::ItemKind::Fn(sig, ast::Generics::default(), Some(main_body)); + let def = ast::Defaultness::Final; + let main = ast::ItemKind::Fn(def, sig, ast::Generics::default(), Some(main_body)); // Honor the reexport_test_harness_main attribute let main_id = match cx.reexport_test_harness_main { diff --git a/src/librustc_expand/build.rs b/src/librustc_expand/build.rs index 8a53e1d1861aa..bd6823cd4e275 100644 --- a/src/librustc_expand/build.rs +++ b/src/librustc_expand/build.rs @@ -644,7 +644,8 @@ impl<'a> ExtCtxt<'a> { ty: P, expr: P, ) -> P { - self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, Some(expr))) + let def = ast::Defaultness::Final; + self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr))) } pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 5d0c474140f16..bbea066b048d2 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -377,8 +377,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.span_err( span, &format!( - "expected crate top-level item to be a module after macro expansion, found a {}", - kind.descriptive_variant() + "expected crate top-level item to be a module after macro expansion, found {} {}", + kind.article(), kind.descr() ), ); } @@ -864,22 +864,22 @@ pub fn parse_ast_fragment<'a>( } AstFragmentKind::TraitItems => { let mut items = SmallVec::new(); - while this.token != token::Eof { - items.push(this.parse_trait_item(&mut false)?); + while let Some(item) = this.parse_trait_item()? { + items.extend(item); } AstFragment::TraitItems(items) } AstFragmentKind::ImplItems => { let mut items = SmallVec::new(); - while this.token != token::Eof { - items.push(this.parse_impl_item(&mut false)?); + while let Some(item) = this.parse_impl_item()? { + items.extend(item); } AstFragment::ImplItems(items) } AstFragmentKind::ForeignItems => { let mut items = SmallVec::new(); - while this.token != token::Eof { - items.push(this.parse_foreign_item(&mut false)?); + while let Some(item) = this.parse_foreign_item()? { + items.extend(item); } AstFragment::ForeignItems(items) } diff --git a/src/librustc_expand/placeholders.rs b/src/librustc_expand/placeholders.rs index c96b394c7b5e2..c323af4336a4c 100644 --- a/src/librustc_expand/placeholders.rs +++ b/src/librustc_expand/placeholders.rs @@ -57,7 +57,6 @@ pub fn placeholder( vis, attrs, kind: ast::AssocItemKind::Macro(mac_placeholder()), - defaultness: ast::Defaultness::Final, tokens: None, })]), AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![P(ast::AssocItem { @@ -67,7 +66,6 @@ pub fn placeholder( vis, attrs, kind: ast::AssocItemKind::Macro(mac_placeholder()), - defaultness: ast::Defaultness::Final, tokens: None, })]), AstFragmentKind::ForeignItems => { diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 8496a6ed23b8c..6d2f5ba6baf14 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2500,16 +2500,16 @@ pub enum ItemKind<'hir> { } impl ItemKind<'_> { - pub fn descriptive_variant(&self) -> &str { + pub fn descr(&self) -> &str { match *self { ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "use", + ItemKind::Use(..) => "`use` import", ItemKind::Static(..) => "static item", ItemKind::Const(..) => "constant item", ItemKind::Fn(..) => "function", ItemKind::Mod(..) => "module", - ItemKind::ForeignMod(..) => "foreign module", - ItemKind::GlobalAsm(..) => "global asm", + ItemKind::ForeignMod(..) => "extern block", + ItemKind::GlobalAsm(..) => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::OpaqueTy(..) => "opaque type", ItemKind::Enum(..) => "enum", @@ -2517,7 +2517,7 @@ impl ItemKind<'_> { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl { .. } => "impl", + ItemKind::Impl { .. } => "implementation", } } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 99e9878bfd8bb..c73f7aafb4860 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -677,7 +677,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { let is_const = match i { ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, - ast::ItemKind::Fn(ref sig, _, _) => Self::is_sig_const(sig), + ast::ItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig), _ => false, }; self.run(is_const, |s| noop_visit_item_kind(i, s)) @@ -686,7 +686,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> { let is_const = match i.kind { ast::AssocItemKind::Const(..) => true, - ast::AssocItemKind::Fn(ref sig, _, _) => Self::is_sig_const(sig), + ast::AssocItemKind::Fn(_, ref sig, _, _) => Self::is_sig_const(sig), _ => false, }; self.run(is_const, |s| noop_flat_map_assoc_item(i, s)) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5c601803a77a2..ca3727d175563 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -640,7 +640,7 @@ declare_lint_pass!( impl EarlyLintPass for AnonymousParameters { fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) { match it.kind { - ast::AssocItemKind::Fn(ref sig, _, _) => { + ast::AssocItemKind::Fn(_, ref sig, _, _) => { for arg in sig.decl.inputs.iter() { match arg.pat.kind { ast::PatKind::Ident(_, ident, None) => { diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 328cf11c53247..d6da627054196 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -5,12 +5,12 @@ use super::{FollowedByType, Parser, PathStyle}; use crate::maybe_whole; use rustc_ast_pretty::pprust; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult, StashKey}; +use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; use rustc_span::source_map::{self, Span}; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast::{self, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID}; -use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind}; -use syntax::ast::{Async, Const, Defaultness, IsAuto, PathSegment, Unsafe}; +use syntax::ast::{AssocItem, AssocItemKind, ForeignItemKind, Item, ItemKind}; +use syntax::ast::{Async, Const, Defaultness, IsAuto, PathSegment, Unsafe, UseTree, UseTreeKind}; use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, Param, SelfKind}; use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; use syntax::ast::{FnHeader, ForeignItem, Mutability, Visibility, VisibilityKind}; @@ -25,19 +25,31 @@ pub(super) type ItemInfo = (Ident, ItemKind); impl<'a> Parser<'a> { pub fn parse_item(&mut self) -> PResult<'a, Option>> { + self.parse_item_(|_| true).map(|i| i.map(P)) + } + + fn parse_item_(&mut self, req_name: ReqName) -> PResult<'a, Option> { let attrs = self.parse_outer_attributes()?; - self.parse_item_(attrs, true, false) + self.parse_item_common(attrs, true, false, req_name) } - pub(super) fn parse_item_( + pub(super) fn parse_item_common( &mut self, - attrs: Vec, - macros_allowed: bool, - attributes_allowed: bool, - ) -> PResult<'a, Option>> { + mut attrs: Vec, + mac_allowed: bool, + attrs_allowed: bool, + req_name: ReqName, + ) -> PResult<'a, Option> { + maybe_whole!(self, NtItem, |item| { + let mut item = item; + mem::swap(&mut item.attrs, &mut attrs); + item.attrs.extend(attrs); + Some(item.into_inner()) + }); + let mut unclosed_delims = vec![]; - let (ret, tokens) = self.collect_tokens(|this| { - let item = this.parse_item_implementation(attrs, macros_allowed, attributes_allowed); + let (mut item, tokens) = self.collect_tokens(|this| { + let item = this.parse_item_common_(attrs, mac_allowed, attrs_allowed, req_name); unclosed_delims.append(&mut this.unclosed_delims); item })?; @@ -57,52 +69,74 @@ impl<'a> Parser<'a> { // it (bad!). To work around this case for now we just avoid recording // `tokens` if we detect any inner attributes. This should help keep // expansion correct, but we should fix this bug one day! - Ok(ret.map(|item| { - item.map(|mut i| { - if !i.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) { - i.tokens = Some(tokens); - } - i - }) - })) + if let Some(item) = &mut item { + if !item.attrs.iter().any(|attr| attr.style == AttrStyle::Inner) { + item.tokens = Some(tokens); + } + } + Ok(item) } - /// Parses one of the items allowed by the flags. - fn parse_item_implementation( + fn parse_item_common_( &mut self, mut attrs: Vec, - macros_allowed: bool, - attributes_allowed: bool, - ) -> PResult<'a, Option>> { - maybe_whole!(self, NtItem, |item| { - let mut item = item; - mem::swap(&mut item.attrs, &mut attrs); - item.attrs.extend(attrs); - Some(item) - }); - + mac_allowed: bool, + attrs_allowed: bool, + req_name: ReqName, + ) -> PResult<'a, Option> { let lo = self.token.span; let vis = self.parse_visibility(FollowedByType::No)?; + let mut def = self.parse_defaultness(); + let kind = self.parse_item_kind(&mut attrs, mac_allowed, lo, &vis, &mut def, req_name)?; + if let Some((ident, kind)) = kind { + self.error_on_unconsumed_default(def, &kind); + let span = lo.to(self.prev_span); + let id = DUMMY_NODE_ID; + let item = Item { ident, attrs, id, kind, vis, span, tokens: None }; + return Ok(Some(item)); + } - if let Some((ident, kind)) = self.parse_item_kind(&mut attrs, macros_allowed, lo, &vis)? { - return Ok(Some(P(self.mk_item(lo, ident, kind, vis, attrs)))); + // At this point, we have failed to parse an item. + self.error_on_unmatched_vis(&vis); + self.error_on_unmatched_defaultness(def); + if !attrs_allowed { + self.recover_attrs_no_item(&attrs)?; } + Ok(None) + } - // FAILURE TO PARSE ITEM + /// Error in-case a non-inherited visibility was parsed but no item followed. + fn error_on_unmatched_vis(&self, vis: &Visibility) { if let VisibilityKind::Inherited = vis.node { - } else { - let vs = pprust::vis_to_string(&vis); - let vs = vs.trim_end(); - self.struct_span_err(vis.span, &format!("unmatched visibility `{}`", vs)) - .span_label(vis.span, "the unmatched visibility") - .help(&format!("you likely meant to define an item, e.g., `{} fn foo() {{}}`", vs)) + return; + } + let vs = pprust::vis_to_string(&vis); + let vs = vs.trim_end(); + self.struct_span_err(vis.span, &format!("visibility `{}` is not followed by an item", vs)) + .span_label(vis.span, "the visibility") + .help(&format!("you likely meant to define an item, e.g., `{} fn foo() {{}}`", vs)) + .emit(); + } + + /// Error in-case a `default` was parsed but no item followed. + fn error_on_unmatched_defaultness(&self, def: Defaultness) { + if let Defaultness::Default(sp) = def { + self.struct_span_err(sp, "`default` is not followed by an item") + .span_label(sp, "the `default` qualifier") + .note("only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`") .emit(); } + } - if !attributes_allowed { - self.recover_attrs_no_item(&attrs)?; + /// Error in-case `default` was parsed in an in-appropriate context. + fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) { + if let Defaultness::Default(span) = def { + let msg = format!("{} {} cannot be `default`", kind.article(), kind.descr()); + self.struct_span_err(span, &msg) + .span_label(span, "`default` because of this") + .note("only associated `fn`, `const`, and `type` items can be `default`") + .emit(); } - Ok(None) } /// Parses one of the items allowed by the flags. @@ -112,7 +146,11 @@ impl<'a> Parser<'a> { macros_allowed: bool, lo: Span, vis: &Visibility, + def: &mut Defaultness, + req_name: ReqName, ) -> PResult<'a, Option> { + let mut def = || mem::replace(def, Defaultness::Final); + let info = if self.eat_keyword(kw::Use) { // USE ITEM let tree = self.parse_use_tree()?; @@ -120,8 +158,8 @@ impl<'a> Parser<'a> { (Ident::invalid(), ItemKind::Use(P(tree))) } else if self.check_fn_front_matter() { // FUNCTION ITEM - let (ident, sig, generics, body) = self.parse_fn(&mut false, attrs, |_| true)?; - (ident, ItemKind::Fn(sig, generics, body)) + let (ident, sig, generics, body) = self.parse_fn(attrs, req_name)?; + (ident, ItemKind::Fn(def(), sig, generics, body)) } else if self.eat_keyword(kw::Extern) { if self.eat_keyword(kw::Crate) { // EXTERN CRATE @@ -134,29 +172,27 @@ impl<'a> Parser<'a> { // STATIC ITEM self.bump(); // `static` let m = self.parse_mutability(); - self.parse_item_const(Some(m))? + let (ident, ty, expr) = self.parse_item_global(Some(m))?; + (ident, ItemKind::Static(ty, m, expr)) } else if let Const::Yes(const_span) = self.parse_constness() { // CONST ITEM self.recover_const_mut(const_span); - self.parse_item_const(None)? + let (ident, ty, expr) = self.parse_item_global(None)?; + (ident, ItemKind::Const(def(), ty, expr)) } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() { // TRAIT ITEM self.parse_item_trait(attrs, lo)? } else if self.check_keyword(kw::Impl) || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Impl]) - || self.check_keyword(kw::Default) && self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe]) { // IMPL ITEM - let defaultness = self.parse_defaultness(); - let unsafety = self.parse_unsafety(); - self.expect_keyword(kw::Impl)?; - self.parse_item_impl(attrs, unsafety, defaultness)? + self.parse_item_impl(attrs, def())? } else if self.eat_keyword(kw::Mod) { // MODULE ITEM self.parse_item_mod(attrs)? } else if self.eat_keyword(kw::Type) { // TYPE ITEM - self.parse_type_alias()? + self.parse_type_alias(def())? } else if self.eat_keyword(kw::Enum) { // ENUM ITEM self.parse_item_enum()? @@ -332,24 +368,7 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn]) } - /// Given this code `path(`, it seems like this is not - /// setting the visibility of a macro invocation, - /// but rather a mistyped method declaration. - /// Create a diagnostic pointing out that `fn` is missing. - /// - /// ``` - /// x | pub path(&self) { - /// | ^ missing `fn`, `type`, `const`, or `static` - /// ``` - fn missing_nested_item_kind_err(&self, prev_span: Span) -> DiagnosticBuilder<'a> { - let sp = prev_span.between(self.token.span); - let expected_kinds = "missing `fn`, `type`, `const`, or `static`"; - let mut err = self.struct_span_err(sp, &format!("{} for item declaration", expected_kinds)); - err.span_label(sp, expected_kinds); - err - } - - /// Parses an implementation item, `impl` keyword is already parsed. + /// Parses an implementation item. /// /// ``` /// impl<'a, T> TYPE { /* impl items */ } @@ -366,9 +385,11 @@ impl<'a> Parser<'a> { fn parse_item_impl( &mut self, attrs: &mut Vec, - unsafety: Unsafe, defaultness: Defaultness, ) -> PResult<'a, ItemInfo> { + let unsafety = self.parse_unsafety(); + self.expect_keyword(kw::Impl)?; + // First, parse generic parameters if necessary. let mut generics = if self.choose_generics_over_qpath() { self.parse_generics()? @@ -420,7 +441,7 @@ impl<'a> Parser<'a> { generics.where_clause = self.parse_where_clause()?; - let impl_items = self.parse_item_list(attrs, |p, at_end| p.parse_impl_item(at_end))?; + let impl_items = self.parse_item_list(attrs, |p| p.parse_impl_item())?; let item_kind = match ty_second { Some(ty_second) => { @@ -479,8 +500,9 @@ impl<'a> Parser<'a> { fn parse_item_list( &mut self, attrs: &mut Vec, - mut parse_item: impl FnMut(&mut Parser<'a>, &mut bool) -> PResult<'a, T>, + mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option>>, ) -> PResult<'a, Vec> { + let open_brace_span = self.token.span; self.expect(&token::OpenDelim(token::Brace))?; attrs.append(&mut self.parse_inner_attributes()?); @@ -489,15 +511,25 @@ impl<'a> Parser<'a> { if self.recover_doc_comment_before_brace() { continue; } - let mut at_end = false; - match parse_item(self, &mut at_end) { - Ok(item) => items.push(item), + match parse_item(self) { + Ok(None) => { + // We have to bail or we'll potentially never make progress. + let non_item_span = self.token.span; + self.consume_block(token::Brace, ConsumeClosingDelim::Yes); + self.struct_span_err(non_item_span, "non-item in item list") + .span_label(open_brace_span, "item list starts here") + .span_label(non_item_span, "non-item starts here") + .span_label(self.prev_span, "item list ends here") + .emit(); + break; + } + Ok(Some(item)) => items.extend(item), Err(mut err) => { - err.emit(); - if !at_end { - self.consume_block(token::Brace, ConsumeClosingDelim::Yes); - break; - } + self.consume_block(token::Brace, ConsumeClosingDelim::Yes); + err.span_label(open_brace_span, "while parsing this item list starting here") + .span_label(self.prev_span, "the item list ends here") + .emit(); + break; } } } @@ -529,25 +561,14 @@ impl<'a> Parser<'a> { /// Parses defaultness (i.e., `default` or nothing). fn parse_defaultness(&mut self) -> Defaultness { - // `pub` is included for better error messages + // We are interested in `default` followed by another identifier. + // However, we must avoid keywords that occur as binary operators. + // Currently, the only applicable keyword is `as` (`default as Ty`). if self.check_keyword(kw::Default) - && self.is_keyword_ahead( - 1, - &[ - kw::Impl, - kw::Static, - kw::Const, - kw::Async, - kw::Fn, - kw::Unsafe, - kw::Extern, - kw::Type, - kw::Pub, - ], - ) + && self.look_ahead(1, |t| t.is_non_raw_ident_where(|i| i.name != kw::As)) { self.bump(); // `default` - Defaultness::Default + Defaultness::Default(self.prev_span) } else { Defaultness::Final } @@ -605,101 +626,41 @@ impl<'a> Parser<'a> { } else { // It's a normal trait. tps.where_clause = self.parse_where_clause()?; - let items = self.parse_item_list(attrs, |p, at_end| p.parse_trait_item(at_end))?; + let items = self.parse_item_list(attrs, |p| p.parse_trait_item())?; Ok((ident, ItemKind::Trait(is_auto, unsafety, tps, bounds, items))) } } - pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, P> { - maybe_whole!(self, NtImplItem, |x| x); - self.parse_assoc_item(at_end, |_| true) + pub fn parse_impl_item(&mut self) -> PResult<'a, Option>>> { + maybe_whole!(self, NtImplItem, |x| Some(Some(x))); + self.parse_assoc_item(|_| true) } - pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, P> { - maybe_whole!(self, NtTraitItem, |x| x); + pub fn parse_trait_item(&mut self) -> PResult<'a, Option>>> { + maybe_whole!(self, NtTraitItem, |x| Some(Some(x))); // This is somewhat dubious; We don't want to allow // param names to be left off if there is a definition... // // We don't allow param names to be left off in edition 2018. - self.parse_assoc_item(at_end, |t| t.span.rust_2018()) + self.parse_assoc_item(|t| t.span.rust_2018()) } /// Parses associated items. - fn parse_assoc_item( - &mut self, - at_end: &mut bool, - req_name: ReqName, - ) -> PResult<'a, P> { - let attrs = self.parse_outer_attributes()?; - let mut unclosed_delims = vec![]; - let (mut item, tokens) = self.collect_tokens(|this| { - let item = this.parse_assoc_item_(at_end, attrs, req_name); - unclosed_delims.append(&mut this.unclosed_delims); - item - })?; - self.unclosed_delims.append(&mut unclosed_delims); - // See `parse_item` for why this clause is here. - 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, - mut attrs: Vec, - req_name: ReqName, - ) -> PResult<'a, AssocItem> { - let lo = self.token.span; - let vis = self.parse_visibility(FollowedByType::No)?; - let defaultness = self.parse_defaultness(); - let (ident, kind) = self.parse_assoc_item_kind(at_end, &mut attrs, req_name, &vis)?; - let span = lo.to(self.prev_span); - let id = DUMMY_NODE_ID; - Ok(AssocItem { id, span, ident, attrs, vis, defaultness, kind, tokens: None }) - } - - fn parse_assoc_item_kind( - &mut self, - at_end: &mut bool, - attrs: &mut Vec, - req_name: ReqName, - vis: &Visibility, - ) -> PResult<'a, (Ident, AssocItemKind)> { - if self.eat_keyword(kw::Type) { - match self.parse_type_alias()? { - (ident, ItemKind::TyAlias(a, b, c)) => Ok((ident, AssocItemKind::TyAlias(a, b, c))), - _ => unreachable!(), - } - } else if self.check_fn_front_matter() { - let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?; - Ok((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))?; - Ok((ident, AssocItemKind::Static(ty, mutbl, expr))) - } else if self.eat_keyword(kw::Const) { - let (ident, ty, expr) = self.parse_item_const_common(None)?; - Ok((ident, AssocItemKind::Const(ty, expr))) - } else if self.isnt_macro_invocation() { - Err(self.missing_nested_item_kind_err(self.prev_span)) - } else if self.token.is_path_start() { - let mac = self.parse_item_macro(&vis)?; - *at_end = true; - Ok((Ident::invalid(), AssocItemKind::Macro(mac))) - } else { - self.recover_attrs_no_item(attrs)?; - self.unexpected() - } + fn parse_assoc_item(&mut self, req_name: ReqName) -> PResult<'a, Option>>> { + Ok(self.parse_item_(req_name)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| { + let kind = match kind { + ItemKind::Mac(a) => AssocItemKind::Macro(a), + ItemKind::Fn(a, b, c, d) => AssocItemKind::Fn(a, b, c, d), + ItemKind::TyAlias(a, b, c, d) => AssocItemKind::TyAlias(a, b, c, d), + ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c), + ItemKind::Static(a, _, b) => { + self.struct_span_err(span, "associated `static` items are not allowed").emit(); + AssocItemKind::Const(Defaultness::Final, a, b) + } + _ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"), + }; + Some(P(Item { attrs, id, span, vis, ident, kind, tokens })) + })) } /// Parses a `type` alias with the following grammar: @@ -707,7 +668,7 @@ impl<'a> Parser<'a> { /// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ; /// ``` /// The `"type"` has already been eaten. - fn parse_type_alias(&mut self) -> PResult<'a, (Ident, ItemKind)> { + fn parse_type_alias(&mut self, def: Defaultness) -> PResult<'a, ItemInfo> { let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; @@ -719,7 +680,7 @@ impl<'a> Parser<'a> { let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None }; self.expect_semi()?; - Ok((ident, ItemKind::TyAlias(generics, bounds, default))) + Ok((ident, ItemKind::TyAlias(def, generics, bounds, default))) } /// Parses a `UseTree`. @@ -866,38 +827,48 @@ impl<'a> Parser<'a> { /// ``` fn parse_item_foreign_mod(&mut self, attrs: &mut Vec) -> PResult<'a, ItemInfo> { let abi = self.parse_abi(); // ABI? - let items = self.parse_item_list(attrs, |p, at_end| p.parse_foreign_item(at_end))?; + let items = self.parse_item_list(attrs, |p| p.parse_foreign_item())?; let module = ast::ForeignMod { abi, items }; Ok((Ident::invalid(), ItemKind::ForeignMod(module))) } /// Parses a foreign item (one in an `extern { ... }` block). - pub fn parse_foreign_item(&mut self, at_end: &mut bool) -> PResult<'a, P> { - maybe_whole!(self, NtForeignItem, |ni| ni); + pub fn parse_foreign_item(&mut self) -> PResult<'a, Option>>> { + maybe_whole!(self, NtForeignItem, |item| Some(Some(item))); + + Ok(self.parse_item_(|_| true)?.map(|Item { attrs, id, span, vis, ident, kind, tokens }| { + let kind = match kind { + ItemKind::Mac(a) => ForeignItemKind::Macro(a), + ItemKind::Fn(a, b, c, d) => ForeignItemKind::Fn(a, b, c, d), + ItemKind::TyAlias(a, b, c, d) => ForeignItemKind::TyAlias(a, b, c, d), + ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c), + ItemKind::Const(_, a, b) => { + self.error_on_foreign_const(span, ident); + ForeignItemKind::Static(a, Mutability::Not, b) + } + _ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"), + }; + Some(P(Item { attrs, id, span, vis, ident, kind, tokens })) + })) + } - let mut attrs = self.parse_outer_attributes()?; - 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)?; - let item = self.mk_item(lo, ident, kind, vis, attrs); - self.error_on_foreign_const(&item); - Ok(P(item)) + fn error_bad_item_kind(&self, span: Span, kind: &ItemKind, ctx: &str) -> Option { + let span = self.sess.source_map().def_span(span); + let msg = format!("{} is not supported in {}", kind.descr(), ctx); + self.struct_span_err(span, &msg).emit(); + return None; } - 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 error_on_foreign_const(&self, span: Span, ident: Ident) { + self.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, + ) + .note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html") + .emit(); } fn is_static_global(&mut self) -> bool { @@ -937,20 +908,7 @@ impl<'a> Parser<'a> { /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`. /// /// When `m` is `"const"`, `$ident` may also be `"_"`. - fn parse_item_const(&mut self, m: Option) -> PResult<'a, ItemInfo> { - let (id, ty, expr) = self.parse_item_const_common(m)?; - let item = match m { - Some(m) => ItemKind::Static(ty, m, expr), - None => ItemKind::Const(ty, expr), - }; - Ok((id, item)) - } - - /// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with - /// `["const" | ("static" "mut"?)]` already parsed and stored in `m`. - /// - /// When `m` is `"const"`, `$ident` may also be `"_"`. - fn parse_item_const_common( + fn parse_item_global( &mut self, m: Option, ) -> PResult<'a, (Ident, P, Option>)> { @@ -1426,18 +1384,6 @@ impl<'a> Parser<'a> { } Ok(true) } - - fn mk_item( - &self, - lo: Span, - ident: Ident, - kind: K, - vis: Visibility, - attrs: Vec, - ) -> Item { - let span = lo.to(self.prev_span); - Item { ident, attrs, id: DUMMY_NODE_ID, kind, vis, span, tokens: None } - } } /// The parsing configuration used to parse a parameter list (see `parse_fn_params`). @@ -1450,7 +1396,6 @@ impl<'a> Parser<'a> { /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`. fn parse_fn( &mut self, - at_end: &mut bool, attrs: &mut Vec, req_name: ReqName, ) -> PResult<'a, (Ident, FnSig, Generics, Option>)> { @@ -1459,18 +1404,14 @@ impl<'a> Parser<'a> { let mut generics = self.parse_generics()?; // `<'a, T, ...>` let decl = self.parse_fn_decl(req_name, AllowPlus::Yes)?; // `(p: u8, ...)` generics.where_clause = self.parse_where_clause()?; // `where T: Ord` - let body = self.parse_fn_body(at_end, attrs)?; // `;` or `{ ... }`. + let body = self.parse_fn_body(attrs)?; // `;` or `{ ... }`. Ok((ident, FnSig { header, decl }, generics, body)) } /// Parse the "body" of a function. /// This can either be `;` when there's no body, /// or e.g. a block when the function is a provided one. - fn parse_fn_body( - &mut self, - at_end: &mut bool, - attrs: &mut Vec, - ) -> PResult<'a, Option>> { + fn parse_fn_body(&mut self, attrs: &mut Vec) -> PResult<'a, Option>> { let (inner_attrs, body) = match self.token.kind { token::Semi => { self.bump(); @@ -1490,7 +1431,6 @@ impl<'a> Parser<'a> { _ => return self.expected_semi_or_open_brace(), }; attrs.extend(inner_attrs); - *at_end = true; Ok(body) } diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index 0ce0e0df66aa4..bbfbe9c20df94 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -81,11 +81,11 @@ impl<'a> Parser<'a> { // FIXME: Bad copy of attrs let old_directory_ownership = mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock); - let item = self.parse_item_(attrs.clone(), false, true)?; + let item = self.parse_item_common(attrs.clone(), false, true, |_| true)?; self.directory.ownership = old_directory_ownership; if let Some(item) = item { - return Ok(Some(self.mk_stmt(lo.to(item.span), StmtKind::Item(item)))); + return Ok(Some(self.mk_stmt(lo.to(item.span), StmtKind::Item(P(item))))); } // Do not attempt to parse an expression if we're done here. diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 25b8b8fcd444b..e0eef1db0f089 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -601,13 +601,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { hir::ItemKind::Struct(..) => "constructed", // Issue #52325 _ => "used", }; - self.warn_dead_code( - item.hir_id, - span, - item.ident.name, - item.kind.descriptive_variant(), - participle, - ); + self.warn_dead_code(item.hir_id, span, item.ident.name, item.kind.descr(), participle); } else { // Only continue if we didn't warn intravisit::walk_item(self, item); diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 0c7f64fefd0d2..99fbac4568e4f 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -362,7 +362,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // optional. They inherit stability from their parents when unannotated. hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {} - _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()), + _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descr()), } intravisit::walk_item(self, i) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 383bfe18fd00b..a81caea4e412a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -718,7 +718,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // These items live in the type namespace. - ItemKind::TyAlias(_, _, ref ty) => { + ItemKind::TyAlias(_, _, _, ref ty) => { let def_kind = match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) { None => DefKind::TyAlias, Some(_) => DefKind::OpaqueTy, @@ -1253,7 +1253,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { let (res, ns) = match item.kind { 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, _, _) => { + 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 60cba55512193..30089633689c4 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -117,7 +117,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), - ItemKind::Fn(sig, generics, body) if sig.header.asyncness.is_async() => { + ItemKind::Fn(_, sig, generics, body) if sig.header.asyncness.is_async() => { return self.visit_async_fn( i.id, i.ident.name, @@ -215,7 +215,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { let def_data = match &i.kind { - AssocItemKind::Fn(FnSig { header, decl }, generics, body) + AssocItemKind::Fn(_, FnSig { header, decl }, generics, body) if header.asyncness.is_async() => { return self.visit_async_fn( diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 74628e6e5a03e..5b5180a7e1a44 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -437,8 +437,8 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { match foreign_item.kind { - ForeignItemKind::Fn(_, ref generics, _) - | ForeignItemKind::TyAlias(ref generics, ..) => { + ForeignItemKind::Fn(_, _, ref generics, _) + | ForeignItemKind::TyAlias(_, ref generics, ..) => { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { visit::walk_foreign_item(this, foreign_item); }); @@ -797,7 +797,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { debug!("(resolving item) resolving {} ({:?})", name, item.kind); match item.kind { - ItemKind::TyAlias(ref generics, _, _) | ItemKind::Fn(_, ref generics, _) => { + ItemKind::TyAlias(_, ref generics, _, _) | ItemKind::Fn(_, _, ref generics, _) => { self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { visit::walk_item(this, item) }); @@ -837,7 +837,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_trait_items(trait_items, |this| { match &item.kind { AssocItemKind::Static(ty, _, default) - | AssocItemKind::Const(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. @@ -845,10 +845,10 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_constant_rib(|this| this.visit_expr(expr)); } } - AssocItemKind::Fn(_, generics, _) => { + AssocItemKind::Fn(_, _, generics, _) => { walk_assoc_item(this, generics, item); } - AssocItemKind::TyAlias(generics, _, _) => { + AssocItemKind::TyAlias(_, generics, _, _) => { walk_assoc_item(this, generics, item); } AssocItemKind::Macro(_) => { @@ -878,7 +878,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }); } - ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(ref ty, ref expr) => { + ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(_, ref ty, ref expr) => { debug!("resolve_item ItemKind::Const"); self.with_item_rib(HasGenericParams::No, |this| { this.visit_ty(ty); @@ -1015,7 +1015,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { trait_items .iter() .filter_map(|item| match &item.kind { - AssocItemKind::TyAlias(_, bounds, _) if bounds.len() == 0 => Some(item.ident), + AssocItemKind::TyAlias(_, _, bounds, _) if bounds.len() == 0 => { + Some(item.ident) + } _ => None, }) .collect(), @@ -1125,7 +1127,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { visit::walk_assoc_item(this, item, AssocCtxt::Impl) }); } - AssocItemKind::Fn(_, generics, _) => { + AssocItemKind::Fn(_, _, generics, _) => { // We also need a new scope for the impl item type parameters. this.with_generic_param_rib( generics, @@ -1148,7 +1150,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }, ); } - AssocItemKind::TyAlias(generics, _, _) => { + AssocItemKind::TyAlias(_, generics, _, _) => { // We also need a new scope for the impl item type parameters. this.with_generic_param_rib( generics, diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 442f3b695a26f..b3a8657d80bed 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1005,7 +1005,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { let vis_span = trait_item.span.shrink_to_lo(); match trait_item.kind { ast::AssocItemKind::Static(ref ty, _, ref expr) - | ast::AssocItemKind::Const(ref ty, ref expr) => { + | ast::AssocItemKind::Const(_, ref ty, ref expr) => { self.process_assoc_const( trait_item.id, trait_item.ident, @@ -1016,7 +1016,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { &trait_item.attrs, ); } - ast::AssocItemKind::Fn(ref sig, ref generics, ref body) => { + ast::AssocItemKind::Fn(_, ref sig, ref generics, ref body) => { self.process_method( sig, body.as_ref().map(|x| &**x), @@ -1027,7 +1027,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { trait_item.span, ); } - ast::AssocItemKind::TyAlias(_, ref bounds, ref default_ty) => { + ast::AssocItemKind::TyAlias(_, _, ref bounds, ref default_ty) => { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); let qualname = format!( @@ -1076,7 +1076,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.process_macro_use(impl_item.span); match impl_item.kind { ast::AssocItemKind::Static(ref ty, _, ref expr) - | ast::AssocItemKind::Const(ref ty, ref expr) => { + | ast::AssocItemKind::Const(_, ref ty, ref expr) => { self.process_assoc_const( impl_item.id, impl_item.ident, @@ -1087,7 +1087,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { &impl_item.attrs, ); } - ast::AssocItemKind::Fn(ref sig, ref generics, ref body) => { + ast::AssocItemKind::Fn(_, ref sig, ref generics, ref body) => { self.process_method( sig, body.as_deref(), @@ -1098,8 +1098,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { impl_item.span, ); } - ast::AssocItemKind::TyAlias(_, _, None) => {} - ast::AssocItemKind::TyAlias(_, _, Some(ref ty)) => { + ast::AssocItemKind::TyAlias(_, _, _, None) => {} + ast::AssocItemKind::TyAlias(_, _, _, Some(ref ty)) => { // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. @@ -1292,11 +1292,11 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { ); } } - Fn(ref sig, ref ty_params, ref body) => { + Fn(_, ref sig, ref ty_params, ref body) => { self.process_fn(item, &sig.decl, &sig.header, ty_params, body.as_deref()) } Static(ref typ, _, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()), - Const(ref typ, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()), + Const(_, ref typ, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()), Struct(ref def, ref ty_params) | Union(ref def, ref ty_params) => { self.process_struct(item, def, ty_params) } @@ -1311,7 +1311,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.process_mod(item); visit::walk_mod(self, m); } - TyAlias(ref ty_params, _, ref ty) => { + TyAlias(_, ref ty_params, _, ref ty) => { let qualname = format!( "::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)) @@ -1520,7 +1520,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { let access = access_from!(self.save_ctxt, item, hir_id); match item.kind { - ast::ForeignItemKind::Fn(ref sig, ref generics, _) => { + ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => { let decl = &sig.decl; if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(fn_data, DefData, item.span); @@ -1537,7 +1537,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.visit_ty(&ret_ty); } } - ast::ForeignItemKind::Const(ref ty, _) | ast::ForeignItemKind::Static(ref ty, _, _) => { + ast::ForeignItemKind::Const(_, ref ty, _) + | ast::ForeignItemKind::Static(ref ty, _, _) => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(var_data, DefData, item.span); self.dumper.dump_def(&access, var_data); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 43a0cfecd3ed0..b253559dd5cd5 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -133,7 +133,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)) ); match item.kind { - ast::ForeignItemKind::Fn(ref sig, ref generics, _) => { + ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => { filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { @@ -151,7 +151,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ForeignItemKind::Const(ref ty, _) | ast::ForeignItemKind::Static(ref ty, _, _) => { + ast::ForeignItemKind::Const(_, ref ty, _) + | ast::ForeignItemKind::Static(ref ty, _, _) => { filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); @@ -180,7 +181,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { pub fn get_item_data(&self, item: &ast::Item) -> Option { match item.kind { - ast::ItemKind::Fn(ref sig, .., ref generics, _) => { + ast::ItemKind::Fn(_, ref sig, .., ref generics, _) => { let qualname = format!( "::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)) @@ -227,7 +228,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Const(ref typ, _) => { + ast::ItemKind::Const(_, ref typ, _) => { let qualname = format!( "::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)) diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 2c07ed0571bde..9670fb1e2c465 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -345,7 +345,7 @@ impl Sig for ast::Item { Ok(extend_sig(ty, text, defs, vec![])) } - ast::ItemKind::Const(ref ty, ref expr) => { + ast::ItemKind::Const(_, ref ty, ref expr) => { let mut text = "const ".to_owned(); let name = self.ident.to_string(); let defs = vec![SigElement { @@ -369,7 +369,7 @@ impl Sig for ast::Item { Ok(extend_sig(ty, text, defs, vec![])) } - ast::ItemKind::Fn(ast::FnSig { ref decl, header }, ref generics, _) => { + ast::ItemKind::Fn(_, ast::FnSig { ref decl, header }, ref generics, _) => { let mut text = String::new(); if let ast::Const::Yes(_) = header.constness { text.push_str("const "); @@ -423,7 +423,7 @@ impl Sig for ast::Item { Ok(Signature { text, defs, refs: vec![] }) } - ast::ItemKind::TyAlias(ref generics, _, ref ty) => { + ast::ItemKind::TyAlias(_, ref generics, _, ref ty) => { let text = "type ".to_owned(); let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; @@ -502,7 +502,7 @@ impl Sig for ast::Item { items: _, } => { let mut text = String::new(); - if let ast::Defaultness::Default = defaultness { + if let ast::Defaultness::Default(_) = defaultness { text.push_str("default "); } if let ast::Unsafe::Yes(_) = unsafety { @@ -732,7 +732,7 @@ impl Sig for ast::ForeignItem { fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { let id = Some(self.id); match self.kind { - ast::ForeignItemKind::Fn(ref sig, ref generics, _) => { + ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => { let decl = &sig.decl; let mut text = String::new(); text.push_str("fn "); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 849950e939a02..19c705fa99753 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2106,7 +2106,7 @@ pub enum Const { /// For details see the [RFC #2532](https://github.com/rust-lang/rfcs/pull/2532). #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum Defaultness { - Default, + Default(Span), Final, } @@ -2411,15 +2411,15 @@ impl VariantData { } } -/// An item. -/// -/// The name might be a dummy name in case of anonymous items. +/// An item definition. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Item { pub attrs: Vec, pub id: NodeId, pub span: Span, pub vis: Visibility, + /// The name of the item. + /// It might be a dummy name in case of anonymous items. pub ident: Ident, pub kind: K, @@ -2506,11 +2506,11 @@ pub enum ItemKind { /// A constant item (`const`). /// /// E.g., `const FOO: i32 = 42;`. - Const(P, Option>), + Const(Defaultness, P, Option>), /// A function declaration (`fn`). /// /// E.g., `fn foo(bar: usize) -> usize { .. }`. - Fn(FnSig, Generics, Option>), + Fn(Defaultness, FnSig, Generics, Option>), /// A module declaration (`mod`). /// /// E.g., `mod foo;` or `mod foo { .. }`. @@ -2524,7 +2524,7 @@ pub enum ItemKind { /// A type alias (`type`). /// /// E.g., `type Foo = Bar;`. - TyAlias(Generics, GenericBounds, Option>), + TyAlias(Defaultness, Generics, GenericBounds, Option>), /// An enum definition (`enum`). /// /// E.g., `enum Foo { C, D }`. @@ -2571,30 +2571,41 @@ pub enum ItemKind { } impl ItemKind { - pub fn descriptive_variant(&self) -> &str { - match *self { + pub fn article(&self) -> &str { + use ItemKind::*; + match self { + Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..) + | Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..) => "a", + ExternCrate(..) | ForeignMod(..) | Mac(..) | Enum(..) | Impl { .. } => "an", + } + } + + pub fn descr(&self) -> &str { + match self { ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "use", + ItemKind::Use(..) => "`use` import", ItemKind::Static(..) => "static item", ItemKind::Const(..) => "constant item", ItemKind::Fn(..) => "function", ItemKind::Mod(..) => "module", - ItemKind::ForeignMod(..) => "foreign module", - ItemKind::GlobalAsm(..) => "global asm", + ItemKind::ForeignMod(..) => "extern block", + ItemKind::GlobalAsm(..) => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item", + ItemKind::Mac(..) => "item macro invocation", + ItemKind::MacroDef(..) => "macro definition", + ItemKind::Impl { .. } => "implementation", } } pub fn generics(&self) -> Option<&Generics> { match self { - Self::Fn(_, generics, _) - | Self::TyAlias(generics, ..) + Self::Fn(_, _, generics, _) + | Self::TyAlias(_, generics, ..) | Self::Enum(_, generics) | Self::Struct(_, generics) | Self::Union(_, generics) @@ -2613,19 +2624,7 @@ pub type ForeignItemKind = AssocItemKind; /// Represents associated items. /// These include items in `impl` and `trait` definitions. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct AssocItem { - pub attrs: Vec, - pub id: NodeId, - pub span: Span, - pub vis: Visibility, - pub ident: Ident, - - pub defaultness: Defaultness, - pub kind: AssocItemKind, - /// See `Item::tokens` for what this is. - pub tokens: Option, -} +pub type AssocItem = Item; /// Represents non-free item kinds. /// @@ -2638,13 +2637,22 @@ pub struct AssocItem { 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>), + Const(Defaultness, P, Option>), /// A static item (`static FOO: u8`). Static(P, Mutability, Option>), /// A function. - Fn(FnSig, Generics, Option>), + Fn(Defaultness, FnSig, Generics, Option>), /// A type. - TyAlias(Generics, GenericBounds, Option>), + TyAlias(Defaultness, Generics, GenericBounds, Option>), /// A macro expanding to items. Macro(Mac), } + +impl AssocItemKind { + pub fn defaultness(&self) -> Defaultness { + match *self { + Self::Const(def, ..) | Self::Fn(def, ..) | Self::TyAlias(def, ..) => def, + Self::Macro(..) | Self::Static(..) => Defaultness::Final, + } + } +} diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 313f526923564..cd485e7137808 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -722,6 +722,6 @@ macro_rules! derive_has_attrs { } derive_has_attrs! { - Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::AssocItem, ast::Arm, + Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::Arm, ast::Field, ast::FieldPat, ast::Variant, ast::Param, GenericParam } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 02f790dfbb4e9..05bb07cd4b90a 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -890,11 +890,11 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { match kind { ItemKind::ExternCrate(_orig_name) => {} ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), - ItemKind::Static(ty, _, expr) | ItemKind::Const(ty, expr) => { + ItemKind::Static(ty, _, expr) | ItemKind::Const(_, ty, expr) => { vis.visit_ty(ty); visit_opt(expr, |expr| vis.visit_expr(expr)); } - ItemKind::Fn(sig, generics, body) => { + ItemKind::Fn(_, sig, generics, body) => { visit_fn_sig(sig, vis); vis.visit_generics(generics); visit_opt(body, |body| vis.visit_block(body)); @@ -902,7 +902,7 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { ItemKind::Mod(m) => vis.visit_mod(m), ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), ItemKind::GlobalAsm(_ga) => {} - ItemKind::TyAlias(generics, bounds, ty) => { + ItemKind::TyAlias(_, generics, bounds, ty) => { vis.visit_generics(generics); visit_bounds(bounds, vis); visit_opt(ty, |ty| vis.visit_ty(ty)); @@ -948,8 +948,7 @@ pub fn noop_flat_map_assoc_item( mut item: P, visitor: &mut T, ) -> SmallVec<[P; 1]> { - let AssocItem { id, ident, vis, defaultness: _, attrs, kind, span, tokens: _ } = - item.deref_mut(); + let Item { id, ident, vis, attrs, kind, span, tokens: _ } = item.deref_mut(); walk_nested_item(visitor, id, span, ident, vis, attrs, kind); smallvec![item] } @@ -968,16 +967,16 @@ pub fn walk_nested_item( visitor.visit_vis(vis); visit_attrs(attrs, visitor); match kind { - AssocItemKind::Const(ty, expr) | AssocItemKind::Static(ty, _, expr) => { + AssocItemKind::Const(_, ty, expr) | AssocItemKind::Static(ty, _, expr) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } - AssocItemKind::Fn(sig, generics, body) => { + AssocItemKind::Fn(_, sig, generics, body) => { visitor.visit_generics(generics); visit_fn_sig(sig, visitor); visit_opt(body, |body| visitor.visit_block(body)); } - AssocItemKind::TyAlias(generics, bounds, ty) => { + AssocItemKind::TyAlias(_, generics, bounds, ty) => { visitor.visit_generics(generics); visit_bounds(bounds, visitor); visit_opt(ty, |ty| visitor.visit_ty(ty)); @@ -1049,7 +1048,7 @@ pub fn noop_flat_map_foreign_item( mut item: P, visitor: &mut T, ) -> SmallVec<[P; 1]> { - let ForeignItem { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); + let Item { ident, attrs, id, kind, vis, span, tokens: _ } = item.deref_mut(); walk_nested_item(visitor, id, span, ident, vis, attrs, kind); smallvec![item] } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index bd35918dba728..96149ad7947ce 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -298,11 +298,11 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { } } ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), - ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(ref typ, ref expr) => { + ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { visitor.visit_ty(typ); walk_list!(visitor, visit_expr, expr); } - ItemKind::Fn(ref sig, ref generics, ref body) => { + ItemKind::Fn(_, ref sig, ref generics, ref body) => { visitor.visit_generics(generics); let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, body.as_deref()); visitor.visit_fn(kind, item.span, item.id) @@ -312,7 +312,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga), - ItemKind::TyAlias(ref generics, ref bounds, ref ty) => { + ItemKind::TyAlias(_, ref generics, ref bounds, ref ty) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_ty, ty); @@ -526,7 +526,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { } pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) { - let ForeignItem { id, span, ident, vis, attrs, kind, tokens: _ } = item; + let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; walk_nested_item(visitor, *id, *span, *ident, vis, attrs, kind, FnCtxt::Foreign); } @@ -610,7 +610,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>, _span: Spa } pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) { - let AssocItem { id, span, ident, vis, attrs, kind, tokens: _, defaultness: _ } = item; + let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; walk_nested_item(visitor, *id, *span, *ident, vis, attrs, kind, FnCtxt::Assoc(ctxt)); } @@ -628,16 +628,16 @@ fn walk_nested_item<'a, V: Visitor<'a>>( visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); match kind { - AssocItemKind::Const(ty, expr) | AssocItemKind::Static(ty, _, expr) => { + AssocItemKind::Const(_, ty, expr) | AssocItemKind::Static(ty, _, expr) => { visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(sig, generics, body) => { + AssocItemKind::Fn(_, sig, generics, body) => { visitor.visit_generics(generics); let kind = FnKind::Fn(ctxt, ident, sig, vis, body.as_deref()); visitor.visit_fn(kind, span, id); } - AssocItemKind::TyAlias(generics, bounds, ty) => { + AssocItemKind::TyAlias(_, generics, bounds, ty) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_ty, ty); diff --git a/src/test/ui/async-await/no-unsafe-async.stderr b/src/test/ui/async-await/no-unsafe-async.stderr index 2651588d59710..c97b4ff0f497e 100644 --- a/src/test/ui/async-await/no-unsafe-async.stderr +++ b/src/test/ui/async-await/no-unsafe-async.stderr @@ -1,8 +1,13 @@ error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/no-unsafe-async.rs:7:12 | +LL | impl S { + | - while parsing this item list starting here +LL | #[cfg(FALSE)] LL | unsafe async fn g() {} | ^^^^^ expected one of `extern` or `fn` +LL | } + | - the item list ends here error: expected one of `extern` or `fn`, found keyword `async` --> $DIR/no-unsafe-async.rs:11:8 diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs index 2ed682cea9503..74f304d81a0f1 100644 --- a/src/test/ui/did_you_mean/issue-40006.rs +++ b/src/test/ui/did_you_mean/issue-40006.rs @@ -1,28 +1,28 @@ -impl dyn A { //~ ERROR missing +impl dyn A { Y -} +} //~ ERROR expected one of `!` or `::`, found `}` struct S; -trait X { //~ ERROR missing - X() {} +trait X { + X() {} //~ ERROR expected one of `!` or `::`, found `(` fn xxx() { ### } L = M; Z = { 2 + 3 }; ::Y (); } -trait A { //~ ERROR missing - X() {} +trait A { + X() {} //~ ERROR expected one of `!` or `::`, found `(` } trait B { fn xxx() { ### } //~ ERROR expected } -trait C { //~ ERROR missing `fn`, `type`, `const`, or `static` for item declaration - L = M; +trait C { + L = M; //~ ERROR expected one of `!` or `::`, found `=` } -trait D { //~ ERROR missing `fn`, `type`, `const`, or `static` for item declaration - Z = { 2 + 3 }; +trait D { + Z = { 2 + 3 }; //~ ERROR expected one of `!` or `::`, found `=` } trait E { ::Y (); //~ ERROR expected one of diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index 119e30a3e0f57..613d7eee59480 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -1,26 +1,36 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-40006.rs:1:13 +error: expected one of `!` or `::`, found `}` + --> $DIR/issue-40006.rs:3:1 | -LL | impl dyn A { - | _____________^ -LL | | Y - | |____^ missing `fn`, `type`, `const`, or `static` +LL | impl dyn A { + | - while parsing this item list starting here +LL | Y + | - expected one of `!` or `::` +LL | } + | ^ + | | + | unexpected token + | the item list ends here -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-40006.rs:7:10 +error: expected one of `!` or `::`, found `(` + --> $DIR/issue-40006.rs:8:6 | -LL | trait X { - | __________^ -LL | | X() {} - | |____^ missing `fn`, `type`, `const`, or `static` +LL | trait X { + | - while parsing this item list starting here +LL | X() {} + | ^ expected one of `!` or `::` +... +LL | } + | - the item list ends here -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-40006.rs:15:10 +error: expected one of `!` or `::`, found `(` + --> $DIR/issue-40006.rs:16:6 | -LL | trait A { - | __________^ -LL | | X() {} - | |____^ missing `fn`, `type`, `const`, or `static` +LL | trait A { + | - while parsing this item list starting here +LL | X() {} + | ^ expected one of `!` or `::` +LL | } + | - the item list ends here error: expected `[`, found `#` --> $DIR/issue-40006.rs:19:17 @@ -28,33 +38,51 @@ error: expected `[`, found `#` LL | fn xxx() { ### } | ^ expected `[` -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-40006.rs:21:10 +error: expected one of `!` or `::`, found `=` + --> $DIR/issue-40006.rs:22:7 | -LL | trait C { - | __________^ -LL | | L = M; - | |____^ missing `fn`, `type`, `const`, or `static` +LL | trait C { + | - while parsing this item list starting here +LL | L = M; + | ^ expected one of `!` or `::` +LL | } + | - the item list ends here -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-40006.rs:24:10 +error: expected one of `!` or `::`, found `=` + --> $DIR/issue-40006.rs:25:7 | -LL | trait D { - | __________^ -LL | | Z = { 2 + 3 }; - | |____^ missing `fn`, `type`, `const`, or `static` +LL | trait D { + | - while parsing this item list starting here +LL | Z = { 2 + 3 }; + | ^ expected one of `!` or `::` +LL | } + | - the item list ends here error: expected one of `!` or `::`, found `(` --> $DIR/issue-40006.rs:28:9 | +LL | trait E { + | - while parsing this item list starting here LL | ::Y (); | ^ expected one of `!` or `::` +LL | } + | - the item list ends here -error: missing `fn`, `type`, `const`, or `static` for item declaration +error: missing `fn` for method definition --> $DIR/issue-40006.rs:32:8 | +LL | impl S { + | - while parsing this item list starting here LL | pub hello_method(&self) { - | ^ missing `fn`, `type`, `const`, or `static` + | ^ +... +LL | } + | - the item list ends here + | +help: add `fn` here to parse `hello_method` as a public method + | +LL | pub fn hello_method(&self) { + | ^^ error[E0599]: no method named `hello_method` found for struct `S` in the current scope --> $DIR/issue-40006.rs:38:7 diff --git a/src/test/ui/generic-associated-types/empty_generics.stderr b/src/test/ui/generic-associated-types/empty_generics.stderr index d3acad47831be..bd5708d814037 100644 --- a/src/test/ui/generic-associated-types/empty_generics.stderr +++ b/src/test/ui/generic-associated-types/empty_generics.stderr @@ -1,8 +1,13 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,` --> $DIR/empty_generics.rs:5:14 | +LL | trait Foo { + | - while parsing this item list starting here LL | type Bar<,>; | ^ expected one of `>`, `const`, identifier, or lifetime +LL | +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/issues/issue-58856-1.stderr b/src/test/ui/issues/issue-58856-1.stderr index 0ea6b01754890..a8db8e8b41ad2 100644 --- a/src/test/ui/issues/issue-58856-1.stderr +++ b/src/test/ui/issues/issue-58856-1.stderr @@ -9,8 +9,14 @@ LL | fn b(self> error: expected `;` or `{`, found `>` --> $DIR/issue-58856-1.rs:3:14 | +LL | impl A { + | - while parsing this item list starting here +LL | LL | fn b(self> | ^ expected `;` or `{` +... +LL | } + | - the item list ends here error[E0412]: cannot find type `A` in this scope --> $DIR/issue-58856-1.rs:1:6 diff --git a/src/test/ui/issues/issue-58856-2.rs b/src/test/ui/issues/issue-58856-2.rs index 745f0300bd5ad..9356d57b0e5f4 100644 --- a/src/test/ui/issues/issue-58856-2.rs +++ b/src/test/ui/issues/issue-58856-2.rs @@ -9,6 +9,6 @@ impl Howness for () { Empty } } -//~^ ERROR expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, +//~^ ERROR non-item in item list fn main() {} diff --git a/src/test/ui/issues/issue-58856-2.stderr b/src/test/ui/issues/issue-58856-2.stderr index f4ca3c46ea28a..303b5eacc3296 100644 --- a/src/test/ui/issues/issue-58856-2.stderr +++ b/src/test/ui/issues/issue-58856-2.stderr @@ -7,13 +7,17 @@ LL | fn how_are_you(&self -> Empty { | | help: `)` may belong here | unclosed delimiter -error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `static`, `type`, `unsafe`, `}`, or identifier, found `)` +error: non-item in item list --> $DIR/issue-58856-2.rs:11:1 | -LL | } - | - expected one of 12 possible tokens +LL | impl Howness for () { + | - item list starts here +... LL | } - | ^ unexpected token + | ^ + | | + | non-item starts here + | item list ends here error[E0407]: method `how_are_you` is not a member of trait `Howness` --> $DIR/issue-58856-2.rs:6:5 diff --git a/src/test/ui/issues/issue-60075.rs b/src/test/ui/issues/issue-60075.rs index 1323f646be893..e89d78ee8a6a2 100644 --- a/src/test/ui/issues/issue-60075.rs +++ b/src/test/ui/issues/issue-60075.rs @@ -4,7 +4,8 @@ trait T { fn qux() -> Option { let _ = if true { }); -//~^ ERROR expected one of `async` -//~| ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `}` +//~^ ERROR non-item in item list +//~| ERROR mismatched closing delimiter: `)` +//~| ERROR expected one of `.`, `;` Some(4) } diff --git a/src/test/ui/issues/issue-60075.stderr b/src/test/ui/issues/issue-60075.stderr index bab50a53b1ae4..e3b7f4ad420e8 100644 --- a/src/test/ui/issues/issue-60075.stderr +++ b/src/test/ui/issues/issue-60075.stderr @@ -4,14 +4,26 @@ 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`, `static`, `type`, `unsafe`, `}`, or identifier, found `;` +error: non-item in item list --> $DIR/issue-60075.rs:6:11 | +LL | trait T { + | - item list starts here +... +LL | }); + | ^ non-item starts here +... +LL | } + | - item list ends here + +error: mismatched closing delimiter: `)` + --> $DIR/issue-60075.rs:6:10 + | LL | fn qux() -> Option { | - unclosed delimiter LL | let _ = if true { LL | }); - | ^ help: `}` may belong here + | ^ mismatched closing delimiter -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/src/test/ui/macros/issue-54441.rs b/src/test/ui/macros/issue-54441.rs index 5570f081b157d..b24d7e1f6bee5 100644 --- a/src/test/ui/macros/issue-54441.rs +++ b/src/test/ui/macros/issue-54441.rs @@ -1,7 +1,6 @@ macro_rules! m { - //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration () => { - let + let //~ ERROR macro expansion ignores token `let` and any following }; } diff --git a/src/test/ui/macros/issue-54441.stderr b/src/test/ui/macros/issue-54441.stderr index 5857aacb43176..752916e665560 100644 --- a/src/test/ui/macros/issue-54441.stderr +++ b/src/test/ui/macros/issue-54441.stderr @@ -1,11 +1,13 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-54441.rs:1:1 +error: macro expansion ignores token `let` and any following + --> $DIR/issue-54441.rs:3:9 | -LL | / macro_rules! m { -LL | | -LL | | () => { -LL | | let - | |________^ missing `fn`, `type`, `const`, or `static` +LL | let + | ^^^ +... +LL | m!(); + | ----- caused by the macro expansion here + | + = note: the usage of `m!` is likely invalid in foreign item context error: aborting due to previous error diff --git a/src/test/ui/parser/assoc-static-semantic-fail.rs b/src/test/ui/parser/assoc-static-semantic-fail.rs index cf3debd77cbfd..215a292131521 100644 --- a/src/test/ui/parser/assoc-static-semantic-fail.rs +++ b/src/test/ui/parser/assoc-static-semantic-fail.rs @@ -10,10 +10,14 @@ impl S { //~^ ERROR associated `static` items are not allowed static IB: u8; //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body default static IC: u8 = 0; //~^ ERROR associated `static` items are not allowed + //~| ERROR a static item cannot be `default` pub(crate) default static ID: u8; //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body + //~| ERROR a static item cannot be `default` } trait T { @@ -23,11 +27,11 @@ trait T { //~^ 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 + //~| ERROR a static item cannot be `default` 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 + //~| ERROR a static item cannot be `default` } impl T for S { @@ -35,9 +39,13 @@ impl T for S { //~^ ERROR associated `static` items are not allowed static TB: u8; //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body default static TC: u8 = 0; //~^ ERROR associated `static` items are not allowed + //~| ERROR a static item cannot be `default` pub default static TD: u8; //~^ ERROR associated `static` items are not allowed + //~| ERROR associated constant in `impl` without body //~| ERROR unnecessary visibility qualifier + //~| ERROR a static item cannot be `default` } diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr index d02e2855c7e62..612297c9cd8b1 100644 --- a/src/test/ui/parser/assoc-static-semantic-fail.stderr +++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr @@ -10,90 +10,158 @@ error: associated `static` items are not allowed LL | static IB: u8; | ^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:14:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:13:5 + --> $DIR/assoc-static-semantic-fail.rs:14:5 | LL | default static IC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:17:16 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:15:5 + --> $DIR/assoc-static-semantic-fail.rs:17:5 | LL | pub(crate) default static ID: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:20:5 + --> $DIR/assoc-static-semantic-fail.rs:24:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:22:5 + --> $DIR/assoc-static-semantic-fail.rs:26:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:28:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:24:5 + --> $DIR/assoc-static-semantic-fail.rs:28:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:31:16 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:27:5 + --> $DIR/assoc-static-semantic-fail.rs:31:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:34:5 + --> $DIR/assoc-static-semantic-fail.rs:38:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:36:5 + --> $DIR/assoc-static-semantic-fail.rs:40:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:43:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:38:5 + --> $DIR/assoc-static-semantic-fail.rs:43:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-semantic-fail.rs:46:9 + | +LL | pub default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-semantic-fail.rs:40:5 + --> $DIR/assoc-static-semantic-fail.rs:46: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 +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:11:5 | -LL | default static TC: u8 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | static IB: u8; + | ^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` -error: `default` is only allowed on items in `impl` definitions - --> $DIR/assoc-static-semantic-fail.rs:27:5 +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:17:5 | -LL | pub(crate) default static TD: u8; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | pub(crate) default static ID: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` error[E0449]: unnecessary visibility qualifier - --> $DIR/assoc-static-semantic-fail.rs:27:5 + --> $DIR/assoc-static-semantic-fail.rs:31:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^ -error[E0449]: unnecessary visibility qualifier +error: associated constant in `impl` without body --> $DIR/assoc-static-semantic-fail.rs:40:5 | +LL | static TB: u8; + | ^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +error: associated constant in `impl` without body + --> $DIR/assoc-static-semantic-fail.rs:46:5 + | +LL | pub default static TD: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +error[E0449]: unnecessary visibility qualifier + --> $DIR/assoc-static-semantic-fail.rs:46:5 + | LL | pub default static TD: u8; | ^^^ `pub` not permitted here because it's implied -error: aborting due to 16 previous errors +error: aborting due to 24 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 index 8f042767e5503..492f2ea16ef57 100644 --- a/src/test/ui/parser/assoc-static-syntactic-fail.rs +++ b/src/test/ui/parser/assoc-static-syntactic-fail.rs @@ -7,7 +7,9 @@ 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 + //~^ ERROR a static item cannot be `default` pub(crate) default static ID: u8; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` } #[cfg(FALSE)] @@ -15,7 +17,9 @@ 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 a static item cannot be `default` pub(crate) default static TD: u8; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` } #[cfg(FALSE)] @@ -23,5 +27,7 @@ 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 + //~^ ERROR a static item cannot be `default` pub default static TD: u8; //~ ERROR associated `static` items are not allowed + //~^ ERROR a static item cannot be `default` } diff --git a/src/test/ui/parser/assoc-static-syntactic-fail.stderr b/src/test/ui/parser/assoc-static-syntactic-fail.stderr index bb1e5c4be2e9c..e972361451235 100644 --- a/src/test/ui/parser/assoc-static-syntactic-fail.stderr +++ b/src/test/ui/parser/assoc-static-syntactic-fail.stderr @@ -10,65 +10,113 @@ error: associated `static` items are not allowed LL | static IB: u8; | ^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:9:5 + | +LL | default static IC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed --> $DIR/assoc-static-syntactic-fail.rs:9:5 | LL | default static IC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:11:16 + | +LL | pub(crate) default static ID: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:10:5 + --> $DIR/assoc-static-syntactic-fail.rs:11:5 | LL | pub(crate) default static ID: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:15:5 + --> $DIR/assoc-static-syntactic-fail.rs:17:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:16:5 + --> $DIR/assoc-static-syntactic-fail.rs:18:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:19:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:17:5 + --> $DIR/assoc-static-syntactic-fail.rs:19:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:21:16 + | +LL | pub(crate) default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:18:5 + --> $DIR/assoc-static-syntactic-fail.rs:21:5 | LL | pub(crate) default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:23:5 + --> $DIR/assoc-static-syntactic-fail.rs:27:5 | LL | static TA: u8 = 0; | ^^^^^^^^^^^^^^^^^^ error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:24:5 + --> $DIR/assoc-static-syntactic-fail.rs:28:5 | LL | static TB: u8; | ^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:29:5 + | +LL | default static TC: u8 = 0; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:25:5 + --> $DIR/assoc-static-syntactic-fail.rs:29:5 | LL | default static TC: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: a static item cannot be `default` + --> $DIR/assoc-static-syntactic-fail.rs:31:9 + | +LL | pub default static TD: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + error: associated `static` items are not allowed - --> $DIR/assoc-static-syntactic-fail.rs:26:5 + --> $DIR/assoc-static-syntactic-fail.rs:31:5 | LL | pub default static TD: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 18 previous errors diff --git a/src/test/ui/parser/attrs-after-extern-mod.stderr b/src/test/ui/parser/attrs-after-extern-mod.stderr index 6060f3afe1e95..3862f5c379fc3 100644 --- a/src/test/ui/parser/attrs-after-extern-mod.stderr +++ b/src/test/ui/parser/attrs-after-extern-mod.stderr @@ -1,8 +1,12 @@ error: expected item after attributes --> $DIR/attrs-after-extern-mod.rs:6:5 | +LL | extern { + | - while parsing this item list starting here LL | #[cfg(stage37)] | ^^^^^^^^^^^^^^^ +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/parser/default-on-wrong-item-kind.rs b/src/test/ui/parser/default-on-wrong-item-kind.rs new file mode 100644 index 0000000000000..98a95cfa35a9e --- /dev/null +++ b/src/test/ui/parser/default-on-wrong-item-kind.rs @@ -0,0 +1,140 @@ +// Test parsing for `default` where it doesn't belong. +// Specifically, we are interested in kinds of items or items in certain contexts. +// Also test item kinds in `extern` blocks and associated contexts which are not allowed there. + +fn main() {} + +#[cfg(FALSE)] +mod free_items { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + default use foo; //~ ERROR a `use` import cannot be `default` + default static foo: u8; //~ ERROR a static item cannot be `default` + default const foo: u8; + default fn foo(); + default mod foo {} //~ ERROR a module cannot be `default` + default extern "C" {} //~ ERROR an extern block cannot be `default` + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + default struct foo {} //~ ERROR a struct cannot be `default` + default union foo {} //~ ERROR a union cannot be `default` + default trait foo {} //~ ERROR a trait cannot be `default` + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + default impl foo {} + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` +} + +#[cfg(FALSE)] +extern "C" { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + //~^ ERROR extern crate is not supported in `extern` blocks + default use foo; //~ ERROR a `use` import cannot be `default` + //~^ ERROR `use` import is not supported in `extern` blocks + default static foo: u8; //~ ERROR a static item cannot be `default` + default const foo: u8; + //~^ ERROR extern items cannot be `const` + default fn foo(); + default mod foo {} //~ ERROR a module cannot be `default` + //~^ ERROR module is not supported in `extern` blocks + default extern "C" {} //~ ERROR an extern block cannot be `default` + //~^ ERROR extern block is not supported in `extern` blocks + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + //~^ ERROR enum is not supported in `extern` blocks + default struct foo {} //~ ERROR a struct cannot be `default` + //~^ ERROR struct is not supported in `extern` blocks + default union foo {} //~ ERROR a union cannot be `default` + //~^ ERROR union is not supported in `extern` blocks + default trait foo {} //~ ERROR a trait cannot be `default` + //~^ ERROR trait is not supported in `extern` blocks + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + //~^ ERROR trait alias is not supported in `extern` blocks + default impl foo {} + //~^ ERROR implementation is not supported in `extern` blocks + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `extern` blocks + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `extern` blocks +} + +#[cfg(FALSE)] +impl S { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + //~^ ERROR extern crate is not supported in `trait`s or `impl`s + default use foo; //~ ERROR a `use` import cannot be `default` + //~^ ERROR `use` import is not supported in `trait`s or `impl`s + default static foo: u8; //~ ERROR a static item cannot be `default` + //~^ ERROR associated `static` items are not allowed + default const foo: u8; + default fn foo(); + default mod foo {}//~ ERROR a module cannot be `default` + //~^ ERROR module is not supported in `trait`s or `impl`s + default extern "C" {} //~ ERROR an extern block cannot be `default` + //~^ ERROR extern block is not supported in `trait`s or `impl`s + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + //~^ ERROR enum is not supported in `trait`s or `impl`s + default struct foo {} //~ ERROR a struct cannot be `default` + //~^ ERROR struct is not supported in `trait`s or `impl`s + default union foo {} //~ ERROR a union cannot be `default` + //~^ ERROR union is not supported in `trait`s or `impl`s + default trait foo {} //~ ERROR a trait cannot be `default` + //~^ ERROR trait is not supported in `trait`s or `impl`s + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + //~^ ERROR trait alias is not supported in `trait`s or `impl`s + default impl foo {} + //~^ ERROR implementation is not supported in `trait`s or `impl`s + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s +} + +#[cfg(FALSE)] +trait T { + default extern crate foo; //~ ERROR an extern crate cannot be `default` + //~^ ERROR extern crate is not supported in `trait`s or `impl`s + default use foo; //~ ERROR a `use` import cannot be `default` + //~^ ERROR `use` import is not supported in `trait`s or `impl`s + default static foo: u8; //~ ERROR a static item cannot be `default` + //~^ ERROR associated `static` items are not allowed + default const foo: u8; + default fn foo(); + default mod foo {}//~ ERROR a module cannot be `default` + //~^ ERROR module is not supported in `trait`s or `impl`s + default extern "C" {} //~ ERROR an extern block cannot be `default` + //~^ ERROR extern block is not supported in `trait`s or `impl`s + default type foo = u8; + default enum foo {} //~ ERROR an enum cannot be `default` + //~^ ERROR enum is not supported in `trait`s or `impl`s + default struct foo {} //~ ERROR a struct cannot be `default` + //~^ ERROR struct is not supported in `trait`s or `impl`s + default union foo {} //~ ERROR a union cannot be `default` + //~^ ERROR union is not supported in `trait`s or `impl`s + default trait foo {} //~ ERROR a trait cannot be `default` + //~^ ERROR trait is not supported in `trait`s or `impl`s + default trait foo = Ord; //~ ERROR a trait alias cannot be `default` + //~^ ERROR trait alias is not supported in `trait`s or `impl`s + default impl foo {} + //~^ ERROR implementation is not supported in `trait`s or `impl`s + default!(); + default::foo::bar!(); + default default!(); //~ ERROR an item macro invocation cannot be `default` + default default::foo::bar!(); //~ ERROR an item macro invocation cannot be `default` + default macro foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s + default macro_rules! foo {} //~ ERROR a macro definition cannot be `default` + //~^ ERROR macro definition is not supported in `trait`s or `impl`s +} diff --git a/src/test/ui/parser/default-on-wrong-item-kind.stderr b/src/test/ui/parser/default-on-wrong-item-kind.stderr new file mode 100644 index 0000000000000..9788bd64725b8 --- /dev/null +++ b/src/test/ui/parser/default-on-wrong-item-kind.stderr @@ -0,0 +1,688 @@ +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:9:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:10:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:11:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:14:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:15:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:17:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:18:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:19:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:20:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:21:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:25:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:26:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:27:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:28:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:33:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern crate is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:33:5 + | +LL | default extern crate foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:35:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: `use` import is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:35:5 + | +LL | default use foo; + | ^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:37:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern items cannot be `const` + --> $DIR/default-on-wrong-item-kind.rs:38:19 + | +LL | default const foo: u8; + | --------------^^^ + | | + | help: try using a static value: `static` + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:41:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: module is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:41:5 + | +LL | default mod foo {} + | ^^^^^^^^^^^^^^^ + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:43:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern block is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:43:5 + | +LL | default extern "C" {} + | ^^^^^^^^^^^^^^^^^^ + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:46:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: enum is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:46:5 + | +LL | default enum foo {} + | ^^^^^^^^^^^^^^^^ + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:48:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: struct is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:48:5 + | +LL | default struct foo {} + | ^^^^^^^^^^^^^^^^^^ + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:50:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: union is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:50:5 + | +LL | default union foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:52:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:52:5 + | +LL | default trait foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:54:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait alias is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:54:5 + | +LL | default trait foo = Ord; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:56:5 + | +LL | default impl foo {} + | ^^^^^^^^^^^^^^^^ + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:60:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:61:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:62:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:62:5 + | +LL | default macro foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:64:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `extern` blocks + --> $DIR/default-on-wrong-item-kind.rs:64:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:70:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern crate is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:70:5 + | +LL | default extern crate foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:72:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: `use` import is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:72:5 + | +LL | default use foo; + | ^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:74:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/default-on-wrong-item-kind.rs:74:5 + | +LL | default static foo: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:78:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: module is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:78:5 + | +LL | default mod foo {} + | ^^^^^^^^^^^^^^^ + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:80:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern block is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:80:5 + | +LL | default extern "C" {} + | ^^^^^^^^^^^^^^^^^^ + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:83:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:83:5 + | +LL | default enum foo {} + | ^^^^^^^^^^^^^^^^ + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:85:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:85:5 + | +LL | default struct foo {} + | ^^^^^^^^^^^^^^^^^^ + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:87:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: union is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:87:5 + | +LL | default union foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:89:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:89:5 + | +LL | default trait foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:91:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait alias is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:91:5 + | +LL | default trait foo = Ord; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:93:5 + | +LL | default impl foo {} + | ^^^^^^^^^^^^^^^^ + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:97:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:98:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:99:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:99:5 + | +LL | default macro foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:101:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:101:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: an extern crate cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:107:5 + | +LL | default extern crate foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern crate is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:107:5 + | +LL | default extern crate foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: a `use` import cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:109:5 + | +LL | default use foo; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: `use` import is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:109:5 + | +LL | default use foo; + | ^^^^^^^^^^^^^^^^ + +error: a static item cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:111:5 + | +LL | default static foo: u8; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: associated `static` items are not allowed + --> $DIR/default-on-wrong-item-kind.rs:111:5 + | +LL | default static foo: u8; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: a module cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:115:5 + | +LL | default mod foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: module is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:115:5 + | +LL | default mod foo {} + | ^^^^^^^^^^^^^^^ + +error: an extern block cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:117:5 + | +LL | default extern "C" {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: extern block is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:117:5 + | +LL | default extern "C" {} + | ^^^^^^^^^^^^^^^^^^ + +error: an enum cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:120:5 + | +LL | default enum foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:120:5 + | +LL | default enum foo {} + | ^^^^^^^^^^^^^^^^ + +error: a struct cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:122:5 + | +LL | default struct foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:122:5 + | +LL | default struct foo {} + | ^^^^^^^^^^^^^^^^^^ + +error: a union cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:124:5 + | +LL | default union foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: union is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:124:5 + | +LL | default union foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a trait cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:126:5 + | +LL | default trait foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:126:5 + | +LL | default trait foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a trait alias cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:128:5 + | +LL | default trait foo = Ord; + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: trait alias is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:128:5 + | +LL | default trait foo = Ord; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:130:5 + | +LL | default impl foo {} + | ^^^^^^^^^^^^^^^^ + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:134:5 + | +LL | default default!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: an item macro invocation cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:135:5 + | +LL | default default::foo::bar!(); + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:136:5 + | +LL | default macro foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:136:5 + | +LL | default macro foo {} + | ^^^^^^^^^^^^^^^^^ + +error: a macro definition cannot be `default` + --> $DIR/default-on-wrong-item-kind.rs:138:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^ `default` because of this + | + = note: only associated `fn`, `const`, and `type` items can be `default` + +error: macro definition is not supported in `trait`s or `impl`s + --> $DIR/default-on-wrong-item-kind.rs:138:5 + | +LL | default macro_rules! foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 95 previous errors + diff --git a/src/test/ui/parser/default-unmatched-assoc.rs b/src/test/ui/parser/default-unmatched-assoc.rs new file mode 100644 index 0000000000000..168ea3e76f648 --- /dev/null +++ b/src/test/ui/parser/default-unmatched-assoc.rs @@ -0,0 +1,16 @@ +fn main() {} + +trait Foo { + default!(); //~ ERROR cannot find macro `default` in this scope + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} + +struct S; +impl S { + default!(); //~ ERROR cannot find macro `default` in this scope + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} diff --git a/src/test/ui/parser/default-unmatched-assoc.stderr b/src/test/ui/parser/default-unmatched-assoc.stderr new file mode 100644 index 0000000000000..c8d1769cb5a2a --- /dev/null +++ b/src/test/ui/parser/default-unmatched-assoc.stderr @@ -0,0 +1,54 @@ +error: `default` is not followed by an item + --> $DIR/default-unmatched-assoc.rs:5:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default-unmatched-assoc.rs:5:13 + | +LL | trait Foo { + | - item list starts here +LL | default!(); +LL | default do + | ^^ non-item starts here +... +LL | } + | - item list ends here + +error: `default` is not followed by an item + --> $DIR/default-unmatched-assoc.rs:13:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default-unmatched-assoc.rs:13:13 + | +LL | impl S { + | - item list starts here +LL | default!(); +LL | default do + | ^^ non-item starts here +... +LL | } + | - item list ends here + +error: cannot find macro `default` in this scope + --> $DIR/default-unmatched-assoc.rs:12:5 + | +LL | default!(); + | ^^^^^^^ + +error: cannot find macro `default` in this scope + --> $DIR/default-unmatched-assoc.rs:4:5 + | +LL | default!(); + | ^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/default-unmatched-extern.rs b/src/test/ui/parser/default-unmatched-extern.rs new file mode 100644 index 0000000000000..8d0ea590f573f --- /dev/null +++ b/src/test/ui/parser/default-unmatched-extern.rs @@ -0,0 +1,8 @@ +fn main() {} + +extern "C" { + default!(); //~ ERROR cannot find macro `default` in this scope + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list +} diff --git a/src/test/ui/parser/default-unmatched-extern.stderr b/src/test/ui/parser/default-unmatched-extern.stderr new file mode 100644 index 0000000000000..bb4efd51631e4 --- /dev/null +++ b/src/test/ui/parser/default-unmatched-extern.stderr @@ -0,0 +1,28 @@ +error: `default` is not followed by an item + --> $DIR/default-unmatched-extern.rs:5:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default-unmatched-extern.rs:5:13 + | +LL | extern "C" { + | - item list starts here +LL | default!(); +LL | default do + | ^^ non-item starts here +... +LL | } + | - item list ends here + +error: cannot find macro `default` in this scope + --> $DIR/default-unmatched-extern.rs:4:5 + | +LL | default!(); + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/parser/default-unmatched.rs b/src/test/ui/parser/default-unmatched.rs new file mode 100644 index 0000000000000..49346e5c6318d --- /dev/null +++ b/src/test/ui/parser/default-unmatched.rs @@ -0,0 +1,6 @@ +mod foo { + default!(); // OK. + default do + //~^ ERROR `default` is not followed by an item + //~| ERROR expected item, found reserved keyword `do` +} diff --git a/src/test/ui/parser/default-unmatched.stderr b/src/test/ui/parser/default-unmatched.stderr new file mode 100644 index 0000000000000..331e003f63c0f --- /dev/null +++ b/src/test/ui/parser/default-unmatched.stderr @@ -0,0 +1,16 @@ +error: `default` is not followed by an item + --> $DIR/default-unmatched.rs:3:5 + | +LL | default do + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: expected item, found reserved keyword `do` + --> $DIR/default-unmatched.rs:3:13 + | +LL | default do + | ^^ expected item + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/parser/default.rs b/src/test/ui/parser/default.rs index 50952eef22f5c..64ba4b5531184 100644 --- a/src/test/ui/parser/default.rs +++ b/src/test/ui/parser/default.rs @@ -20,7 +20,8 @@ impl Foo for u16 { impl Foo for u32 { //~ ERROR not all trait items implemented, missing: `foo` default pub fn foo() -> T { T::default() } - //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration + //~^ ERROR `default` is not followed by an item + //~| ERROR non-item in item list } fn main() {} diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index 07b051ece2b5d..15c49e8b6270b 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -1,8 +1,21 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/default.rs:22:12 +error: `default` is not followed by an item + --> $DIR/default.rs:22:5 | LL | default pub fn foo() -> T { T::default() } - | ^ missing `fn`, `type`, `const`, or `static` + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: non-item in item list + --> $DIR/default.rs:22:13 + | +LL | impl Foo for u32 { + | - item list starts here +LL | default pub fn foo() -> T { T::default() } + | ^^^ non-item starts here +... +LL | } + | - item list ends here error[E0449]: unnecessary visibility qualifier --> $DIR/default.rs:16:5 @@ -19,7 +32,7 @@ LL | fn foo() -> T; LL | impl Foo for u32 { | ^^^^^^^^^^^^^^^^ missing `foo` in implementation -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0449. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs index f6e7f7e6abe8f..31318ae3a096c 100644 --- a/src/test/ui/parser/duplicate-visibility.rs +++ b/src/test/ui/parser/duplicate-visibility.rs @@ -2,5 +2,6 @@ fn main() {} extern { pub pub fn foo(); - //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration + //~^ ERROR visibility `pub` is not followed by an item + //~| ERROR non-item in item list } diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr index 398ba65c9e1d8..36b9efd9dca6e 100644 --- a/src/test/ui/parser/duplicate-visibility.stderr +++ b/src/test/ui/parser/duplicate-visibility.stderr @@ -1,8 +1,21 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/duplicate-visibility.rs:4:8 +error: visibility `pub` is not followed by an item + --> $DIR/duplicate-visibility.rs:4:5 | LL | pub pub fn foo(); - | ^ missing `fn`, `type`, `const`, or `static` + | ^^^ the visibility + | + = help: you likely meant to define an item, e.g., `pub fn foo() {}` + +error: non-item in item list + --> $DIR/duplicate-visibility.rs:4:9 + | +LL | extern { + | - item list starts here +LL | pub pub fn foo(); + | ^^^ non-item starts here +... +LL | } + | - item list ends here -error: aborting due to previous error +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/extern-no-fn.rs b/src/test/ui/parser/extern-no-fn.rs index dc47f7410730c..d9f35e0eb5cfc 100644 --- a/src/test/ui/parser/extern-no-fn.rs +++ b/src/test/ui/parser/extern-no-fn.rs @@ -1,6 +1,5 @@ extern { -//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration - f(); + f(); //~ ERROR expected one of `!` or `::`, found `(` } fn main() { diff --git a/src/test/ui/parser/extern-no-fn.stderr b/src/test/ui/parser/extern-no-fn.stderr index 8d55eefc8d0ec..0151cb4235b0d 100644 --- a/src/test/ui/parser/extern-no-fn.stderr +++ b/src/test/ui/parser/extern-no-fn.stderr @@ -1,11 +1,12 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/extern-no-fn.rs:1:9 +error: expected one of `!` or `::`, found `(` + --> $DIR/extern-no-fn.rs:2:6 | -LL | extern { - | _________^ -LL | | -LL | | f(); - | |____^ missing `fn`, `type`, `const`, or `static` +LL | extern { + | - while parsing this item list starting here +LL | f(); + | ^ expected one of `!` or `::` +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/parser/foreign-const-semantic-fail.rs b/src/test/ui/parser/foreign-const-semantic-fail.rs index d28b64142826c..82978e655ba38 100644 --- a/src/test/ui/parser/foreign-const-semantic-fail.rs +++ b/src/test/ui/parser/foreign-const-semantic-fail.rs @@ -5,4 +5,5 @@ extern { //~^ ERROR extern items cannot be `const` const B: isize = 42; //~^ ERROR extern items cannot be `const` + //~| ERROR incorrect `static` inside `extern` block } diff --git a/src/test/ui/parser/foreign-const-semantic-fail.stderr b/src/test/ui/parser/foreign-const-semantic-fail.stderr index f364f11bb038d..f529b3ad87b2f 100644 --- a/src/test/ui/parser/foreign-const-semantic-fail.stderr +++ b/src/test/ui/parser/foreign-const-semantic-fail.stderr @@ -18,5 +18,18 @@ LL | const B: isize = 42; | = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html -error: aborting due to 2 previous errors +error: incorrect `static` inside `extern` block + --> $DIR/foreign-const-semantic-fail.rs:6:11 + | +LL | extern { + | ------ `extern` blocks define existing foreign statics and statics inside of them cannot have a body +... +LL | const B: isize = 42; + | ^ -- the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/impl-parsing.rs b/src/test/ui/parser/impl-parsing.rs index 270c8b43dfd5e..80ce888557078 100644 --- a/src/test/ui/parser/impl-parsing.rs +++ b/src/test/ui/parser/impl-parsing.rs @@ -6,4 +6,5 @@ impl Trait .. {} //~ ERROR missing `for` in a trait impl impl ?Sized for Type {} //~ ERROR expected a trait, found type impl ?Sized for .. {} //~ ERROR expected a trait, found type -default unsafe FAIL //~ ERROR expected `impl`, found `FAIL` +default unsafe FAIL //~ ERROR expected item, found keyword `unsafe` +//~^ ERROR `default` is not followed by an item diff --git a/src/test/ui/parser/impl-parsing.stderr b/src/test/ui/parser/impl-parsing.stderr index 7c2a7937c5da7..755addf14527a 100644 --- a/src/test/ui/parser/impl-parsing.stderr +++ b/src/test/ui/parser/impl-parsing.stderr @@ -22,11 +22,19 @@ error: expected a trait, found type LL | impl ?Sized for .. {} | ^^^^^^ -error: expected `impl`, found `FAIL` - --> $DIR/impl-parsing.rs:9:16 +error: `default` is not followed by an item + --> $DIR/impl-parsing.rs:9:1 | LL | default unsafe FAIL - | ^^^^ expected `impl` + | ^^^^^^^ the `default` qualifier + | + = note: only `fn`, `const`, `type`, or `impl` items may be prefixed by `default` + +error: expected item, found keyword `unsafe` + --> $DIR/impl-parsing.rs:9:9 + | +LL | default unsafe FAIL + | ^^^^^^ expected item -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors diff --git a/src/test/ui/parser/issue-19398.rs b/src/test/ui/parser/issue-19398.rs index 014c930ef8205..46eb320a172f2 100644 --- a/src/test/ui/parser/issue-19398.rs +++ b/src/test/ui/parser/issue-19398.rs @@ -1,6 +1,6 @@ trait T { - //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration extern "Rust" unsafe fn foo(); + //~^ ERROR expected `{`, found keyword `unsafe` } fn main() {} diff --git a/src/test/ui/parser/issue-19398.stderr b/src/test/ui/parser/issue-19398.stderr index b38b39f9bd99f..1da00960adfe4 100644 --- a/src/test/ui/parser/issue-19398.stderr +++ b/src/test/ui/parser/issue-19398.stderr @@ -1,11 +1,13 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-19398.rs:1:10 +error: expected `{`, found keyword `unsafe` + --> $DIR/issue-19398.rs:2:19 | -LL | trait T { - | __________^ -LL | | -LL | | extern "Rust" unsafe fn foo(); - | |____^ missing `fn`, `type`, `const`, or `static` +LL | trait T { + | - while parsing this item list starting here +LL | extern "Rust" unsafe fn foo(); + | ^^^^^^ expected `{` +LL | +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/parser/issue-20711-2.stderr b/src/test/ui/parser/issue-20711-2.stderr index 10ef31584dec1..12b18bbc59416 100644 --- a/src/test/ui/parser/issue-20711-2.stderr +++ b/src/test/ui/parser/issue-20711-2.stderr @@ -1,8 +1,14 @@ error: expected item after attributes --> $DIR/issue-20711-2.rs:6:5 | +LL | impl Foo { + | - while parsing this item list starting here +... LL | #[stable(feature = "rust1", since = "1.0.0")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/parser/issue-20711.stderr b/src/test/ui/parser/issue-20711.stderr index 66768de569418..4af4b22bee292 100644 --- a/src/test/ui/parser/issue-20711.stderr +++ b/src/test/ui/parser/issue-20711.stderr @@ -1,8 +1,13 @@ error: expected item after attributes --> $DIR/issue-20711.rs:4:5 | +LL | impl Foo { + | - while parsing this item list starting here LL | #[stable(feature = "rust1", since = "1.0.0")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/parser/issue-21153.rs b/src/test/ui/parser/issue-21153.rs index 4fe05e6f04155..bf5fdb1f3c6b0 100644 --- a/src/test/ui/parser/issue-21153.rs +++ b/src/test/ui/parser/issue-21153.rs @@ -1,6 +1,6 @@ trait MyTrait: Iterator { - //~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration Item = T; + //~^ ERROR expected one of `!` or `::`, found `=` } fn main() {} diff --git a/src/test/ui/parser/issue-21153.stderr b/src/test/ui/parser/issue-21153.stderr index e9824bd729081..cbfa9ded3c393 100644 --- a/src/test/ui/parser/issue-21153.stderr +++ b/src/test/ui/parser/issue-21153.stderr @@ -1,11 +1,13 @@ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/issue-21153.rs:1:29 +error: expected one of `!` or `::`, found `=` + --> $DIR/issue-21153.rs:2:10 | -LL | trait MyTrait: Iterator { - | _____________________________^ -LL | | -LL | | Item = T; - | |____^ missing `fn`, `type`, `const`, or `static` +LL | trait MyTrait: Iterator { + | - while parsing this item list starting here +LL | Item = T; + | ^ expected one of `!` or `::` +LL | +LL | } + | - the item list ends here error: aborting due to previous error diff --git a/src/test/ui/parser/issue-32446.stderr b/src/test/ui/parser/issue-32446.stderr index d25828da0b979..7515369aaa0b9 100644 --- a/src/test/ui/parser/issue-32446.stderr +++ b/src/test/ui/parser/issue-32446.stderr @@ -1,8 +1,11 @@ -error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `static`, `type`, `unsafe`, `}`, or identifier, found `...` +error: non-item in item list --> $DIR/issue-32446.rs:4:11 | LL | trait T { ... } - | ^^^ expected one of 12 possible tokens + | - ^^^ - item list ends here + | | | + | | non-item starts here + | item list starts here error: aborting due to previous error diff --git a/src/test/ui/parser/issue-41155.rs b/src/test/ui/parser/issue-41155.rs index 3c24d2b447de4..5a7488e6ffcb4 100644 --- a/src/test/ui/parser/issue-41155.rs +++ b/src/test/ui/parser/issue-41155.rs @@ -1,7 +1,7 @@ struct S; impl S { - pub -} //~ ERROR expected one of + pub //~ ERROR visibility `pub` is not followed by an item +} //~ ERROR non-item in item list fn main() {} diff --git a/src/test/ui/parser/issue-41155.stderr b/src/test/ui/parser/issue-41155.stderr index a91ef6c67e89e..8491afae23004 100644 --- a/src/test/ui/parser/issue-41155.stderr +++ b/src/test/ui/parser/issue-41155.stderr @@ -1,10 +1,22 @@ -error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `static`, `type`, `unsafe`, or identifier, found `}` +error: visibility `pub` is not followed by an item + --> $DIR/issue-41155.rs:4:5 + | +LL | pub + | ^^^ the visibility + | + = help: you likely meant to define an item, e.g., `pub fn foo() {}` + +error: non-item in item list --> $DIR/issue-41155.rs:5:1 | +LL | impl S { + | - item list starts here LL | pub - | - expected one of 10 possible tokens LL | } - | ^ unexpected token + | ^ + | | + | non-item starts here + | item list ends here -error: aborting due to previous error +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs new file mode 100644 index 0000000000000..48a679b2d098d --- /dev/null +++ b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs @@ -0,0 +1,44 @@ +fn main() {} + +macro_rules! expand_to_enum { + () => { + enum BadE {} + //~^ ERROR enum is not supported in `trait`s or `impl`s + //~| ERROR enum is not supported in `trait`s or `impl`s + //~| ERROR enum is not supported in `extern` blocks + }; +} + +macro_rules! mac_impl { + ($($i:item)*) => { + struct S; + impl S { $($i)* } + } +} + +mac_impl! { + struct BadS; //~ ERROR struct is not supported in `trait`s or `impl`s + expand_to_enum!(); +} + +macro_rules! mac_trait { + ($($i:item)*) => { + trait T { $($i)* } + } +} + +mac_trait! { + struct BadS; //~ ERROR struct is not supported in `trait`s or `impl`s + expand_to_enum!(); +} + +macro_rules! mac_extern { + ($($i:item)*) => { + extern "C" { $($i)* } + } +} + +mac_extern! { + struct BadS; //~ ERROR struct is not supported in `extern` blocks + expand_to_enum!(); +} diff --git a/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr new file mode 100644 index 0000000000000..bfd27a1a41e13 --- /dev/null +++ b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.stderr @@ -0,0 +1,53 @@ +error: struct is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:20:5 + | +LL | struct BadS; + | ^^^^^^^^^^^^ + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 + | +LL | enum BadE {} + | ^^^^^^^^^ +... +LL | expand_to_enum!(); + | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:31:5 + | +LL | struct BadS; + | ^^^^^^^^^^^^ + +error: enum is not supported in `trait`s or `impl`s + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 + | +LL | enum BadE {} + | ^^^^^^^^^ +... +LL | expand_to_enum!(); + | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: struct is not supported in `extern` blocks + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:42:5 + | +LL | struct BadS; + | ^^^^^^^^^^^^ + +error: enum is not supported in `extern` blocks + --> $DIR/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs:5:9 + | +LL | enum BadE {} + | ^^^^^^^^^ +... +LL | expand_to_enum!(); + | ------------------ in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs new file mode 100644 index 0000000000000..8592f8a728715 --- /dev/null +++ b/src/test/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs @@ -0,0 +1,34 @@ +// check-pass + +fn main() {} + +macro_rules! mac_impl { + ($i:item) => { + struct S; + impl S { $i } + } +} + +mac_impl! { + fn foo() {} +} + +macro_rules! mac_trait { + ($i:item) => { + trait T { $i } + } +} + +mac_trait! { + fn foo() {} +} + +macro_rules! mac_extern { + ($i:item) => { + extern "C" { $i } + } +} + +mac_extern! { + fn foo(); +} diff --git a/src/test/ui/parser/issue-6610.stderr b/src/test/ui/parser/issue-6610.stderr index 22d93bffeaded..a980420894664 100644 --- a/src/test/ui/parser/issue-6610.stderr +++ b/src/test/ui/parser/issue-6610.stderr @@ -2,7 +2,11 @@ error: expected `;` or `{`, found `}` --> $DIR/issue-6610.rs:1:20 | LL | trait Foo { fn a() } - | ^ expected `;` or `{` + | - ^ + | | | + | | expected `;` or `{` + | | the item list ends here + | while parsing this item list starting here error: aborting due to previous error diff --git a/src/test/ui/parser/macro/trait-non-item-macros.rs b/src/test/ui/parser/macro/trait-non-item-macros.rs index 5021886bf9881..97fb564bf6479 100644 --- a/src/test/ui/parser/macro/trait-non-item-macros.rs +++ b/src/test/ui/parser/macro/trait-non-item-macros.rs @@ -1,10 +1,13 @@ macro_rules! bah { - ($a:expr) => ($a) - //~^ ERROR expected one of `async` + ($a:expr) => { + $a + }; //~^ ERROR macro expansion ignores token `2` and any following } -trait bar { +trait Bar { bah!(2); } -fn main() {} +fn main() { + let _recovery_witness: () = 0; //~ ERROR mismatched types +} 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 c76b096a1ebf4..35e5bfe62f5b4 100644 --- a/src/test/ui/parser/macro/trait-non-item-macros.stderr +++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr @@ -1,13 +1,22 @@ -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 +error: macro expansion ignores token `2` and any following + --> $DIR/trait-non-item-macros.rs:3:9 | -LL | ($a:expr) => ($a) - | ^^ expected one of 11 possible tokens +LL | $a + | ^^ ... LL | bah!(2); - | -------- in this macro invocation + | -------- caused by the macro expansion here | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + = note: the usage of `bah!` is likely invalid in trait item context -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/trait-non-item-macros.rs:12:33 + | +LL | let _recovery_witness: () = 0; + | -- ^ expected `()`, found integer + | | + | expected due to this + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs index 748db8983b595..8f46970b1af4d 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs @@ -3,12 +3,11 @@ fn main() {} impl T for () { //~ ERROR cannot find trait `T` in this scope fn foo(&self) {} -//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration -trait T { +trait T { //~ ERROR trait is not supported in `trait`s or `impl`s fn foo(&self); } -pub(crate) struct Bar(); +pub(crate) struct Bar(); //~ ERROR struct is not supported in `trait`s or `impl`s //~ ERROR this file contains an unclosed delimiter diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr index 240be39eacef4..1655a96839569 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr @@ -1,5 +1,5 @@ error: this file contains an unclosed delimiter - --> $DIR/missing-close-brace-in-impl-trait.rs:14:52 + --> $DIR/missing-close-brace-in-impl-trait.rs:13:52 | LL | impl T for () { | - unclosed delimiter @@ -7,15 +7,17 @@ LL | impl T for () { LL | | ^ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/missing-close-brace-in-impl-trait.rs:5:17 +error: trait is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-impl-trait.rs:7:1 | -LL | fn foo(&self) {} - | _________________^ -LL | | -LL | | -LL | | trait T { - | |_ missing `fn`, `type`, `const`, or `static` +LL | trait T { + | ^^^^^^^ + +error: struct is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-impl-trait.rs:11:1 + | +LL | pub(crate) struct Bar(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0405]: cannot find trait `T` in this scope --> $DIR/missing-close-brace-in-impl-trait.rs:3:6 @@ -23,6 +25,6 @@ error[E0405]: cannot find trait `T` in this scope LL | impl T for () { | ^ not found in this scope -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs index 4e8cc6489bc64..b6932deb5c0a6 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs @@ -1,11 +1,11 @@ trait T { -//~^ ERROR `main` function not found in crate `missing_close_brace_in_trait` fn foo(&self); pub(crate) struct Bar(); -//~^ ERROR missing `fn`, `type`, `const`, or `static` for item declaration +//~^ ERROR struct is not supported in `trait`s or `impl`s impl T for Bar { +//~^ ERROR implementation is not supported in `trait`s or `impl`s fn foo(&self) {} } diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr index 54afad5755b15..43a3883357a75 100644 --- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr +++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr @@ -7,24 +7,17 @@ LL | trait T { LL | fn main() {} | ^ -error: missing `fn`, `type`, `const`, or `static` for item declaration - --> $DIR/missing-close-brace-in-trait.rs:5:11 +error: struct is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-trait.rs:4:1 | LL | pub(crate) struct Bar(); - | ^ missing `fn`, `type`, `const`, or `static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0601]: `main` function not found in crate `missing_close_brace_in_trait` - --> $DIR/missing-close-brace-in-trait.rs:1:1 +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/missing-close-brace-in-trait.rs:7:1 | -LL | / trait T { -LL | | -LL | | fn foo(&self); -LL | | -... | -LL | | -LL | | fn main() {} - | |________________________________________________________________^ consider adding a `main` function to `$DIR/missing-close-brace-in-trait.rs` +LL | impl T for Bar { + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr index dc5625bdadea3..04e34dc16a842 100644 --- a/src/test/ui/parser/removed-syntax-static-fn.stderr +++ b/src/test/ui/parser/removed-syntax-static-fn.stderr @@ -7,8 +7,13 @@ LL | static fn f() {} error: expected one of `:`, `;`, or `=`, found `f` --> $DIR/removed-syntax-static-fn.rs:4:15 | +LL | impl S { + | - while parsing this item list starting here LL | static fn f() {} | ^ expected one of `:`, `;`, or `=` +... +LL | } + | - the item list ends here error: missing type for `static` item --> $DIR/removed-syntax-static-fn.rs:4:12 diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr index 54111df342343..6bb946d5b6470 100644 --- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr @@ -2,37 +2,49 @@ error: `default` is only allowed on items in `impl` definitions --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5 | LL | default const A: u8; - | ^^^^^^^^^^^^^^^^^^^^ + | -------^^^^^^^^^^^^^ + | | + | `default` because of this error: `default` is only allowed on items in `impl` definitions --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5 | LL | default const B: u8 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | -------^^^^^^^^^^^^^^^^^ + | | + | `default` because of this error: `default` is only allowed on items in `impl` definitions --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5 | LL | default type D; - | ^^^^^^^^^^^^^^^ + | -------^^^^^^^^ + | | + | `default` because of this error: `default` is only allowed on items in `impl` definitions --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5 | LL | default type C: Ord; - | ^^^^^^^^^^^^^^^^^^^^ + | -------^^^^^^^^^^^^^ + | | + | `default` because of this error: `default` is only allowed on items in `impl` definitions --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5 | LL | default fn f1(); - | ^^^^^^^^^^^^^^^^ + | -------^^^^^^^^^ + | | + | `default` because of this error: `default` is only allowed on items in `impl` definitions --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5 | LL | default fn f2() {} - | ^^^^^^^^^^^^^^^^^^ + | -------^^^^^^^^ + | | + | `default` because of this error: aborting due to 6 previous errors diff --git a/src/test/ui/pub/pub-restricted-error-fn.rs b/src/test/ui/pub/pub-restricted-error-fn.rs index 3f8904fbe79d8..fc1aeae2b0cf4 100644 --- a/src/test/ui/pub/pub-restricted-error-fn.rs +++ b/src/test/ui/pub/pub-restricted-error-fn.rs @@ -1,2 +1,2 @@ -pub(crate) () fn foo() {} //~ unmatched visibility +pub(crate) () fn foo() {} //~ ERROR visibility `pub(crate)` is not followed by an item //~^ ERROR expected item, found `(` diff --git a/src/test/ui/pub/pub-restricted-error-fn.stderr b/src/test/ui/pub/pub-restricted-error-fn.stderr index c0168b02da607..0511a821a7afd 100644 --- a/src/test/ui/pub/pub-restricted-error-fn.stderr +++ b/src/test/ui/pub/pub-restricted-error-fn.stderr @@ -1,8 +1,8 @@ -error: unmatched visibility `pub(crate)` +error: visibility `pub(crate)` is not followed by an item --> $DIR/pub-restricted-error-fn.rs:1:1 | LL | pub(crate) () fn foo() {} - | ^^^^^^^^^^ the unmatched visibility + | ^^^^^^^^^^ the visibility | = help: you likely meant to define an item, e.g., `pub(crate) fn foo() {}` diff --git a/src/test/ui/specialization/defaultimpl/validation.rs b/src/test/ui/specialization/defaultimpl/validation.rs index cf5d6628054ab..26b3f1ec41491 100644 --- a/src/test/ui/specialization/defaultimpl/validation.rs +++ b/src/test/ui/specialization/defaultimpl/validation.rs @@ -4,7 +4,7 @@ struct S; struct Z; -default impl S {} //~ ERROR inherent impls cannot be default +default impl S {} //~ ERROR inherent impls cannot be `default` default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default diff --git a/src/test/ui/specialization/defaultimpl/validation.stderr b/src/test/ui/specialization/defaultimpl/validation.stderr index 14a06c39088d4..03b1ef69ca072 100644 --- a/src/test/ui/specialization/defaultimpl/validation.stderr +++ b/src/test/ui/specialization/defaultimpl/validation.stderr @@ -1,10 +1,12 @@ -error: inherent impls cannot be default +error: inherent impls cannot be `default` --> $DIR/validation.rs:7:1 | LL | default impl S {} - | ^^^^^^^^^^^^^^^^^ + | -------^^^^^^^ + | | + | `default` because of this | - = note: only trait implementations may be annotated with default + = note: only trait implementations may be annotated with `default` error: impls of auto traits cannot be default --> $DIR/validation.rs:9:1