1
Fork 0

Adjust check_no_mangle and check_export_name to warn/error on #[no_mangle]/#[export_name] on trait methods

This commit is contained in:
hyd-dev 2021-08-11 02:41:57 +08:00
parent 0bb2ea653e
commit db138485b1
No known key found for this signature in database
GPG key ID: 74FA7FD5B8DA14B8
5 changed files with 254 additions and 196 deletions

View file

@ -962,6 +962,10 @@ impl CheckAttrVisitor<'tcx> {
} }
} }
fn is_impl_item(&self, hir_id: HirId) -> bool {
matches!(self.tcx.hir().get(hir_id), hir::Node::ImplItem(..))
}
/// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid. /// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid.
fn check_export_name( fn check_export_name(
&self, &self,
@ -971,7 +975,8 @@ impl CheckAttrVisitor<'tcx> {
target: Target, target: Target,
) -> bool { ) -> bool {
match target { match target {
Target::Static | Target::Fn | Target::Method(..) => true, Target::Static | Target::Fn => true,
Target::Method(..) if self.is_impl_item(hir_id) => true,
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[export_name]` attribute with just a lint, because we previously // `#[export_name]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to to be compatible // erroneously allowed it and some crates used it accidentally, to to be compatible
@ -985,9 +990,9 @@ impl CheckAttrVisitor<'tcx> {
.sess .sess
.struct_span_err( .struct_span_err(
attr.span, attr.span,
"attribute should be applied to a function or static", "attribute should be applied to a free function, impl method or static",
) )
.span_label(*span, "not a function or static") .span_label(*span, "not a free function, impl method or static")
.emit(); .emit();
false false
} }
@ -1169,7 +1174,8 @@ impl CheckAttrVisitor<'tcx> {
/// Checks if `#[no_mangle]` is applied to a function or static. /// Checks if `#[no_mangle]` is applied to a function or static.
fn check_no_mangle(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) { fn check_no_mangle(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
match target { match target {
Target::Static | Target::Fn | Target::Method(..) => {} Target::Static | Target::Fn => {}
Target::Method(..) if self.is_impl_item(hir_id) => {}
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[no_mangle]` attribute with just a lint, because we previously // `#[no_mangle]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to to be compatible // erroneously allowed it and some crates used it accidentally, to to be compatible
@ -1181,14 +1187,16 @@ impl CheckAttrVisitor<'tcx> {
// FIXME: #[no_mangle] was previously allowed on non-functions/statics and some // FIXME: #[no_mangle] was previously allowed on non-functions/statics and some
// crates used this, so only emit a warning. // crates used this, so only emit a warning.
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
lint.build("attribute should be applied to a function or static") lint.build(
.warn( "attribute should be applied to a free function, impl method or static",
"this was previously accepted by the compiler but is \ )
being phased out; it will become a hard error in \ .warn(
a future release!", "this was previously accepted by the compiler but is \
) being phased out; it will become a hard error in \
.span_label(*span, "not a function or static") a future release!",
.emit(); )
.span_label(*span, "not a free function, impl method or static")
.emit();
}); });
} }
} }

View file

@ -1,5 +1,5 @@
//~ NOTE: not an `extern crate` item //~ NOTE: not an `extern crate` item
//~^ NOTE: not a function or static //~^ NOTE: not a free function, impl method or static
//~^^ NOTE: not a function or closure //~^^ NOTE: not a function or closure
// This is testing whether various builtin attributes signals an // This is testing whether various builtin attributes signals an
// error or warning when put in "weird" places. // error or warning when put in "weird" places.
@ -25,7 +25,7 @@
#![no_link] #![no_link]
//~^ ERROR: attribute should be applied to an `extern crate` item //~^ ERROR: attribute should be applied to an `extern crate` item
#![export_name = "2200"] #![export_name = "2200"]
//~^ ERROR: attribute should be applied to a function or static //~^ ERROR: attribute should be applied to a free function, impl method or static
#![inline] #![inline]
//~^ ERROR: attribute should be applied to function or closure //~^ ERROR: attribute should be applied to function or closure
#[inline] #[inline]
@ -83,27 +83,37 @@ mod no_link {
} }
#[export_name = "2200"] #[export_name = "2200"]
//~^ ERROR attribute should be applied to a function or static //~^ ERROR attribute should be applied to a free function, impl method or static
mod export_name { mod export_name {
//~^ NOTE not a function or static //~^ NOTE not a free function, impl method or static
mod inner { #![export_name="2200"] } mod inner { #![export_name="2200"] }
//~^ ERROR attribute should be applied to a function or static //~^ ERROR attribute should be applied to a free function, impl method or static
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
#[export_name = "2200"] fn f() { } #[export_name = "2200"] fn f() { }
#[export_name = "2200"] struct S; #[export_name = "2200"] struct S;
//~^ ERROR attribute should be applied to a function or static //~^ ERROR attribute should be applied to a free function, impl method or static
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
#[export_name = "2200"] type T = S; #[export_name = "2200"] type T = S;
//~^ ERROR attribute should be applied to a function or static //~^ ERROR attribute should be applied to a free function, impl method or static
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
#[export_name = "2200"] impl S { } #[export_name = "2200"] impl S { }
//~^ ERROR attribute should be applied to a function or static //~^ ERROR attribute should be applied to a free function, impl method or static
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
trait Tr {
#[export_name = "2200"] fn foo();
//~^ ERROR attribute should be applied to a free function, impl method or static
//~| NOTE not a free function, impl method or static
#[export_name = "2200"] fn bar() {}
//~^ ERROR attribute should be applied to a free function, impl method or static
//~| NOTE not a free function, impl method or static
}
} }
#[start] #[start]

View file

@ -17,31 +17,31 @@ LL | #[inline = "2100"] fn f() { }
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
error: `start` attribute can only be used on functions error: `start` attribute can only be used on functions
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:1 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:1
| |
LL | #[start] LL | #[start]
| ^^^^^^^^ | ^^^^^^^^
error: `start` attribute can only be used on functions error: `start` attribute can only be used on functions
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:112:17 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:122:17
| |
LL | mod inner { #![start] } LL | mod inner { #![start] }
| ^^^^^^^^^ | ^^^^^^^^^
error: `start` attribute can only be used on functions error: `start` attribute can only be used on functions
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:117:5 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:5
| |
LL | #[start] struct S; LL | #[start] struct S;
| ^^^^^^^^ | ^^^^^^^^
error: `start` attribute can only be used on functions error: `start` attribute can only be used on functions
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:120:5 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:130:5
| |
LL | #[start] type T = S; LL | #[start] type T = S;
| ^^^^^^^^ | ^^^^^^^^
error: `start` attribute can only be used on functions error: `start` attribute can only be used on functions
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:5 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:5
| |
LL | #[start] impl S { } LL | #[start] impl S { }
| ^^^^^^^^ | ^^^^^^^^
@ -76,7 +76,7 @@ LL | |
LL | | } LL | | }
| |_- not an `extern crate` item | |_- not an `extern crate` item
error: attribute should be applied to a function or static error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:85:1 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:85:1
| |
LL | #[export_name = "2200"] LL | #[export_name = "2200"]
@ -87,9 +87,9 @@ LL | |
LL | | LL | |
LL | | mod inner { #![export_name="2200"] } LL | | mod inner { #![export_name="2200"] }
... | ... |
LL | | LL | | }
LL | | } LL | | }
| |_- not a function or static | |_- not a free function, impl method or static
error: attribute should be applied to an `extern crate` item error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1
@ -97,7 +97,7 @@ error: attribute should be applied to an `extern crate` item
LL | #![no_link] LL | #![no_link]
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: attribute should be applied to a function or static error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1
| |
LL | #![export_name = "2200"] LL | #![export_name = "2200"]
@ -199,31 +199,43 @@ error: attribute should be applied to an `extern crate` item
LL | #[no_link] impl S { } LL | #[no_link] impl S { }
| ^^^^^^^^^^ ---------- not an `extern crate` item | ^^^^^^^^^^ ---------- not an `extern crate` item
error: attribute should be applied to a function or static error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:90:17 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:90:17
| |
LL | mod inner { #![export_name="2200"] } LL | mod inner { #![export_name="2200"] }
| ------------^^^^^^^^^^^^^^^^^^^^^^-- not a function or static | ------------^^^^^^^^^^^^^^^^^^^^^^-- not a free function, impl method or static
error: attribute should be applied to a function or static error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5
| |
LL | #[export_name = "2200"] struct S; LL | #[export_name = "2200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static | ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a free function, impl method or static
error: attribute should be applied to a function or static error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:100:5 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:100:5
| |
LL | #[export_name = "2200"] type T = S; LL | #[export_name = "2200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static | ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a free function, impl method or static
error: attribute should be applied to a function or static error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:104:5 --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:104:5
| |
LL | #[export_name = "2200"] impl S { } LL | #[export_name = "2200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static | ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a free function, impl method or static
error: aborting due to 32 previous errors error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:9
|
LL | #[export_name = "2200"] fn foo();
| ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a free function, impl method or static
error: attribute should be applied to a free function, impl method or static
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:9
|
LL | #[export_name = "2200"] fn bar() {}
| ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a free function, impl method or static
error: aborting due to 34 previous errors
Some errors have detailed explanations: E0518, E0658. Some errors have detailed explanations: E0518, E0658.
For more information about an error, try `rustc --explain E0518`. For more information about an error, try `rustc --explain E0518`.

View file

@ -295,31 +295,43 @@ mod automatically_derived {
} }
#[no_mangle] #[no_mangle]
//~^ WARN attribute should be applied to a function or static [unused_attributes] //~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
mod no_mangle { mod no_mangle {
//~^ NOTE not a function or static //~^ NOTE not a free function, impl method or static
mod inner { #![no_mangle] } mod inner { #![no_mangle] }
//~^ WARN attribute should be applied to a function or static [unused_attributes] //~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
#[no_mangle] fn f() { } #[no_mangle] fn f() { }
#[no_mangle] struct S; #[no_mangle] struct S;
//~^ WARN attribute should be applied to a function or static [unused_attributes] //~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
#[no_mangle] type T = S; #[no_mangle] type T = S;
//~^ WARN attribute should be applied to a function or static [unused_attributes] //~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
#[no_mangle] impl S { } #[no_mangle] impl S { }
//~^ WARN attribute should be applied to a function or static [unused_attributes] //~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| NOTE not a function or static //~| NOTE not a free function, impl method or static
trait Tr {
#[no_mangle] fn foo();
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| NOTE not a free function, impl method or static
#[no_mangle] fn bar() {}
//~^ WARN attribute should be applied to a free function, impl method or static [unused_attributes]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| NOTE not a free function, impl method or static
}
} }
#[should_panic] #[should_panic]