Feature gate non-builtin attributes in inner attribute position

This commit is contained in:
Vadim Petrochenkov 2018-09-10 01:54:51 +03:00
parent 2d4e34ca8b
commit 615eaba14b
8 changed files with 48 additions and 12 deletions

View File

@ -1074,6 +1074,21 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
self.collect(kind, InvocationKind::Attr { attr, traits, item }) self.collect(kind, InvocationKind::Attr { attr, traits, item })
} }
fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
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. /// If `item` is an attr invocation, remove and return the macro attribute and derive traits.
fn classify_item<T>(&mut self, mut item: T) -> (Option<ast::Attribute>, Vec<Path>, T) fn classify_item<T>(&mut self, mut item: T) -> (Option<ast::Attribute>, Vec<Path>, T)
where T: HasAttrs, where T: HasAttrs,
@ -1087,7 +1102,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
return attrs; return attrs;
} }
attr = find_attr_invoc(&mut attrs); attr = self.find_attr_invoc(&mut attrs);
traits = collect_derives(&mut self.cx, &mut attrs); traits = collect_derives(&mut self.cx, &mut attrs);
attrs attrs
}); });
@ -1108,7 +1123,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
return attrs; return attrs;
} }
attr = find_attr_invoc(&mut attrs); attr = self.find_attr_invoc(&mut attrs);
attrs attrs
}); });
@ -1145,12 +1160,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
} }
} }
pub fn find_attr_invoc(attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
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> { impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> { fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
let mut expr = self.cfg.configure_expr(expr).into_inner(); 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_expr = proc_macro_expr,
fn proc_macro_non_items = proc_macro_non_items, 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. // A Marker adds the given mark to the syntax context.

View File

@ -518,6 +518,9 @@ declare_features! (
// #![test_runner] // #![test_runner]
// #[test_case] // #[test_case]
(active, custom_test_frameworks, "1.30.0", Some(50297), None), (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! ( declare_features! (

View File

@ -11,6 +11,8 @@
// aux-build:attribute-with-error.rs // aux-build:attribute-with-error.rs
// ignore-stage1 // ignore-stage1
#![feature(custom_inner_attributes)]
extern crate attribute_with_error; extern crate attribute_with_error;
use attribute_with_error::foo; use attribute_with_error::foo;

View File

@ -13,6 +13,8 @@
// FIXME: https://github.com/rust-lang/rust/issues/41430 // FIXME: https://github.com/rust-lang/rust/issues/41430
// This is a temporary regression test for the ICE reported in #41211 // This is a temporary regression test for the ICE reported in #41211
#![feature(custom_inner_attributes)]
#![emit_unchanged] #![emit_unchanged]
//~^ ERROR attribute `emit_unchanged` is currently unknown to the compiler //~^ ERROR attribute `emit_unchanged` is currently unknown to the compiler
extern crate issue_41211; extern crate issue_41211;

View File

@ -22,7 +22,7 @@ extern crate proc_macro_gates as foo;
use foo::*; use foo::*;
fn _test_inner() { fn _test_inner() {
#![a] // OK #![a] //~ ERROR: non-builtin inner attributes are unstable
} }
#[a] //~ ERROR: custom attributes cannot be applied to modules #[a] //~ ERROR: custom attributes cannot be applied to modules
@ -30,6 +30,7 @@ mod _test2 {}
mod _test2_inner { mod _test2_inner {
#![a] //~ ERROR: custom attributes cannot be applied to modules #![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 #[a = y] //~ ERROR: must only be followed by a delimiter token

View File

@ -20,6 +20,8 @@
// See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is // See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is
// handled in "weird places" when `--test` is passed. // handled in "weird places" when `--test` is passed.
#![feature(custom_inner_attributes)]
#![bench = "4100"] #![bench = "4100"]
fn main() { } fn main() { }

View File

@ -8,7 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// gate-test-custom_inner_attributes
#[foo] //~ ERROR is currently unknown to the compiler #[foo] //~ ERROR is currently unknown to the compiler
mod foo { mod foo {
#![foo] //~ ERROR is currently unknown to the compiler #![foo] //~ ERROR is currently unknown to the compiler
//~| ERROR non-builtin inner attributes are unstable
} }

View File

@ -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) 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 LL | #[foo] //~ ERROR is currently unknown to the compiler
| ^^^ | ^^^
| |
= help: add #![feature(custom_attribute)] to the crate attributes to enable = 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) 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 LL | #![foo] //~ ERROR is currently unknown to the compiler
| ^^^ | ^^^
| |
= help: add #![feature(custom_attribute)] to the crate attributes to enable = 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`. For more information about this error, try `rustc --explain E0658`.