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 1 commit
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
Next Next commit
Make sure #[rustc_doc_only_macro] and other rustc attributes are re…
…gistered
  • Loading branch information
petrochenkov committed Jun 30, 2019
commit 0ffb6438a6b19135cdfd3461dbd9efaf0011a149
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
12 changes: 2 additions & 10 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,21 323,13 @@ impl<'a> Resolver<'a> {
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
52 changes: 39 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 @@ -1647,19 1679,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)]

#![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
4 changes: 2 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,6 @@
// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.

#[rustc_foo]
//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved
#[rustc_dummy]
//~^ ERROR used by the test suite

fn main() {}
8 changes: 4 additions & 4 deletions src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
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/feature-gate-rustc-attrs.rs:3:3
error[E0658]: used by the test suite
--> $DIR/feature-gate-rustc-attrs.rs:3:1
|
LL | #[rustc_foo]
| ^^^^^^^^^
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
Expand Down
44 changes: 19 additions & 25 deletions src/test/ui/generic/generic-param-attrs.rs
Original file line number Diff line number Diff line change
@@ -1,44 1,38 @@
// This test previously ensured that attributes on formals in generic parameter
// lists are rejected without a feature gate.
//
// (We are prefixing all tested features with `rustc_`, to ensure that
// the attributes themselves won't be rejected by the compiler when
// using `rustc_attrs` feature. There is a separate compile-fail/ test
// ensuring that the attribute feature-gating works in this context.)

// compile-pass

#![feature(rustc_attrs)]
#![allow(dead_code)]

struct StLt<#[rustc_lt_struct] 'a>(&'a u32);
struct StTy<#[rustc_ty_struct] I>(I);
enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B }
enum EnTy<#[rustc_ty_enum] J> { A(J), B }
trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); }
type TyLt<#[rustc_lt_type] 'd> = &'d u32;
type TyTy<#[rustc_ty_type] L> = (L, );

impl<#[rustc_lt_inherent] 'e> StLt<'e> { }
impl<#[rustc_ty_inherent] M> StTy<M> { }
impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> {

struct StLt<#[rustc_dummy] 'a>(&'a u32);
struct StTy<#[rustc_dummy] I>(I);
enum EnLt<#[rustc_dummy] 'b> { A(&'b u32), B }
enum EnTy<#[rustc_dummy] J> { A(J), B }
trait TrLt<#[rustc_dummy] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
trait TrTy<#[rustc_dummy] K> { fn foo(&self, _: K); }
type TyLt<#[rustc_dummy] 'd> = &'d u32;
type TyTy<#[rustc_dummy] L> = (L, );

impl<#[rustc_dummy] 'e> StLt<'e> { }
impl<#[rustc_dummy] M> StTy<M> { }
impl<#[rustc_dummy] 'f> TrLt<'f> for StLt<'f> {
fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
}
impl<#[rustc_ty_impl_for] N> TrTy<N> for StTy<N> {
impl<#[rustc_dummy] N> TrTy<N> for StTy<N> {
fn foo(&self, _: N) { }
}

fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
fn f_ty<#[rustc_ty_fn] O>(_: O) { }
fn f_lt<#[rustc_dummy] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
fn f_ty<#[rustc_dummy] O>(_: O) { }

impl<I> StTy<I> {
fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
fn m_ty<#[rustc_ty_meth] P>(_: P) { }
fn m_lt<#[rustc_dummy] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
fn m_ty<#[rustc_dummy] P>(_: P) { }
}

fn hof_lt<Q>(_: Q)
where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
where Q: for <#[rustc_dummy] 'i> Fn(&'i [u32]) -> &'i u32
{}

fn main() {}
7 changes: 1 addition & 6 deletions src/test/ui/nll/ty-outlives/projection-implied-bounds.rs
Original file line number Diff line number Diff line change
@@ -1,10 1,7 @@
// compile-flags:-Zborrowck=mir -Zverbose

// Test that we can deduce when projections like `T::Item` outlive the
// function body. Test that this does not imply that `T: 'a` holds.

#![allow(warnings)]
#![feature(rustc_attrs)]
// compile-flags:-Zborrowck=mir -Zverbose

use std::cell::Cell;

Expand All @@ -18,7 15,6 @@ where
f(&value, Cell::new(&n));
}

#[rustc_errors]
fn generic1<T: Iterator>(value: T) {
// No error here:
twice(value, |value_ref, item| invoke1(item));
Expand All @@ -30,7 26,6 @@ where
{
}

#[rustc_errors]
fn generic2<T: Iterator>(value: T) {
twice(value, |value_ref, item| invoke2(value_ref, item));
//~^ ERROR the parameter type `T` may not live long enough
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/projection-implied-bounds.rs:35:18
--> $DIR/projection-implied-bounds.rs:30:18
|
LL | twice(value, |value_ref, item| invoke2(value_ref, item));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 0 additions & 4 deletions src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 4,6 @@
// Test that we assume that universal types like `T` outlive the
// function body.

#![allow(warnings)]
#![feature(rustc_attrs)]

use std::cell::Cell;

fn twice<F, T>(value: T, mut f: F)
Expand All @@ -17,7 14,6 @@ where
f(Cell::new(&value));
}

#[rustc_errors]
fn generic<T>(value: T) {
// No error here:
twice(value, |r| invoke(r));
Expand Down
Loading