Add validation for link
attribute position.
This commit is contained in:
parent
f7bb8e3677
commit
59d4bae018
3 changed files with 264 additions and 161 deletions
|
@ -126,6 +126,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
// lint-only checks
|
// lint-only checks
|
||||||
match attr.name_or_empty() {
|
match attr.name_or_empty() {
|
||||||
sym::cold => self.check_cold(hir_id, attr, span, target),
|
sym::cold => self.check_cold(hir_id, attr, span, target),
|
||||||
|
sym::link => self.check_link(hir_id, attr, span, target),
|
||||||
sym::link_name => self.check_link_name(hir_id, attr, span, target),
|
sym::link_name => self.check_link_name(hir_id, attr, span, target),
|
||||||
sym::link_section => self.check_link_section(hir_id, attr, span, target),
|
sym::link_section => self.check_link_section(hir_id, attr, span, target),
|
||||||
sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target),
|
sym::no_mangle => self.check_no_mangle(hir_id, attr, span, target),
|
||||||
|
@ -1140,6 +1141,26 @@ impl CheckAttrVisitor<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if `#[link]` is applied to an item other than a foreign module.
|
||||||
|
fn check_link(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
|
||||||
|
match target {
|
||||||
|
Target::ForeignMod => {}
|
||||||
|
_ => {
|
||||||
|
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||||
|
let mut diag = lint.build("attribute should be applied to an `extern` block");
|
||||||
|
diag.warn(
|
||||||
|
"this was previously accepted by the compiler but is \
|
||||||
|
being phased out; it will become a hard error in \
|
||||||
|
a future release!",
|
||||||
|
);
|
||||||
|
|
||||||
|
diag.span_label(*span, "not an `extern` block");
|
||||||
|
diag.emit();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
|
/// Checks if `#[link_name]` is applied to an item other than a foreign function or static.
|
||||||
fn check_link_name(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
|
fn check_link_name(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) {
|
||||||
match target {
|
match target {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//~ NOTE not a function
|
//~ NOTE not a function
|
||||||
//~^ NOTE not a foreign function or static
|
//~| NOTE not a foreign function or static
|
||||||
//~^^ NOTE not a function or static
|
//~| NOTE not a function or static
|
||||||
|
//~| NOTE not an `extern` block
|
||||||
// This test enumerates as many compiler-builtin ungated attributes as
|
// This test enumerates as many compiler-builtin ungated attributes as
|
||||||
// possible (that is, all the mutually compatible ones), and checks
|
// possible (that is, all the mutually compatible ones), and checks
|
||||||
// that we get "expected" (*) warnings for each in the various weird
|
// that we get "expected" (*) warnings for each in the various weird
|
||||||
|
@ -59,9 +60,9 @@
|
||||||
#![proc_macro_derive()] //~ WARN `#[proc_macro_derive]` only has an effect
|
#![proc_macro_derive()] //~ WARN `#[proc_macro_derive]` only has an effect
|
||||||
#![doc = "2400"]
|
#![doc = "2400"]
|
||||||
#![cold] //~ WARN attribute should be applied to a function
|
#![cold] //~ WARN attribute should be applied to a function
|
||||||
//~^ WARN
|
//~^ WARN this was previously accepted
|
||||||
// see issue-43106-gating-of-builtin-attrs-error.rs
|
#![link()] //~ WARN attribute should be applied to an `extern` block
|
||||||
#![link()]
|
//~^ WARN this was previously accepted
|
||||||
#![link_name = "1900"]
|
#![link_name = "1900"]
|
||||||
//~^ WARN attribute should be applied to a foreign function
|
//~^ WARN attribute should be applied to a foreign function
|
||||||
//~^^ WARN this was previously accepted by the compiler
|
//~^^ WARN this was previously accepted by the compiler
|
||||||
|
@ -547,22 +548,38 @@ mod link_section {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Note that this is a `check-pass` test, so it
|
// Note that this is a `check-pass` test, so it will never invoke the linker.
|
||||||
// will never invoke the linker. These are here nonetheless to point
|
|
||||||
// out that we allow them at non-crate-level (though I do not know
|
|
||||||
// whether they have the same effect here as at crate-level).
|
|
||||||
|
|
||||||
#[link()]
|
#[link()]
|
||||||
|
//~^ WARN attribute should be applied to an `extern` block
|
||||||
|
//~| WARN this was previously accepted
|
||||||
mod link {
|
mod link {
|
||||||
|
//~^ NOTE not an `extern` block
|
||||||
|
|
||||||
mod inner { #![link()] }
|
mod inner { #![link()] }
|
||||||
|
//~^ WARN attribute should be applied to an `extern` block
|
||||||
|
//~| WARN this was previously accepted
|
||||||
|
//~| NOTE not an `extern` block
|
||||||
|
|
||||||
#[link()] fn f() { }
|
#[link()] fn f() { }
|
||||||
|
//~^ WARN attribute should be applied to an `extern` block
|
||||||
|
//~| WARN this was previously accepted
|
||||||
|
//~| NOTE not an `extern` block
|
||||||
|
|
||||||
#[link()] struct S;
|
#[link()] struct S;
|
||||||
|
//~^ WARN attribute should be applied to an `extern` block
|
||||||
|
//~| WARN this was previously accepted
|
||||||
|
//~| NOTE not an `extern` block
|
||||||
|
|
||||||
#[link()] type T = S;
|
#[link()] type T = S;
|
||||||
|
//~^ WARN attribute should be applied to an `extern` block
|
||||||
|
//~| WARN this was previously accepted
|
||||||
|
//~| NOTE not an `extern` block
|
||||||
|
|
||||||
#[link()] impl S { }
|
#[link()] impl S { }
|
||||||
|
//~^ WARN attribute should be applied to an `extern` block
|
||||||
|
//~| WARN this was previously accepted
|
||||||
|
//~| NOTE not an `extern` block
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StructForDeprecated;
|
struct StructForDeprecated;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue