diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index d02aab54127a6..7f806ed71f293 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -179,6 +179,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } fn visit_generic_param(&mut self, param: &'a GenericParam) { + if param.ident.as_str() == "placeholder" { + return self.visit_macro_invoc(param.id); + } let name = param.ident.as_interned_str(); let def_path_data = match param.kind { GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name), diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ee11228654b6f..022100e1cdafe 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1070,4 +1070,11 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { } visit::walk_attribute(self, attr); } + + fn visit_generic_param(&mut self, param: &'a ast::GenericParam) { + if param.ident.as_str() == "placeholder" { + self.visit_invoc(param.id); + } + visit::walk_generic_param(self, param); + } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3760cabcd898a..0ebdcab616b28 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -15,7 +15,7 @@ use syntax::ast::{self, Ident, ItemKind}; use syntax::attr::{self, StabilityLevel}; use syntax::ext::base::{self, Indeterminate}; use syntax::ext::base::{MacroKind, SyntaxExtension}; -use syntax::ext::expand::{AstFragment, Invocation, InvocationKind}; +use syntax::ext::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind}; use syntax::ext::hygiene::{self, ExpnId, ExpnInfo, ExpnKind}; use syntax::ext::tt::macro_rules; use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name}; @@ -236,6 +236,16 @@ impl<'a> base::Resolver for Resolver<'a> { normal_module_def_id); } + match invoc.fragment_kind { + AstFragmentKind::GenericParams => { + if let Res::Def(..) = res { + self.session.span_err(span, "expected an inert attribute, found an attribute macro"); + return Ok(Some(self.dummy_ext(kind))); + } + } + _ => {} + } + Ok(Some(ext)) } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 1ab367f73c1b3..ad7c0a1967512 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -241,10 +241,6 @@ impl<'a> StripUnconfigured<'a> { items.flat_map_in_place(|item| self.configure(item)); } - pub fn configure_generic_params(&mut self, params: &mut Vec) { - params.flat_map_in_place(|param| self.configure(param)); - } - fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) { match vdata { ast::VariantData::Struct(fields, ..) | ast::VariantData::Tuple(fields, _) => diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 926c9e88efe15..c979c0fd174bb 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -34,6 +34,8 @@ pub enum Annotatable { ForeignItem(P), Stmt(P), Expr(P), + // New + GenericParam(ast::GenericParam), } impl HasAttrs for Annotatable { @@ -45,6 +47,7 @@ impl HasAttrs for Annotatable { Annotatable::ForeignItem(ref foreign_item) => &foreign_item.attrs, Annotatable::Stmt(ref stmt) => stmt.attrs(), Annotatable::Expr(ref expr) => &expr.attrs, + Annotatable::GenericParam(ref param) => ¶m.attrs, } } @@ -56,6 +59,7 @@ impl HasAttrs for Annotatable { Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f), Annotatable::Stmt(stmt) => stmt.visit_attrs(f), Annotatable::Expr(expr) => expr.visit_attrs(f), + Annotatable::GenericParam(param) => param.visit_attrs(f), } } } @@ -69,6 +73,7 @@ impl Annotatable { Annotatable::ForeignItem(ref foreign_item) => foreign_item.span, Annotatable::Stmt(ref stmt) => stmt.span, Annotatable::Expr(ref expr) => expr.span, + Annotatable::GenericParam(..) => DUMMY_SP, } } @@ -124,6 +129,13 @@ impl Annotatable { } } + pub fn expect_generic_param(self) -> ast::GenericParam { + match self { + Annotatable::GenericParam(i) => i, + _ => panic!("expected generic parameter") + } + } + pub fn derive_allowed(&self) -> bool { match *self { Annotatable::Item(ref item) => match item.node { @@ -315,6 +327,10 @@ pub trait MacResult { fn make_ty(self: Box) -> Option> { None } + + fn make_generic_params(self: Box) -> Option> { + None + } } macro_rules! make_MacEager { @@ -515,6 +531,14 @@ impl MacResult for DummyResult { fn make_ty(self: Box) -> Option> { Some(DummyResult::raw_ty(self.span, self.is_error)) } + + fn make_generic_params(self: Box) -> Option> { + if self.expr_only { + None + } else { + Some(SmallVec::new()) + } + } } /// A syntax extension kind. diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ae72f1fd108ed..b2063048bed1f 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -155,6 +155,10 @@ ast_fragments! { ForeignItems(SmallVec<[ast::ForeignItem; 1]>) { "foreign item"; many fn flat_map_foreign_item; fn visit_foreign_item; fn make_foreign_items; } + // New + GenericParams(SmallVec<[ast::GenericParam; 1]>) { + "generic parameter"; many fn flat_map_generic_param; fn visit_generic_param; fn make_generic_params; + } } impl AstFragmentKind { @@ -181,6 +185,8 @@ impl AstFragmentKind { ), AstFragmentKind::OptExpr => AstFragment::OptExpr(items.next().map(Annotatable::expect_expr)), + AstFragmentKind::GenericParams => + AstFragment::GenericParams(items.map(Annotatable::expect_generic_param).collect()), AstFragmentKind::Pat | AstFragmentKind::Ty => panic!("patterns and types aren't annotatable"), } @@ -189,7 +195,7 @@ impl AstFragmentKind { pub struct Invocation { pub kind: InvocationKind, - fragment_kind: AstFragmentKind, + pub fragment_kind: AstFragmentKind, pub expansion_data: ExpansionData, } @@ -479,6 +485,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Annotatable::Expr(mut expr) => { Annotatable::Expr({ cfg.visit_expr(&mut expr); expr }) } + Annotatable::GenericParam(param) => { + Annotatable::GenericParam(cfg.flat_map_generic_param(param).pop().unwrap()) + } } } @@ -540,6 +549,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()), Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), Annotatable::Expr(expr) => token::NtExpr(expr), + Annotatable::GenericParam(..) => panic!("unexpected annotatable") })), DUMMY_SP).into(); let input = self.extract_proc_macro_attr_input(attr.tokens, span); let tok_result = expander.expand(self.cx, span, input, item_tok); @@ -623,6 +633,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { Annotatable::Expr(_) if self.cx.ecfg.proc_macro_hygiene() => return, Annotatable::Stmt(_) => ("statements", sym::proc_macro_hygiene), Annotatable::Expr(_) => ("expressions", sym::proc_macro_hygiene), + Annotatable::GenericParam(..) => panic!("unexpected annotatable"), }; emit_feature_err( self.cx.parse_sess, @@ -679,6 +690,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { AstFragmentKind::TraitItems => return, AstFragmentKind::ImplItems => return, AstFragmentKind::ForeignItems => return, + AstFragmentKind::GenericParams => panic!("unexpected AST fragment kind"), }; if self.cx.ecfg.proc_macro_hygiene() { return @@ -767,6 +779,7 @@ impl<'a> Parser<'a> { }, AstFragmentKind::Ty => AstFragment::Ty(self.parse_ty()?), AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat(None)?), + AstFragmentKind::GenericParams => panic!("unexpected AST fragment kind"), }) } @@ -1220,9 +1233,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } } - fn visit_generic_params(&mut self, params: &mut Vec) { - self.cfg.configure_generic_params(params); - noop_visit_generic_params(params, self); + fn flat_map_generic_param(&mut self, param: ast::GenericParam) -> SmallVec<[ast::GenericParam; 1]> { + let mut param = configure!(self, param); + + let (attr, traits, after_derive) = self.classify_item(&mut param); + if attr.is_some() || !traits.is_empty() { + return self.collect_attr(attr, traits, Annotatable::GenericParam(param), + AstFragmentKind::GenericParams, after_derive) + .make_generic_params(); + } + + noop_flat_map_generic_param(param, self) } fn visit_attribute(&mut self, at: &mut ast::Attribute) { diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 17d8bf3ab175f..7e71920b281bf 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -66,6 +66,15 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ThinVec::new())); ast::Stmt { id, span, node: ast::StmtKind::Mac(mac) } }]), + AstFragmentKind::GenericParams => AstFragment::GenericParams(smallvec![{ + ast::GenericParam { + id, + ident: ast::Ident::from_str("placeholder"), + attrs: Default::default(), + bounds: Default::default(), + kind: ast::GenericParamKind::Lifetime, + } + }]) } } @@ -164,6 +173,13 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { stmts } + fn flat_map_generic_param(&mut self, param: ast::GenericParam) -> SmallVec<[ast::GenericParam; 1]> { + if param.ident.as_str() == "placeholder" { + return self.remove(param.id).make_generic_params() + } + noop_flat_map_generic_param(param, self) + } + fn visit_pat(&mut self, pat: &mut P) { match pat.node { ast::PatKind::Mac(_) => *pat = self.remove(pat.id).make_pat(), diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index dc656222fbc10..d1ae7ae636711 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -242,12 +242,8 @@ pub trait MutVisitor: Sized { noop_visit_variant_data(vdata, self); } - fn visit_generic_param(&mut self, param: &mut GenericParam) { - noop_visit_generic_param(param, self); - } - - fn visit_generic_params(&mut self, params: &mut Vec) { - noop_visit_generic_params(params, self); + fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { + noop_flat_map_generic_param(param, self) } fn visit_tt(&mut self, tt: &mut TokenTree) { @@ -421,7 +417,7 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { } TyKind::BareFn(bft) => { let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut(); - vis.visit_generic_params(generic_params); + generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_fn_decl(decl); } TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)), @@ -702,8 +698,8 @@ pub fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) } } -pub fn noop_visit_generic_param(param: &mut GenericParam, vis: &mut T) { - let GenericParam { id, ident, attrs, bounds, kind } = param; +pub fn noop_flat_map_generic_param(mut param: GenericParam, vis: &mut T) -> SmallVec<[GenericParam; 1]> { + let GenericParam { id, ident, attrs, bounds, kind } = &mut param; vis.visit_id(id); vis.visit_ident(ident); visit_thin_attrs(attrs, vis); @@ -717,10 +713,8 @@ pub fn noop_visit_generic_param(param: &mut GenericParam, vis: &m vis.visit_ty(ty); } } -} -pub fn noop_visit_generic_params(params: &mut Vec, vis: &mut T){ - visit_vec(params, |param| vis.visit_generic_param(param)); + smallvec![param] } pub fn noop_visit_label(Label { ident }: &mut Label, vis: &mut T) { @@ -734,7 +728,7 @@ fn noop_visit_lifetime(Lifetime { id, ident }: &mut Lifetime, vis pub fn noop_visit_generics(generics: &mut Generics, vis: &mut T) { let Generics { params, where_clause, span } = generics; - vis.visit_generic_params(params); + params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_where_clause(where_clause); vis.visit_span(span); } @@ -750,7 +744,7 @@ pub fn noop_visit_where_predicate(pred: &mut WherePredicate, vis: WherePredicate::BoundPredicate(bp) => { let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; vis.visit_span(span); - vis.visit_generic_params(bound_generic_params); + bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_ty(bounded_ty); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } @@ -788,7 +782,7 @@ pub fn noop_visit_trait_ref(TraitRef { path, ref_id }: &mut Trait pub fn noop_visit_poly_trait_ref(p: &mut PolyTraitRef, vis: &mut T) { let PolyTraitRef { bound_generic_params, trait_ref, span } = p; - vis.visit_generic_params(bound_generic_params); + bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_trait_ref(trait_ref); vis.visit_span(span); } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 98465d75e4680..7816e23c755aa 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -53,6 +53,7 @@ impl MultiItemModifier for ProcMacroDerive { applied to a struct, enum, or union"); return Vec::new() } + Annotatable::GenericParam(..) => panic!("unexpected annotatable") }; match item.node { ItemKind::Struct(..) | diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.rs b/src/test/ui/conditional-compilation/cfg-generic-params.rs index d80d3ea7b7fe9..f0d003da80456 100644 --- a/src/test/ui/conditional-compilation/cfg-generic-params.rs +++ b/src/test/ui/conditional-compilation/cfg-generic-params.rs @@ -16,21 +16,21 @@ struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy; //~^ ERROR only lifetime parameters can be used in this context fn f_lt_no<#[cfg_attr(no, unknown)] 'a>() {} // OK -fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} //~ ERROR attribute `unknown` is currently unknown +fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} //~ ERROR cannot find attribute macro `unknown` in this scope fn f_ty_no<#[cfg_attr(no, unknown)] T>() {} // OK -fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} //~ ERROR attribute `unknown` is currently unknown +fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} //~ ERROR cannot find attribute macro `unknown` in this scope type FnNo = for<#[cfg_attr(no, unknown)] 'a> fn(); // OK type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); -//~^ ERROR attribute `unknown` is currently unknown +//~^ ERROR cannot find attribute macro `unknown` in this scope type PolyNo = dyn for<#[cfg_attr(no, unknown)] 'a> Copy; // OK type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; -//~^ ERROR attribute `unknown` is currently unknown +//~^ ERROR cannot find attribute macro `unknown` in this scope struct WhereNo where for<#[cfg_attr(no, unknown)] 'a> u8: Copy; // OK struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; -//~^ ERROR attribute `unknown` is currently unknown +//~^ ERROR cannot find attribute macro `unknown` in this scope fn main() { f_lt::<'static>(); diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.stderr b/src/test/ui/conditional-compilation/cfg-generic-params.stderr index 1f9731fcfbefb..a1f814d2d4714 100644 --- a/src/test/ui/conditional-compilation/cfg-generic-params.stderr +++ b/src/test/ui/conditional-compilation/cfg-generic-params.stderr @@ -16,51 +16,35 @@ error: only lifetime parameters can be used in this context LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy; | ^ -error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/cfg-generic-params.rs:19:29 - | -LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} - | ^^^^^^^ +error: cannot find attribute macro `unknown` in this scope + --> $DIR/cfg-generic-params.rs:32:43 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; + | ^^^^^^^ -error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/cfg-generic-params.rs:21:29 - | -LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} - | ^^^^^^^ +error: cannot find attribute macro `unknown` in this scope + --> $DIR/cfg-generic-params.rs:28:40 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; + | ^^^^^^^ -error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future +error: cannot find attribute macro `unknown` in this scope --> $DIR/cfg-generic-params.rs:24:34 | LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable -error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/cfg-generic-params.rs:28:40 - | -LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; - | ^^^^^^^ +error: cannot find attribute macro `unknown` in this scope + --> $DIR/cfg-generic-params.rs:21:29 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} + | ^^^^^^^ -error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/cfg-generic-params.rs:32:43 - | -LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; - | ^^^^^^^ +error: cannot find attribute macro `unknown` in this scope + --> $DIR/cfg-generic-params.rs:19:29 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} + | ^^^^^^^ error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs index 8fe11cb02a021..51b5bf5387b5f 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs @@ -4,54 +4,54 @@ // gate-test-custom_attribute struct StLt<#[lt_struct] 'a>(&'a u32); -//~^ ERROR the attribute `lt_struct` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `lt_struct` in this scope struct StTy<#[ty_struct] I>(I); -//~^ ERROR the attribute `ty_struct` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `ty_struct` in this scope enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } -//~^ ERROR the attribute `lt_enum` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `lt_enum` in this scope enum EnTy<#[ty_enum] J> { A(J), B } -//~^ ERROR the attribute `ty_enum` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `ty_enum` in this scope trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -//~^ ERROR the attribute `lt_trait` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `lt_trait` in this scope trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } -//~^ ERROR the attribute `ty_trait` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `ty_trait` in this scope type TyLt<#[lt_type] 'd> = &'d u32; -//~^ ERROR the attribute `lt_type` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `lt_type` in this scope type TyTy<#[ty_type] L> = (L, ); -//~^ ERROR the attribute `ty_type` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `ty_type` in this scope impl<#[lt_inherent] 'e> StLt<'e> { } -//~^ ERROR the attribute `lt_inherent` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `lt_inherent` in this scope impl<#[ty_inherent] M> StTy { } -//~^ ERROR the attribute `ty_inherent` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `ty_inherent` in this scope impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - //~^ ERROR the attribute `lt_impl_for` is currently unknown to the compiler + //~^ ERROR cannot find attribute macro `lt_impl_for` in this scope fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } } impl<#[ty_impl_for] N> TrTy for StTy { - //~^ ERROR the attribute `ty_impl_for` is currently unknown to the compiler + //~^ ERROR cannot find attribute macro `ty_impl_for` in this scope fn foo(&self, _: N) { } } fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -//~^ ERROR the attribute `lt_fn` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `lt_fn` in this scope fn f_ty<#[ty_fn] O>(_: O) { } -//~^ ERROR the attribute `ty_fn` is currently unknown to the compiler +//~^ ERROR cannot find attribute macro `ty_fn` in this scope impl StTy { fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - //~^ ERROR the attribute `lt_meth` is currently unknown to the compiler + //~^ ERROR cannot find attribute macro `lt_meth` in this scope fn m_ty<#[ty_meth] P>(_: P) { } - //~^ ERROR the attribute `ty_meth` is currently unknown to the compiler + //~^ ERROR cannot find attribute macro `ty_meth` in this scope } fn hof_lt(_: Q) where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - //~^ ERROR the attribute `lt_hof` is currently unknown to the compiler + //~^ ERROR cannot find attribute macro `lt_hof` in this scope { } diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr index 15e0c41b90637..9250616127f3d 100644 --- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr +++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr @@ -1,156 +1,104 @@ -error[E0658]: the attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:6:13 +error: cannot find attribute macro `lt_hof` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:53:21 | -LL | struct StLt<#[lt_struct] 'a>(&'a u32); - | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 + | ^^^^^^ -error[E0658]: the attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:8:13 +error: cannot find attribute macro `ty_meth` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:48:15 | -LL | struct StTy<#[ty_struct] I>(I); - | ^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | fn m_ty<#[ty_meth] P>(_: P) { } + | ^^^^^^^ -error[E0658]: the attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:11:11 +error: cannot find attribute macro `lt_meth` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:46:15 | -LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } - | ^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } + | ^^^^^^^ -error[E0658]: the attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:13:11 - | -LL | enum EnTy<#[ty_enum] J> { A(J), B } - | ^^^^^^^^^^ +error: cannot find attribute macro `ty_fn` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:42:11 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | fn f_ty<#[ty_fn] O>(_: O) { } + | ^^^^^ -error[E0658]: the attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:16:12 +error: cannot find attribute macro `lt_fn` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:40:11 | -LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } - | ^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } + | ^^^^^ -error[E0658]: the attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:18:12 - | -LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } - | ^^^^^^^^^^^ +error: cannot find attribute macro `ty_impl_for` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:35:8 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | impl<#[ty_impl_for] N> TrTy for StTy { + | ^^^^^^^^^^^ -error[E0658]: the attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:21:11 - | -LL | type TyLt<#[lt_type] 'd> = &'d u32; - | ^^^^^^^^^^ +error: cannot find attribute macro `lt_impl_for` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:31:8 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { + | ^^^^^^^^^^^ -error[E0658]: the attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:23:11 - | -LL | type TyTy<#[ty_type] L> = (L, ); - | ^^^^^^^^^^ +error: cannot find attribute macro `ty_inherent` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:28:8 | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | impl<#[ty_inherent] M> StTy { } + | ^^^^^^^^^^^ -error[E0658]: the attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:26:6 +error: cannot find attribute macro `lt_inherent` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:26:8 | LL | impl<#[lt_inherent] 'e> StLt<'e> { } - | ^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable + | ^^^^^^^^^^^ -error[E0658]: the attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:28:6 +error: cannot find attribute macro `ty_type` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:23:13 | -LL | impl<#[ty_inherent] M> StTy { } - | ^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | type TyTy<#[ty_type] L> = (L, ); + | ^^^^^^^ -error[E0658]: the attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:31:6 +error: cannot find attribute macro `lt_type` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:21:13 | -LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - | ^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | type TyLt<#[lt_type] 'd> = &'d u32; + | ^^^^^^^ -error[E0658]: the attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:35:6 +error: cannot find attribute macro `ty_trait` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:18:14 | -LL | impl<#[ty_impl_for] N> TrTy for StTy { - | ^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } + | ^^^^^^^^ -error[E0658]: the attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:40:9 +error: cannot find attribute macro `lt_trait` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:16:14 | -LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } - | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } + | ^^^^^^^^ -error[E0658]: the attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:42:9 +error: cannot find attribute macro `ty_enum` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:13:13 | -LL | fn f_ty<#[ty_fn] O>(_: O) { } - | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | enum EnTy<#[ty_enum] J> { A(J), B } + | ^^^^^^^ -error[E0658]: the attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:46:13 +error: cannot find attribute macro `lt_enum` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:11:13 | -LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - | ^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } + | ^^^^^^^ -error[E0658]: the attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:48:13 +error: cannot find attribute macro `ty_struct` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:8:15 | -LL | fn m_ty<#[ty_meth] P>(_: P) { } - | ^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | struct StTy<#[ty_struct] I>(I); + | ^^^^^^^^^ -error[E0658]: the attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future - --> $DIR/feature-gate-custom_attribute2.rs:53:19 +error: cannot find attribute macro `lt_struct` in this scope + --> $DIR/feature-gate-custom_attribute2.rs:6:15 | -LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable +LL | struct StLt<#[lt_struct] 'a>(&'a u32); + | ^^^^^^^^^ error: aborting due to 17 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/issues/issue-49934.rs b/src/test/ui/issues/issue-49934.rs index e75381afae9ae..f4c68c1b03043 100644 --- a/src/test/ui/issues/issue-49934.rs +++ b/src/test/ui/issues/issue-49934.rs @@ -1,11 +1,10 @@ -// build-pass (FIXME(62277): could be check-pass?) - #![feature(stmt_expr_attributes)] -#![warn(unused_attributes)] //~ NOTE lint level defined here +#![warn(unused_attributes)] // NOTE lint level defined here -fn foo<#[derive(Debug)] T>() { //~ WARN unused attribute +fn foo<#[derive(Debug)] T>() { //~ ERROR `derive` may only be applied to structs, enums and unions + //~^ ERROR expected an inert attribute, found an attribute macro match 0 { - #[derive(Debug)] //~ WARN unused attribute + #[derive(Debug)] // WARN unused attribute _ => (), } } @@ -23,20 +22,20 @@ fn main() { println!("Hello, world!"); // fold_stmt (Semi) - #[derive(Debug)] //~ WARN unused attribute + #[derive(Debug)] // WARN unused attribute "Hello, world!"; // fold_stmt (Local) - #[derive(Debug)] //~ WARN unused attribute + #[derive(Debug)] // WARN unused attribute let _ = "Hello, world!"; // visit_expr let _ = #[derive(Debug)] "Hello, world!"; - //~^ WARN unused attribute + //^ WARN unused attribute let _ = [ // filter_map_expr - #[derive(Debug)] //~ WARN unused attribute + #[derive(Debug)] // WARN unused attribute "Hello, world!" ]; } diff --git a/src/test/ui/issues/issue-49934.stderr b/src/test/ui/issues/issue-49934.stderr index 6ca751a47c47d..fe543d23ed117 100644 --- a/src/test/ui/issues/issue-49934.stderr +++ b/src/test/ui/issues/issue-49934.stderr @@ -1,50 +1,22 @@ warning: `#[derive]` does nothing on macro invocations - --> $DIR/issue-49934.rs:20:5 + --> $DIR/issue-49934.rs:19:5 | LL | #[derive(Debug)] | ^^^^^^^^^^^^^^^^ | = note: this may become a hard error in a future release -warning: unused attribute - --> $DIR/issue-49934.rs:6:8 +error: `derive` may only be applied to structs, enums and unions + --> $DIR/issue-49934.rs:4:8 | LL | fn foo<#[derive(Debug)] T>() { | ^^^^^^^^^^^^^^^^ - | -note: lint level defined here - --> $DIR/issue-49934.rs:4:9 - | -LL | #![warn(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ - -warning: unused attribute - --> $DIR/issue-49934.rs:8:9 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ - -warning: unused attribute - --> $DIR/issue-49934.rs:26:5 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ -warning: unused attribute - --> $DIR/issue-49934.rs:30:5 +error: expected an inert attribute, found an attribute macro + --> $DIR/issue-49934.rs:4:17 | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ - -warning: unused attribute - --> $DIR/issue-49934.rs:34:13 - | -LL | let _ = #[derive(Debug)] "Hello, world!"; - | ^^^^^^^^^^^^^^^^ +LL | fn foo<#[derive(Debug)] T>() { + | ^^^^^ -warning: unused attribute - --> $DIR/issue-49934.rs:39:9 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors diff --git a/src/test/ui/proc-macro/proc-macro-gates2.rs b/src/test/ui/proc-macro/proc-macro-gates2.rs index 35d7fc8042a3d..7b1f091336e36 100644 --- a/src/test/ui/proc-macro/proc-macro-gates2.rs +++ b/src/test/ui/proc-macro/proc-macro-gates2.rs @@ -10,7 +10,7 @@ extern crate test_macros; // should either require a feature gate or not be allowed on stable. fn _test6<#[empty_attr] T>() {} -//~^ ERROR: unknown to the compiler +//~^ ERROR: expected an inert attribute, found an attribute macro fn _test7() { match 1 { diff --git a/src/test/ui/proc-macro/proc-macro-gates2.stderr b/src/test/ui/proc-macro/proc-macro-gates2.stderr index a7f6f8bfb13d6..2e66bc0f474c2 100644 --- a/src/test/ui/proc-macro/proc-macro-gates2.stderr +++ b/src/test/ui/proc-macro/proc-macro-gates2.stderr @@ -1,11 +1,8 @@ -error[E0658]: the attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future +error: expected an inert attribute, found an attribute macro --> $DIR/proc-macro-gates2.rs:12:11 | LL | fn _test6<#[empty_attr] T>() {} | ^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/29642 - = help: add `#![feature(custom_attribute)]` to the crate attributes to enable error[E0658]: the attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future --> $DIR/proc-macro-gates2.rs:17:9