Enforce crate level attributes checks
This commit is contained in:
parent
6ec2474622
commit
3641a37455
10 changed files with 377 additions and 372 deletions
|
@ -19,8 +19,8 @@ use rustc_hir::{
|
|||
use rustc_hir::{MethodKind, Target};
|
||||
use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
pub(crate) fn target_from_impl_item<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -821,6 +821,33 @@ fn is_c_like_enum(item: &Item<'_>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
|
||||
const ATTRS_TO_CHECK: &[Symbol] = &[
|
||||
sym::macro_export,
|
||||
sym::repr,
|
||||
sym::path,
|
||||
sym::automatically_derived,
|
||||
sym::start,
|
||||
sym::main,
|
||||
];
|
||||
|
||||
for attr in attrs {
|
||||
for attr_to_check in ATTRS_TO_CHECK {
|
||||
if tcx.sess.check_name(attr, *attr_to_check) {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
&format!(
|
||||
"`{}` attribute cannot be used at crate level",
|
||||
attr_to_check.to_ident_string()
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
||||
tcx.hir()
|
||||
.visit_item_likes_in_module(module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor());
|
||||
|
@ -828,10 +855,11 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
|
|||
CheckAttrVisitor { tcx }.check_attributes(
|
||||
CRATE_HIR_ID,
|
||||
tcx.hir().krate_attrs(),
|
||||
&tcx.hir().span(CRATE_HIR_ID),
|
||||
&DUMMY_SP,
|
||||
Target::Mod,
|
||||
None,
|
||||
);
|
||||
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,8 +78,6 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(LocalDefId, EntryFnType)
|
|||
// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
|
||||
// (with `ast::Item`), so make sure to keep them in sync.
|
||||
fn entry_point_type(sess: &Session, item: &Item<'_>, at_root: bool) -> EntryPointType {
|
||||
match item.kind {
|
||||
ItemKind::Fn(..) => {
|
||||
if sess.contains_name(&item.attrs, sym::start) {
|
||||
EntryPointType::Start
|
||||
} else if sess.contains_name(&item.attrs, sym::main) {
|
||||
|
@ -94,13 +92,24 @@ fn entry_point_type(sess: &Session, item: &Item<'_>, at_root: bool) -> EntryPoin
|
|||
} else {
|
||||
EntryPointType::None
|
||||
}
|
||||
}
|
||||
_ => EntryPointType::None,
|
||||
}
|
||||
}
|
||||
|
||||
fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
|
||||
sess.struct_span_err(span, &format!("`{}` attribute can only be used on functions", attr))
|
||||
.emit();
|
||||
}
|
||||
|
||||
fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
|
||||
match entry_point_type(&ctxt.session, item, at_root) {
|
||||
EntryPointType::None => (),
|
||||
_ if !matches!(item.kind, ItemKind::Fn(..)) => {
|
||||
if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::start) {
|
||||
throw_attr_err(&ctxt.session, attr.span, "start");
|
||||
}
|
||||
if let Some(attr) = ctxt.session.find_by_name(item.attrs, sym::main) {
|
||||
throw_attr_err(&ctxt.session, attr.span, "main");
|
||||
}
|
||||
}
|
||||
EntryPointType::MainNamed => {
|
||||
if ctxt.main_fn.is_none() {
|
||||
ctxt.main_fn = Some((item.hir_id, item.span));
|
||||
|
@ -137,7 +146,6 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
|
|||
.emit();
|
||||
}
|
||||
}
|
||||
EntryPointType::None => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ declare_lint! {
|
|||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![macro_export]
|
||||
/// #![ignore]
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#![feature(doc_alias)]
|
||||
|
||||
#![doc(alias = "shouldn't work!")] //~ ERROR
|
||||
#![doc(alias = "crate-level-not-working")] //~ ERROR
|
||||
|
||||
#[doc(alias = "shouldn't work!")] //~ ERROR
|
||||
pub fn foo() {}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
error: '\'' character isn't allowed in `#[doc(alias = "...")]`
|
||||
--> $DIR/doc-alias-crate-level.rs:5:7
|
||||
|
|
||||
LL | #[doc(alias = "shouldn't work!")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute
|
||||
--> $DIR/doc-alias-crate-level.rs:3:8
|
||||
|
|
||||
LL | #![doc(alias = "shouldn't work!")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #![doc(alias = "crate-level-not-working")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: `#![doc(alias = "...")]` isn't allowed as a crate level attribute
|
||||
error: '\'' character isn't allowed in `#[doc(alias = "...")]`
|
||||
--> $DIR/doc-alias-crate-level.rs:7:8
|
||||
|
|
||||
LL | #![doc(alias = "shouldn't work!")]
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
//~ NOTE: not an `extern crate` item
|
||||
//~^ NOTE: not a function or static
|
||||
//~^^ NOTE: not a function or closure
|
||||
// This is testing whether various builtin attributes signals an
|
||||
// error or warning when put in "weird" places.
|
||||
//
|
||||
|
@ -7,22 +10,19 @@
|
|||
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![deny(unused_attributes)]
|
||||
//~^ NOTE not a function or static
|
||||
//~^^ NOTE the lint level is defined here
|
||||
//~^^^ NOTE not an `extern crate` item
|
||||
//~^^^^ NOTE not a function or static
|
||||
//~^^^^^ NOTE not a function or closure
|
||||
|
||||
#![macro_export]
|
||||
//~^ ERROR: `macro_export` attribute cannot be used at crate level
|
||||
#![main]
|
||||
//~^ ERROR: `main` attribute cannot be used at crate level
|
||||
#![start]
|
||||
//~^ ERROR: `start` attribute cannot be used at crate level
|
||||
#![repr()]
|
||||
//~^ ERROR: `repr` attribute cannot be used at crate level
|
||||
#![path = "3800"]
|
||||
//~^ ERROR: `path` attribute cannot be used at crate level
|
||||
#![automatically_derived]
|
||||
//~^ ERROR: `automatically_derived` attribute cannot be used at crate level
|
||||
#![no_mangle]
|
||||
//~^ ERROR attribute should be applied to a function or static
|
||||
//~^^ WARN
|
||||
#![no_link]
|
||||
//~^ ERROR: attribute should be applied to an `extern crate` item
|
||||
#![export_name = "2200"]
|
||||
|
@ -107,4 +107,40 @@ mod export_name {
|
|||
//~| NOTE not a function or static
|
||||
}
|
||||
|
||||
#[main]
|
||||
//~^ ERROR: `main` attribute can only be used on functions
|
||||
mod main {
|
||||
mod inner { #![main] }
|
||||
//~^ ERROR: `main` attribute can only be used on functions
|
||||
|
||||
// for `fn f()` case, see feature-gate-main.rs
|
||||
|
||||
#[main] struct S;
|
||||
//~^ ERROR: `main` attribute can only be used on functions
|
||||
|
||||
#[main] type T = S;
|
||||
//~^ ERROR: `main` attribute can only be used on functions
|
||||
|
||||
#[main] impl S { }
|
||||
//~^ ERROR: `main` attribute can only be used on functions
|
||||
}
|
||||
|
||||
#[start]
|
||||
//~^ ERROR: `start` attribute can only be used on functions
|
||||
mod start {
|
||||
mod inner { #![start] }
|
||||
//~^ ERROR: `start` attribute can only be used on functions
|
||||
|
||||
// for `fn f()` case, see feature-gate-start.rs
|
||||
|
||||
#[start] struct S;
|
||||
//~^ ERROR: `start` attribute can only be used on functions
|
||||
|
||||
#[start] type T = S;
|
||||
//~^ ERROR: `start` attribute can only be used on functions
|
||||
|
||||
#[start] impl S { }
|
||||
//~^ ERROR: `start` attribute can only be used on functions
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -8,6 +8,66 @@ LL | #[inline = "2100"] fn f() { }
|
|||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
|
||||
|
||||
error: `main` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:110:1
|
||||
|
|
||||
LL | #[main]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `main` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:17
|
||||
|
|
||||
LL | mod inner { #![main] }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `main` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:118:5
|
||||
|
|
||||
LL | #[main] struct S;
|
||||
| ^^^^^^^
|
||||
|
||||
error: `main` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:5
|
||||
|
|
||||
LL | #[main] type T = S;
|
||||
| ^^^^^^^
|
||||
|
||||
error: `main` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:124:5
|
||||
|
|
||||
LL | #[main] impl S { }
|
||||
| ^^^^^^^
|
||||
|
||||
error: `start` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:128:1
|
||||
|
|
||||
LL | #[start]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `start` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:17
|
||||
|
|
||||
LL | mod inner { #![start] }
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: `start` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:136:5
|
||||
|
|
||||
LL | #[start] struct S;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `start` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:139:5
|
||||
|
|
||||
LL | #[start] type T = S;
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `start` attribute can only be used on functions
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:142:5
|
||||
|
|
||||
LL | #[start] impl S { }
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0518]: attribute should be applied to function or closure
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1
|
||||
|
|
||||
|
@ -53,72 +113,59 @@ LL | |
|
|||
LL | | }
|
||||
| |_- not a function or static
|
||||
|
||||
error: attribute should be applied to a function or static
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1
|
||||
|
|
||||
LL | / #![deny(unused_attributes)]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | #![no_mangle]
|
||||
| | ^^^^^^^^^^^^^
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________- not a function or static
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:10:9
|
||||
|
|
||||
LL | #![deny(unused_attributes)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
error: attribute should be applied to an `extern crate` item
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:26:1
|
||||
|
|
||||
LL | / #![deny(unused_attributes)]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | #![no_link]
|
||||
| | ^^^^^^^^^^^
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________- not an `extern crate` item
|
||||
LL | #![no_link]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: attribute should be applied to a function or static
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:28:1
|
||||
|
|
||||
LL | / #![deny(unused_attributes)]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | #![export_name = "2200"]
|
||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________- not a function or static
|
||||
LL | #![export_name = "2200"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0518]: attribute should be applied to function or closure
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:30:1
|
||||
|
|
||||
LL | / #![deny(unused_attributes)]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | #![inline]
|
||||
| | ^^^^^^^^^^
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |____________- not a function or closure
|
||||
LL | #![inline]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: `macro_export` attribute cannot be used at crate level
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:13:1
|
||||
|
|
||||
LL | #![macro_export]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `main` attribute cannot be used at crate level
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:15:1
|
||||
|
|
||||
LL | #![main]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `start` attribute cannot be used at crate level
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1
|
||||
|
|
||||
LL | #![start]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: `repr` attribute cannot be used at crate level
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:19:1
|
||||
|
|
||||
LL | #![repr()]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: `path` attribute cannot be used at crate level
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1
|
||||
|
|
||||
LL | #![path = "3800"]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `automatically_derived` attribute cannot be used at crate level
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1
|
||||
|
|
||||
LL | #![automatically_derived]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0518]: attribute should be applied to function or closure
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:17
|
||||
|
@ -198,6 +245,6 @@ error: attribute should be applied to a function or static
|
|||
LL | #[export_name = "2200"] impl S { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static
|
||||
|
||||
error: aborting due to 21 previous errors
|
||||
error: aborting due to 36 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0518`.
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
//~ NOTE not a function
|
||||
//~^ NOTE not a foreign function or static
|
||||
//~^^ NOTE not a function or static
|
||||
// This test enumerates as many compiler-builtin ungated attributes as
|
||||
// possible (that is, all the mutually compatible ones), and checks
|
||||
// that we get "expected" (*) warnings for each in the various weird
|
||||
|
@ -34,9 +37,6 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
#![feature(test, plugin_registrar)]
|
||||
//~^ NOTE not a function
|
||||
//~^^ NOTE not a foreign function or static
|
||||
//~^^^ NOTE not a function or static
|
||||
#![warn(unused_attributes, unknown_lints)]
|
||||
//~^ NOTE the lint level is defined here
|
||||
//~| NOTE the lint level is defined here
|
||||
|
@ -249,42 +249,6 @@ mod plugin_registrar {
|
|||
//~| HELP may be removed in a future compiler version
|
||||
}
|
||||
|
||||
#[main]
|
||||
//~^ WARN unused attribute
|
||||
mod main {
|
||||
mod inner { #![main] }
|
||||
//~^ WARN unused attribute
|
||||
|
||||
// for `fn f()` case, see feature-gate-main.rs
|
||||
|
||||
#[main] struct S;
|
||||
//~^ WARN unused attribute
|
||||
|
||||
#[main] type T = S;
|
||||
//~^ WARN unused attribute
|
||||
|
||||
#[main] impl S { }
|
||||
//~^ WARN unused attribute
|
||||
}
|
||||
|
||||
#[start]
|
||||
//~^ WARN unused attribute
|
||||
mod start {
|
||||
mod inner { #![start] }
|
||||
//~^ WARN unused attribute
|
||||
|
||||
// for `fn f()` case, see feature-gate-start.rs
|
||||
|
||||
#[start] struct S;
|
||||
//~^ WARN unused attribute
|
||||
|
||||
#[start] type T = S;
|
||||
//~^ WARN unused attribute
|
||||
|
||||
#[start] impl S { }
|
||||
//~^ WARN unused attribute
|
||||
}
|
||||
|
||||
// At time of unit test authorship, if compiling without `--test` then
|
||||
// non-crate-level #[test] attributes seem to be ignored.
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue