Rollup merge of #143138 - JonathanBrouwer:link_name_parser, r=jdonszelmann
Port `#[link_name]` to the new attribute parsing infrastructure Ports `link_name` to the new attribute parsing infrastructure for https://github.com/rust-lang/rust/issues/131229#issuecomment-2971353197 r? `@jdonszelmann`
This commit is contained in:
@@ -253,6 +253,9 @@ pub enum AttributeKind {
|
||||
/// Represents `#[inline]` and `#[rustc_force_inline]`.
|
||||
Inline(InlineAttr, Span),
|
||||
|
||||
/// Represents `#[link_name]`.
|
||||
LinkName { name: Symbol, span: Span },
|
||||
|
||||
/// Represents `#[loop_match]`.
|
||||
LoopMatch(Span),
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ impl AttributeKind {
|
||||
Stability { .. } => Yes,
|
||||
Cold(..) => No,
|
||||
ConstContinue(..) => No,
|
||||
LinkName { .. } => Yes,
|
||||
LoopMatch(..) => No,
|
||||
MayDangle(..) => No,
|
||||
MustUse { .. } => Yes,
|
||||
|
||||
30
compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Normal file
30
compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use rustc_attr_data_structures::AttributeKind;
|
||||
use rustc_attr_data_structures::AttributeKind::LinkName;
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_span::{Symbol, sym};
|
||||
|
||||
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::parser::ArgParser;
|
||||
|
||||
pub(crate) struct LinkNameParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for LinkNameParser {
|
||||
const PATH: &[Symbol] = &[sym::link_name];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let Some(nv) = args.name_value() else {
|
||||
cx.expected_name_value(cx.attr_span, None);
|
||||
return None;
|
||||
};
|
||||
let Some(name) = nv.value_as_str() else {
|
||||
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(LinkName { name, span: cx.attr_span })
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ pub(crate) mod codegen_attrs;
|
||||
pub(crate) mod confusables;
|
||||
pub(crate) mod deprecation;
|
||||
pub(crate) mod inline;
|
||||
pub(crate) mod link_attrs;
|
||||
pub(crate) mod lint_helpers;
|
||||
pub(crate) mod loop_match;
|
||||
pub(crate) mod must_use;
|
||||
|
||||
@@ -22,6 +22,7 @@ use crate::attributes::codegen_attrs::{
|
||||
use crate::attributes::confusables::ConfusablesParser;
|
||||
use crate::attributes::deprecation::DeprecationParser;
|
||||
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
|
||||
use crate::attributes::link_attrs::LinkNameParser;
|
||||
use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
|
||||
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
|
||||
use crate::attributes::must_use::MustUseParser;
|
||||
@@ -121,6 +122,7 @@ attribute_parsers!(
|
||||
Single<DeprecationParser>,
|
||||
Single<ExportNameParser>,
|
||||
Single<InlineParser>,
|
||||
Single<LinkNameParser>,
|
||||
Single<LoopMatchParser>,
|
||||
Single<MayDangleParser>,
|
||||
Single<MustUseParser>,
|
||||
|
||||
@@ -123,6 +123,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
}
|
||||
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
|
||||
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
|
||||
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
|
||||
AttributeKind::NoMangle(attr_span) => {
|
||||
if tcx.opt_item_name(did.to_def_id()).is_some() {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
||||
@@ -262,7 +263,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
}
|
||||
}
|
||||
}
|
||||
sym::link_name => codegen_fn_attrs.link_name = attr.value_str(),
|
||||
sym::link_ordinal => {
|
||||
link_ordinal_span = Some(attr.span());
|
||||
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use rustc_abi::FIRST_VARIANT;
|
||||
use rustc_attr_data_structures::{AttributeKind, find_attr};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_hir as hir;
|
||||
@@ -6,7 +7,7 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{self, AdtDef, Instance, Ty, TyCtxt};
|
||||
use rustc_session::declare_lint;
|
||||
use rustc_span::{Span, Symbol, sym};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::lints::{BuiltinClashingExtern, BuiltinClashingExternSub};
|
||||
@@ -182,7 +183,11 @@ fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> SymbolName {
|
||||
// information, we could have codegen_fn_attrs also give span information back for
|
||||
// where the attribute was defined. However, until this is found to be a
|
||||
// bottleneck, this does just fine.
|
||||
(overridden_link_name, tcx.get_attr(fi, sym::link_name).unwrap().span())
|
||||
(
|
||||
overridden_link_name,
|
||||
find_attr!(tcx.get_all_attrs(fi), AttributeKind::LinkName {span, ..} => *span)
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
{
|
||||
SymbolName::Link(overridden_link_name, overridden_link_name_span)
|
||||
|
||||
@@ -302,6 +302,7 @@ fn emit_malformed_attribute(
|
||||
| sym::no_mangle
|
||||
| sym::must_use
|
||||
| sym::track_caller
|
||||
| sym::link_name
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -191,6 +191,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
|
||||
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::LinkName { span: attr_span, name }) => {
|
||||
self.check_link_name(hir_id, *attr_span, *name, span, target)
|
||||
}
|
||||
Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
|
||||
self.check_may_dangle(hir_id, *attr_span)
|
||||
}
|
||||
@@ -283,7 +286,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
[sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target),
|
||||
[sym::link_ordinal, ..] => self.check_link_ordinal(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_section, ..] => self.check_link_section(hir_id, attr, span, target),
|
||||
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
|
||||
self.check_macro_use(hir_id, attr, target)
|
||||
@@ -1604,7 +1606,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
}
|
||||
|
||||
/// 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_span: Span,
|
||||
name: Symbol,
|
||||
span: Span,
|
||||
target: Target,
|
||||
) {
|
||||
match target {
|
||||
Target::ForeignFn | Target::ForeignStatic => {}
|
||||
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
|
||||
@@ -1612,27 +1621,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
// erroneously allowed it and some crates used it accidentally, to be compatible
|
||||
// with crates depending on them, we can't throw an error here.
|
||||
Target::Field | Target::Arm | Target::MacroDef => {
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "link_name");
|
||||
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "link_name");
|
||||
}
|
||||
_ => {
|
||||
// FIXME: #[cold] was previously allowed on non-functions/statics and some crates
|
||||
// FIXME: #[link_name] was previously allowed on non-functions/statics and some crates
|
||||
// used this, so only emit a warning.
|
||||
let attr_span = matches!(target, Target::ForeignMod).then_some(attr.span());
|
||||
if let Some(s) = attr.value_str() {
|
||||
let help_span = matches!(target, Target::ForeignMod).then_some(attr_span);
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
errors::LinkName { span, attr_span, value: s.as_str() },
|
||||
attr_span,
|
||||
errors::LinkName { span, help_span, value: name.as_str() },
|
||||
);
|
||||
} else {
|
||||
self.tcx.emit_node_span_lint(
|
||||
UNUSED_ATTRIBUTES,
|
||||
hir_id,
|
||||
attr.span(),
|
||||
errors::LinkName { span, attr_span, value: "..." },
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ pub(crate) struct Link {
|
||||
#[warning]
|
||||
pub(crate) struct LinkName<'a> {
|
||||
#[help]
|
||||
pub attr_span: Option<Span>,
|
||||
pub help_span: Option<Span>,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub value: &'a str,
|
||||
|
||||
5
tests/ui/extern/issue-47725.rs
vendored
5
tests/ui/extern/issue-47725.rs
vendored
@@ -17,12 +17,9 @@ extern "C" {
|
||||
#[link_name]
|
||||
//~^ ERROR malformed `link_name` attribute input
|
||||
//~| HELP must be of the form
|
||||
//~| WARN attribute should be applied to a foreign function 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!
|
||||
//~| HELP try `#[link(name = "...")]` instead
|
||||
//~| NOTE expected this to be of the form `link_name = "..."
|
||||
extern "C" {
|
||||
fn bar() -> u32;
|
||||
}
|
||||
//~^^^ NOTE not a foreign function or static
|
||||
|
||||
fn main() {}
|
||||
|
||||
28
tests/ui/extern/issue-47725.stderr
vendored
28
tests/ui/extern/issue-47725.stderr
vendored
@@ -1,8 +1,11 @@
|
||||
error: malformed `link_name` attribute input
|
||||
error[E0539]: malformed `link_name` attribute input
|
||||
--> $DIR/issue-47725.rs:17:1
|
||||
|
|
||||
LL | #[link_name]
|
||||
| ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]`
|
||||
| ^^^^^^^^^^^^
|
||||
| |
|
||||
| expected this to be of the form `link_name = "..."`
|
||||
| help: must be of the form: `#[link_name = "name"]`
|
||||
|
||||
warning: attribute should be applied to a foreign function or static
|
||||
--> $DIR/issue-47725.rs:3:1
|
||||
@@ -38,23 +41,6 @@ help: try `#[link(name = "foobar")]` instead
|
||||
LL | #[link_name = "foobar"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: attribute should be applied to a foreign function or static
|
||||
--> $DIR/issue-47725.rs:17:1
|
||||
|
|
||||
LL | #[link_name]
|
||||
| ^^^^^^^^^^^^
|
||||
...
|
||||
LL | / extern "C" {
|
||||
LL | | fn bar() -> u32;
|
||||
LL | | }
|
||||
| |_- not a foreign function or static
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
help: try `#[link(name = "...")]` instead
|
||||
--> $DIR/issue-47725.rs:17:1
|
||||
|
|
||||
LL | #[link_name]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error; 3 warnings emitted
|
||||
error: aborting due to 1 previous error; 2 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
||||
@@ -387,14 +387,6 @@ LL | #![link()]
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to a foreign function or static
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
|
||||
|
|
||||
LL | #![link_name = "1900"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not a foreign function or static
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to a function or static
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
|
||||
|
|
||||
@@ -411,6 +403,14 @@ LL | #![cold]
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: attribute should be applied to a foreign function or static
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
|
||||
|
|
||||
LL | #![link_name = "1900"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not a foreign function or static
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
warning: `#[must_use]` has no effect when applied to a module
|
||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
|
||||
|
|
||||
|
||||
@@ -89,19 +89,6 @@ note: attribute also specified here
|
||||
LL | #[automatically_derived]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused attribute
|
||||
--> $DIR/unused-attr-duplicate.rs:86:5
|
||||
|
|
||||
LL | #[link_name = "this_does_not_exist"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
||||
|
|
||||
note: attribute also specified here
|
||||
--> $DIR/unused-attr-duplicate.rs:88:5
|
||||
|
|
||||
LL | #[link_name = "rust_dbg_extern_identity_u32"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
error: unused attribute
|
||||
--> $DIR/unused-attr-duplicate.rs:14:1
|
||||
|
|
||||
@@ -252,6 +239,19 @@ note: attribute also specified here
|
||||
LL | #[track_caller]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: unused attribute
|
||||
--> $DIR/unused-attr-duplicate.rs:86:5
|
||||
|
|
||||
LL | #[link_name = "this_does_not_exist"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
||||
|
|
||||
note: attribute also specified here
|
||||
--> $DIR/unused-attr-duplicate.rs:88:5
|
||||
|
|
||||
LL | #[link_name = "rust_dbg_extern_identity_u32"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
||||
error: unused attribute
|
||||
--> $DIR/unused-attr-duplicate.rs:92:1
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user