diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 3bb19121ee308..7b4e1814a33d7 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1074,6 +1074,21 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { self.collect(kind, InvocationKind::Attr { attr, traits, item }) } + fn find_attr_invoc(&self, attrs: &mut Vec) -> Option { + let attr = attrs.iter() + .position(|a| !attr::is_known(a) && !is_builtin_attr(a)) + .map(|i| attrs.remove(i)); + if let Some(attr) = &attr { + if !self.cx.ecfg.enable_custom_inner_attributes() && + attr.style == ast::AttrStyle::Inner && attr.path != "test" { + emit_feature_err(&self.cx.parse_sess, "custom_inner_attributes", + attr.span, GateIssue::Language, + "non-builtin inner attributes are unstable"); + } + } + attr + } + /// If `item` is an attr invocation, remove and return the macro attribute and derive traits. fn classify_item(&mut self, mut item: T) -> (Option, Vec, T) where T: HasAttrs, @@ -1087,7 +1102,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { return attrs; } - attr = find_attr_invoc(&mut attrs); + attr = self.find_attr_invoc(&mut attrs); traits = collect_derives(&mut self.cx, &mut attrs); attrs }); @@ -1108,7 +1123,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { return attrs; } - attr = find_attr_invoc(&mut attrs); + attr = self.find_attr_invoc(&mut attrs); attrs }); @@ -1145,12 +1160,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { } } -pub fn find_attr_invoc(attrs: &mut Vec) -> Option { - attrs.iter() - .position(|a| !attr::is_known(a) && !is_builtin_attr(a)) - .map(|i| attrs.remove(i)) -} - impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { fn fold_expr(&mut self, expr: P) -> P { let mut expr = self.cfg.configure_expr(expr).into_inner(); @@ -1582,6 +1591,12 @@ impl<'feat> ExpansionConfig<'feat> { fn proc_macro_expr = proc_macro_expr, fn proc_macro_non_items = proc_macro_non_items, } + + fn enable_custom_inner_attributes(&self) -> bool { + self.features.map_or(false, |features| { + features.custom_inner_attributes || features.custom_attribute || features.rustc_attrs + }) + } } // A Marker adds the given mark to the syntax context. diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e912482cf586e..3e880bb6cf633 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -518,6 +518,9 @@ declare_features! ( // #![test_runner] // #[test_case] (active, custom_test_frameworks, "1.30.0", Some(50297), None), + + // Non-builtin attributes in inner attribute position + (active, custom_inner_attributes, "1.30.0", Some(38356), None), ); declare_features! ( diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs b/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs index 3cb565c1ede38..cf2522be922e3 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/attribute-with-error.rs @@ -11,6 +11,8 @@ // aux-build:attribute-with-error.rs // ignore-stage1 +#![feature(custom_inner_attributes)] + extern crate attribute_with_error; use attribute_with_error::foo; diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs index 52d7afb26adba..e0922c452b5fb 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs @@ -13,6 +13,8 @@ // FIXME: https://github.com/rust-lang/rust/issues/41430 // This is a temporary regression test for the ICE reported in #41211 +#![feature(custom_inner_attributes)] + #![emit_unchanged] //~^ ERROR attribute `emit_unchanged` is currently unknown to the compiler extern crate issue_41211; diff --git a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs index 5cf65103ba3eb..c07e6e31d6287 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/proc-macro-gates.rs @@ -22,7 +22,7 @@ extern crate proc_macro_gates as foo; use foo::*; fn _test_inner() { - #![a] // OK + #![a] //~ ERROR: non-builtin inner attributes are unstable } #[a] //~ ERROR: custom attributes cannot be applied to modules @@ -30,6 +30,7 @@ mod _test2 {} mod _test2_inner { #![a] //~ ERROR: custom attributes cannot be applied to modules + //~| ERROR: non-builtin inner attributes are unstable } #[a = y] //~ ERROR: must only be followed by a delimiter token diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs b/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs index 6c22679933874..d0adcf4025f7f 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs @@ -20,6 +20,8 @@ // See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is // handled in "weird places" when `--test` is passed. +#![feature(custom_inner_attributes)] + #![bench = "4100"] fn main() { } diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs index c6cdb8b6db7cf..fbe1535caaed2 100644 --- a/src/test/ui/span/issue-36530.rs +++ b/src/test/ui/span/issue-36530.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-custom_inner_attributes + #[foo] //~ ERROR is currently unknown to the compiler mod foo { #![foo] //~ ERROR is currently unknown to the compiler + //~| ERROR non-builtin inner attributes are unstable } diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr index e7dd8e7aa8fa0..78d81ad049306 100644 --- a/src/test/ui/span/issue-36530.stderr +++ b/src/test/ui/span/issue-36530.stderr @@ -1,19 +1,27 @@ error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/issue-36530.rs:11:3 + --> $DIR/issue-36530.rs:13:3 | LL | #[foo] //~ ERROR is currently unknown to the compiler | ^^^ | = help: add #![feature(custom_attribute)] to the crate attributes to enable +error[E0658]: non-builtin inner attributes are unstable (see issue #38356) + --> $DIR/issue-36530.rs:15:5 + | +LL | #![foo] //~ ERROR is currently unknown to the compiler + | ^^^^^^^ + | + = help: add #![feature(custom_inner_attributes)] to the crate attributes to enable + error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/issue-36530.rs:13:8 + --> $DIR/issue-36530.rs:15:8 | LL | #![foo] //~ ERROR is currently unknown to the compiler | ^^^ | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`.