Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature gate rustc attributes harder #62133

Merged
merged 2 commits into from
Jul 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_fn_union)]
#![feature(custom_inner_attributes)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![feature(extern_types)]
Expand Down
31 changes: 17 additions & 14 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{
feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
};
use syntax::feature_gate::{feature_err, emit_feature_err, is_builtin_attr_name};
use syntax::feature_gate::{AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES};
use syntax::symbol::{Symbol, kw, sym};
use syntax::visit::Visitor;
use syntax::util::lev_distance::find_best_match_for_name;
Expand Down Expand Up @@ -298,12 +297,25 @@ impl<'a> Resolver<'a> {
let res = self.resolve_macro_to_res_inner(path, kind, parent_scope, trace, force);

// Report errors and enforce feature gates for the resolved macro.
let features = self.session.features_untracked();
if res != Err(Determinacy::Undetermined) {
// Do not report duplicated errors on every undetermined resolution.
for segment in &path.segments {
if let Some(args) = &segment.args {
self.session.span_err(args.span(), "generic arguments in macro path");
}
if kind == MacroKind::Attr && !features.rustc_attrs &&
segment.ident.as_str().starts_with("rustc") {
let msg = "attributes starting with `rustc` are \
reserved for use by the `rustc` compiler";
emit_feature_err(
&self.session.parse_sess,
sym::rustc_attrs,
segment.ident.span,
GateIssue::Language,
msg,
);
}
}
}

Expand All @@ -320,24 +332,15 @@ impl<'a> Resolver<'a> {
}
Res::NonMacroAttr(attr_kind) => {
if kind == MacroKind::Attr {
let features = self.session.features_untracked();
if attr_kind == NonMacroAttrKind::Custom {
assert!(path.segments.len() == 1);
let name = path.segments[0].ident.as_str();
if name.starts_with("rustc_") {
if !features.rustc_attrs {
let msg = "unless otherwise specified, attributes with the prefix \
`rustc_` are reserved for internal compiler diagnostics";
self.report_unknown_attribute(path.span, &name, msg,
sym::rustc_attrs);
}
} else if !features.custom_attribute {
if !features.custom_attribute {
let msg = format!("The attribute `{}` is currently unknown to the \
compiler and may have meaning added to it in the \
future", path);
self.report_unknown_attribute(
path.span,
&name,
&path.segments[0].ident.as_str(),
&msg,
sym::custom_attribute,
);
Expand Down
4 changes: 1 addition & 3 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1525,9 +1525,7 @@ impl<'feat> ExpansionConfig<'feat> {
}

fn enable_custom_inner_attributes(&self) -> bool {
self.features.map_or(false, |features| {
features.custom_inner_attributes || features.custom_attribute || features.rustc_attrs
})
self.features.map_or(false, |features| features.custom_inner_attributes)
}
}

Expand Down
60 changes: 47 additions & 13 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
attribute is just used for rustc unit \
tests and will never be stable",
cfg_fn!(rustc_attrs))),
(sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"the `#[rustc_dump_env_program_clauses]` \
attribute is just used for rustc unit \
tests and will never be stable",
cfg_fn!(rustc_attrs))),
(sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"the `#[rustc_object_lifetime_default]` \
attribute is just used for rustc unit \
tests and will never be stable",
cfg_fn!(rustc_attrs))),
(sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"the `#[rustc_test_marker]` attribute \
Expand Down Expand Up @@ -1351,6 +1363,26 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
"internal implementation detail",
cfg_fn!(rustc_attrs))),

(sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"internal implementation detail",
cfg_fn!(rustc_attrs))),

(sym::rustc_doc_only_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"internal implementation detail",
cfg_fn!(rustc_attrs))),

(sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"internal implementation detail",
cfg_fn!(rustc_attrs))),

(sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable,
sym::rustc_attrs,
"internal implementation detail",
cfg_fn!(rustc_attrs))),

(sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
sym::rustc_attrs,
"used by the test suite",
Expand Down Expand Up @@ -1637,6 +1669,14 @@ impl<'a> Context<'a> {
}
debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
return;
} else {
for segment in &attr.path.segments {
if segment.ident.as_str().starts_with("rustc") {
let msg = "attributes starting with `rustc` are \
reserved for use by the `rustc` compiler";
gate_feature!(self, rustc_attrs, segment.ident.span, msg);
}
}
}
for &(n, ty) in self.plugin_attributes {
if attr.path == n {
Expand All @@ -1647,19 +1687,13 @@ impl<'a> Context<'a> {
return;
}
}
if !attr::is_known(attr) {
if attr.name_or_empty().as_str().starts_with("rustc_") {
let msg = "unless otherwise specified, attributes with the prefix `rustc_` \
are reserved for internal compiler diagnostics";
gate_feature!(self, rustc_attrs, attr.span, msg);
} else if !is_macro {
// Only run the custom attribute lint during regular feature gate
// checking. Macro gating runs before the plugin attributes are
// registered, so we skip this in that case.
let msg = format!("The attribute `{}` is currently unknown to the compiler and \
may have meaning added to it in the future", attr.path);
gate_feature!(self, custom_attribute, attr.span, &msg);
}
if !is_macro && !attr::is_known(attr) {
// Only run the custom attribute lint during regular feature gate
// checking. Macro gating runs before the plugin attributes are
// registered, so we skip this in that case.
let msg = format!("The attribute `{}` is currently unknown to the compiler and \
may have meaning added to it in the future", attr.path);
gate_feature!(self, custom_attribute, attr.span, &msg);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/test/run-pass-fulldeps/issue-15778-pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
// ignore-stage1
// compile-flags: -D crate-not-okay

#![feature(plugin, rustc_attrs)]
#![feature(plugin, custom_attribute, custom_inner_attributes, rustc_attrs)]

#![plugin(lint_for_crate)]
#![rustc_crate_okay]
#![rustc_crate_blue]
#![rustc_crate_red]
#![rustc_crate_grey]
#![rustc_crate_green]

pub fn main() { }
fn main() {}
52 changes: 0 additions & 52 deletions src/test/run-pass/attr-on-generic-formals.rs

This file was deleted.

6 changes: 2 additions & 4 deletions src/test/ui/attributes/attrs-with-no-formal-in-generics-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

struct RefIntPair<'a, 'b>(&'a u32, &'b u32);

impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
//~^ ERROR trailing attribute after generic parameter
}

fn main() {

}
fn main() {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: trailing attribute after generic parameter
--> $DIR/attrs-with-no-formal-in-generics-1.rs:9:25
--> $DIR/attrs-with-no-formal-in-generics-1.rs:9:29
|
LL | impl<#[rustc_1] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
| ^^^^^^^ attributes must go before parameters
LL | impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> {
| ^^^^^^^ attributes must go before parameters

error: aborting due to previous error

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

struct RefAny<'a, T>(&'a T);

impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {}
impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {}
//~^ ERROR trailing attribute after generic parameter

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error: trailing attribute after generic parameter
--> $DIR/attrs-with-no-formal-in-generics-2.rs:9:35
--> $DIR/attrs-with-no-formal-in-generics-2.rs:9:43
|
LL | impl<#[rustc_1] 'a, #[rustc_2] T, #[oops]> RefAny<'a, T> {}
| ^^^^^^^ attributes must go before parameters
LL | impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {}
| ^^^^^^^ attributes must go before parameters

error: aborting due to previous error

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const fn error(_: fn()) {}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_allow_const_fn_ptr]
//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved
//~^ ERROR internal implementation detail
const fn compiles(_: fn()) {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
--> $DIR/allow_const_fn_ptr_feature_gate.rs:7:3
error[E0658]: internal implementation detail
--> $DIR/allow_const_fn_ptr_feature_gate.rs:7:1
|
LL | #[rustc_allow_const_fn_ptr]
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add #![feature(rustc_attrs)] to the crate attributes to enable
Expand Down
21 changes: 19 additions & 2 deletions src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.

#[rustc_foo]
//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved
#![feature(decl_macro)]

mod rustc { pub macro unknown() {} }
mod unknown { pub macro rustc() {} }

#[rustc::unknown]
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
//~| ERROR macro `rustc::unknown` may not be used in attributes
fn f() {}

#[unknown::rustc]
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
//~| ERROR macro `unknown::rustc` may not be used in attributes
fn g() {}

#[rustc_dummy]
//~^ ERROR used by the test suite
#[rustc_unknown]
//~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
//~| ERROR attribute `rustc_unknown` is currently unknown
fn main() {}
58 changes: 53 additions & 5 deletions src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,60 @@
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics
--> $DIR/feature-gate-rustc-attrs.rs:3:3
error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
--> $DIR/feature-gate-rustc-attrs.rs:8:3
|
LL | #[rustc_foo]
| ^^^^^^^^^
LL | #[rustc::unknown]
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

error: aborting due to previous error
error: macro `rustc::unknown` may not be used in attributes
--> $DIR/feature-gate-rustc-attrs.rs:8:1
|
LL | #[rustc::unknown]
| ^^^^^^^^^^^^^^^^^

error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
--> $DIR/feature-gate-rustc-attrs.rs:13:12
|
LL | #[unknown::rustc]
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

error: macro `unknown::rustc` may not be used in attributes
--> $DIR/feature-gate-rustc-attrs.rs:13:1
|
LL | #[unknown::rustc]
| ^^^^^^^^^^^^^^^^^

error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
--> $DIR/feature-gate-rustc-attrs.rs:20:3
|
LL | #[rustc_unknown]
| ^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

error[E0658]: The attribute `rustc_unknown` is currently unknown to the compiler and may have meaning added to it in the future
--> $DIR/feature-gate-rustc-attrs.rs:20:3
|
LL | #[rustc_unknown]
| ^^^^^^^^^^^^^
|
= 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]: used by the test suite
--> $DIR/feature-gate-rustc-attrs.rs:18:1
|
LL | #[rustc_dummy]
| ^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0658`.
Loading