diff --git a/Cargo.lock b/Cargo.lock index b8a8d7b7d2329..2c7e047cb47ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3323,6 +3323,7 @@ dependencies = [ "rustc_macros", "rustc_session", "rustc_span", + "rustc_target", "thin-vec", ] @@ -3880,6 +3881,7 @@ dependencies = [ "rustc_ast_lowering", "rustc_ast_passes", "rustc_ast_pretty", + "rustc_attr_data_structures", "rustc_attr_parsing", "rustc_borrowck", "rustc_builtin_macros", @@ -4431,6 +4433,7 @@ dependencies = [ "rand 0.9.1", "rustc_abi", "rustc_ast", + "rustc_attr_data_structures", "rustc_data_structures", "rustc_errors", "rustc_feature", diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 3dedeb1b3726f..eee88a51ee6e6 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -165,6 +165,120 @@ pub enum CfgEntry { Version(Option, Span), } +/// Different ways that the PE Format can decorate a symbol name. +/// From +#[derive( + Copy, + Clone, + Debug, + Encodable, + Decodable, + HashStable_Generic, + PartialEq, + Eq, + PrintAttribute +)] +pub enum PeImportNameType { + /// IMPORT_ORDINAL + /// Uses the ordinal (i.e., a number) rather than the name. + Ordinal(u16), + /// Same as IMPORT_NAME + /// Name is decorated with all prefixes and suffixes. + Decorated, + /// Same as IMPORT_NAME_NOPREFIX + /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept. + NoPrefix, + /// Same as IMPORT_NAME_UNDECORATE + /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all + /// trailing characters) are skipped. + Undecorated, +} + +#[derive( + Copy, + Clone, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Encodable, + Decodable, + PrintAttribute +)] +#[derive(HashStable_Generic)] +pub enum NativeLibKind { + /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC) + Static { + /// Whether to bundle objects from static library into produced rlib + bundle: Option, + /// Whether to link static library without throwing any object files away + whole_archive: Option, + }, + /// Dynamic library (e.g. `libfoo.so` on Linux) + /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). + Dylib { + /// Whether the dynamic library will be linked only if it satisfies some undefined symbols + as_needed: Option, + }, + /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library. + /// On Linux, it refers to a generated shared library stub. + RawDylib, + /// A macOS-specific kind of dynamic libraries. + Framework { + /// Whether the framework will be linked only if it satisfies some undefined symbols + as_needed: Option, + }, + /// Argument which is passed to linker, relative order with libraries and other arguments + /// is preserved + LinkArg, + + /// Module imported from WebAssembly + WasmImportModule, + + /// The library kind wasn't specified, `Dylib` is currently used as a default. + Unspecified, +} + +impl NativeLibKind { + pub fn has_modifiers(&self) -> bool { + match self { + NativeLibKind::Static { bundle, whole_archive } => { + bundle.is_some() || whole_archive.is_some() + } + NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => { + as_needed.is_some() + } + NativeLibKind::RawDylib + | NativeLibKind::Unspecified + | NativeLibKind::LinkArg + | NativeLibKind::WasmImportModule => false, + } + } + + pub fn is_statically_included(&self) -> bool { + matches!(self, NativeLibKind::Static { .. }) + } + + pub fn is_dllimport(&self) -> bool { + matches!( + self, + NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified + ) + } +} + +#[derive(Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)] +pub struct LinkEntry { + pub span: Span, + pub kind: NativeLibKind, + pub name: Symbol, + pub cfg: Option, + pub verbatim: Option, + pub import_name_type: Option<(PeImportNameType, Span)>, +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -319,6 +433,9 @@ pub enum AttributeKind { /// Represents `#[inline]` and `#[rustc_force_inline]`. Inline(InlineAttr, Span), + /// Represents `#[link]`. + Link(ThinVec, Span), + /// Represents `#[link_name]`. LinkName { name: Symbol, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 3e2dc0a15b2f3..768ac8275ab85 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { Fundamental { .. } => Yes, Ignore { .. } => No, Inline(..) => No, + Link(..) => No, LinkName { .. } => Yes, LinkOrdinal { .. } => No, LinkSection { .. } => No, diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index 32029137268ba..0fc38a661ca25 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -17,5 +17,6 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } thin-vec = "0.2.12" # tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 8d0ead63a8d82..ba2a004532f20 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -158,3 +158,56 @@ attr_parsing_unused_multiple = -attr_parsing_previously_accepted = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + + +attr_parsing_as_needed_compatibility = + linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds + +attr_parsing_bundle_needs_static = + linking modifier `bundle` is only compatible with `static` linking kind + +attr_parsing_empty_link_name = + link name must not be empty + .label = empty link name + +attr_parsing_import_name_type_raw = + import name type can only be used with link kind `raw-dylib` + +attr_parsing_import_name_type_x86 = + import name type is only supported on x86 + +attr_parsing_incompatible_wasm_link = + `wasm_import_module` is incompatible with other arguments in `#[link]` attributes + +attr_parsing_invalid_link_modifier = + invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed + +attr_parsing_link_arg_unstable = + link kind `link-arg` is unstable + +attr_parsing_link_cfg_unstable = + link cfg is unstable + +attr_parsing_link_framework_apple = + link kind `framework` is only supported on Apple targets + +attr_parsing_link_requires_name = + `#[link]` attribute requires a `name = "string"` argument + .label = missing `name` argument + +attr_parsing_multiple_modifiers = + multiple `{$modifier}` modifiers in a single `modifiers` argument + +attr_parsing_multiple_renamings = + multiple renamings were specified for library `{$lib_name}` +attr_parsing_raw_dylib_no_nul = + link name must not contain NUL characters if link kind is `raw-dylib` + +attr_parsing_raw_dylib_elf_unstable = + link kind `raw-dylib` is unstable on ELF platforms + +attr_parsing_raw_dylib_only_windows = + link kind `raw-dylib` is only supported on Windows targets + +attr_parsing_whole_archive_needs_static = + linking modifier `whole-archive` is only compatible with `static` linking kind diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index a56855b3bd3d1..35f4c338cb89e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -32,7 +32,7 @@ pub fn parse_cfg_attr<'c, S: Stage>( parse_cfg_entry(cx, single) } -fn parse_cfg_entry( +pub(crate) fn parse_cfg_entry( cx: &mut AcceptContext<'_, '_, S>, item: &MetaItemOrLitParser<'_>, ) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 960cebd89259a..2fda86f3b5e34 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -1,14 +1,24 @@ -use rustc_attr_data_structures::AttributeKind; use rustc_attr_data_structures::AttributeKind::{LinkName, LinkOrdinal, LinkSection}; +use rustc_attr_data_structures::{AttributeKind, LinkEntry, NativeLibKind, PeImportNameType}; use rustc_feature::{AttributeTemplate, template}; +use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; +use rustc_target::spec::BinaryFormat; +use crate::attributes::cfg::parse_cfg_entry; use crate::attributes::{ - AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, + AttributeOrder, CombineAttributeParser, ConvertFn, NoArgsAttributeParser, OnDuplicate, + SingleAttributeParser, }; use crate::context::{AcceptContext, Stage, parse_single_integer}; +use crate::fluent_generated; use crate::parser::ArgParser; -use crate::session_diagnostics::{LinkOrdinalOutOfRange, NullOnLinkSection}; +use crate::session_diagnostics::{ + AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86, + IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange, + LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, + WholeArchiveNeedsStatic, +}; pub(crate) struct LinkNameParser; @@ -32,6 +42,316 @@ impl SingleAttributeParser for LinkNameParser { } } +pub(crate) struct LinkParser; + +impl CombineAttributeParser for LinkParser { + type Item = LinkEntry; + const PATH: &[Symbol] = &[sym::link]; + const CONVERT: ConvertFn = AttributeKind::Link; + const TEMPLATE: AttributeTemplate = template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#); + + fn extend<'c>( + cx: &'c mut AcceptContext<'_, '_, S>, + args: &'c ArgParser<'_>, + ) -> impl IntoIterator + 'c { + let mut result = None; + let Some(items) = args.list() else { + cx.expected_list(cx.attr_span); + return result; + }; + + let sess = cx.sess(); + let features = cx.features(); + + let mut name = None; + let mut kind = None; + let mut modifiers = None; + let mut cfg = None; + let mut wasm_import_module = None; + let mut import_name_type = None; + for item in items.mixed() { + let Some(item) = item.meta_item() else { + cx.unexpected_literal(item.span()); + continue; + }; + + match item.path().word().map(|ident| ident.name) { + Some(sym::name) => { + if name.is_some() { + cx.duplicate_key(item.span(), sym::name); + continue; + } + let Some((link_name, link_name_span)) = item.args().name_value_str() else { + cx.expected_name_value(item.span(), Some(sym::name)); + return result; + }; + if link_name.is_empty() { + cx.emit_err(EmptyLinkName { span: link_name_span }); + } + name = Some((link_name, link_name_span)); + } + Some(sym::kind) => { + if kind.is_some() { + cx.duplicate_key(item.span(), sym::kind); + continue; + } + let Some((link_kind, link_kind_span)) = item.args().name_value_str() else { + cx.expected_name_value(item.span(), Some(sym::kind)); + continue; + }; + + let link_kind = match link_kind.as_str() { + "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, + "dylib" => NativeLibKind::Dylib { as_needed: None }, + "framework" => { + if !sess.target.is_like_darwin { + cx.emit_err(LinkFrameworkApple { span: link_kind_span }); + } + NativeLibKind::Framework { as_needed: None } + } + "raw-dylib" => { + if sess.target.is_like_windows { + // raw-dylib is stable and working on Windows + } else if sess.target.binary_format == BinaryFormat::Elf + && features.raw_dylib_elf() + { + // raw-dylib is unstable on ELF, but the user opted in + } else if sess.target.binary_format == BinaryFormat::Elf + && sess.is_nightly_build() + { + feature_err( + sess, + sym::raw_dylib_elf, + link_kind_span, + fluent_generated::attr_parsing_raw_dylib_elf_unstable, + ) + .emit(); + } else { + cx.emit_err(RawDylibOnlyWindows { span: link_kind_span }); + } + + NativeLibKind::RawDylib + } + "link-arg" => { + if !features.link_arg_attribute() { + feature_err( + sess, + sym::link_arg_attribute, + link_kind_span, + fluent_generated::attr_parsing_link_arg_unstable, + ) + .emit(); + } + NativeLibKind::LinkArg + } + _kind => { + cx.expected_specific_argument_strings( + link_kind_span, + vec!["static", "dylib", "framework", "raw-dylib", "link-arg"], + ); + continue; + } + }; + kind = Some(link_kind); + } + Some(sym::modifiers) => { + if modifiers.is_some() { + cx.duplicate_key(item.span(), sym::modifiers); + continue; + } + let Some((link_modifiers, link_modifiers_span)) = item.args().name_value_str() + else { + cx.expected_name_value(item.span(), Some(sym::modifiers)); + continue; + }; + modifiers = Some((link_modifiers, link_modifiers_span)); + } + Some(sym::cfg) => { + if cfg.is_some() { + cx.duplicate_key(item.span(), sym::cfg); + continue; + } + let Some(link_cfg) = item.args().list() else { + cx.expected_list(item.span()); + continue; + }; + let Some(link_cfg) = link_cfg.single() else { + cx.expected_single_argument(item.span()); + continue; + }; + if !features.link_cfg() { + feature_err( + sess, + sym::link_cfg, + item.span(), + fluent_generated::attr_parsing_link_cfg_unstable, + ) + .emit(); + } + cfg = parse_cfg_entry(cx, link_cfg); + } + Some(sym::wasm_import_module) => { + if wasm_import_module.is_some() { + cx.duplicate_key(item.span(), sym::wasm_import_module); + continue; + } + let Some((link_wasm_import_module, _)) = item.args().name_value_str() else { + cx.expected_name_value(item.span(), Some(sym::wasm_import_module)); + continue; + }; + wasm_import_module = Some((link_wasm_import_module, item.span())); + } + Some(sym::import_name_type) => { + if import_name_type.is_some() { + cx.duplicate_key(item.span(), sym::import_name_type); + continue; + } + let Some((link_import_name_type, _)) = item.args().name_value_str() else { + cx.expected_name_value(item.span(), Some(sym::import_name_type)); + continue; + }; + if cx.sess().target.arch != "x86" { + cx.emit_err(ImportNameTypeX86 { span: item.span() }); + continue; + } + + let link_import_name_type = match link_import_name_type.as_str() { + "decorated" => PeImportNameType::Decorated, + "noprefix" => PeImportNameType::NoPrefix, + "undecorated" => PeImportNameType::Undecorated, + _ => { + cx.expected_specific_argument_strings( + item.span(), + vec!["decorated", "noprefix", "undecorated"], + ); + continue; + } + }; + import_name_type = Some((link_import_name_type, item.span())); + } + _ => { + cx.expected_specific_argument_strings( + item.span(), + vec![ + "name", + "kind", + "modifiers", + "cfg", + "wasm_import_module", + "import_name_type", + ], + ); + } + } + } + + // Do this outside the above loop so we don't depend on modifiers coming after kinds + let mut verbatim = None; + if let Some((modifiers, span)) = modifiers { + for modifier in modifiers.as_str().split(',') { + let (modifier, value) = match modifier.strip_prefix(&['+', '-']) { + Some(m) => (m, modifier.starts_with('+')), + None => { + cx.emit_err(InvalidLinkModifier { span }); + continue; + } + }; + + macro report_unstable_modifier($feature: ident) { + if !features.$feature() { + // FIXME: make this translatable + #[expect(rustc::untranslatable_diagnostic)] + feature_err( + sess, + sym::$feature, + span, + format!("linking modifier `{modifier}` is unstable"), + ) + .emit(); + } + } + let assign_modifier = |dst: &mut Option| { + if dst.is_some() { + cx.emit_err(MultipleModifiers { span, modifier }); + } else { + *dst = Some(value); + } + }; + match (modifier, &mut kind) { + ("bundle", Some(NativeLibKind::Static { bundle, .. })) => { + assign_modifier(bundle) + } + ("bundle", _) => { + cx.emit_err(BundleNeedsStatic { span }); + } + + ("verbatim", _) => assign_modifier(&mut verbatim), + + ("whole-archive", Some(NativeLibKind::Static { whole_archive, .. })) => { + assign_modifier(whole_archive) + } + ("whole-archive", _) => { + cx.emit_err(WholeArchiveNeedsStatic { span }); + } + + ("as-needed", Some(NativeLibKind::Dylib { as_needed })) + | ("as-needed", Some(NativeLibKind::Framework { as_needed })) => { + report_unstable_modifier!(native_link_modifiers_as_needed); + assign_modifier(as_needed) + } + ("as-needed", _) => { + cx.emit_err(AsNeededCompatibility { span }); + } + + _ => { + cx.expected_specific_argument_strings( + span, + vec!["bundle", "verbatim", "whole-archive", "as-needed"], + ); + } + } + } + } + + if let Some((_, span)) = wasm_import_module { + if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() { + cx.emit_err(IncompatibleWasmLink { span }); + } + } + + if wasm_import_module.is_some() { + (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule)); + } + let Some((name, name_span)) = name else { + cx.emit_err(LinkRequiresName { span: cx.attr_span }); + return result; + }; + + // Do this outside of the loop so that `import_name_type` can be specified before `kind`. + if let Some((_, span)) = import_name_type { + if kind != Some(NativeLibKind::RawDylib) { + cx.emit_err(ImportNameTypeRaw { span }); + } + } + + if let Some(NativeLibKind::RawDylib) = kind + && name.as_str().contains('\0') + { + cx.emit_err(RawDylibNoNul { span: name_span }); + } + + result = Some(LinkEntry { + span: cx.attr_span, + kind: kind.unwrap_or(NativeLibKind::Unspecified), + name, + cfg, + verbatim, + import_name_type, + }); + result + } +} + pub(crate) struct LinkSectionParser; impl SingleAttributeParser for LinkSectionParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 567341d1517dd..bc5392c23785a 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -24,7 +24,7 @@ use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::link_attrs::{ ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser, - LinkSectionParser, StdInternalSymbolParser, + LinkParser, LinkSectionParser, StdInternalSymbolParser, }; use crate::attributes::lint_helpers::{ AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, @@ -131,6 +131,7 @@ attribute_parsers!( // tidy-alphabetical-start Combine, Combine, + Combine, Combine, Combine, // tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 2102a26108bc4..7952101ebe2fa 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -79,6 +79,7 @@ // tidy-alphabetical-start #![allow(internal_features)] #![doc(rust_logo)] +#![feature(decl_macro)] #![feature(rustdoc_internals)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index aecaae947c99b..708c8885e8be9 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -169,6 +169,15 @@ impl<'a> ArgParser<'a> { } } + /// Asserts that this MetaItem is a name-value pair, and that the value is a string. + /// Returns the value and the span of the value. + pub fn name_value_str(&self) -> Option<(Symbol, Span)> { + match self { + Self::NameValue(n) => n.value_as_str().map(|s| (s, n.value_span)), + Self::List(_) | Self::NoArgs => None, + } + } + /// Assert that there were no args. /// If there were, get a span to the arguments /// (to pass to [`AcceptContext::expected_no_args`](crate::context::AcceptContext::expected_no_args)). diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 97bf3d1c54955..84c8592bf120e 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -650,3 +650,97 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag } } + +#[derive(Diagnostic)] +#[diag(attr_parsing_empty_link_name, code = E0454)] +pub(crate) struct EmptyLinkName { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_link_framework_apple, code = E0455)] +pub(crate) struct LinkFrameworkApple { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_incompatible_wasm_link)] +pub(crate) struct IncompatibleWasmLink { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_link_requires_name, code = E0459)] +pub(crate) struct LinkRequiresName { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_raw_dylib_no_nul)] +pub(crate) struct RawDylibNoNul { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_raw_dylib_only_windows, code = E0455)] +pub(crate) struct RawDylibOnlyWindows { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_invalid_link_modifier)] +pub(crate) struct InvalidLinkModifier { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_multiple_modifiers)] +pub(crate) struct MultipleModifiers<'a> { + #[primary_span] + pub span: Span, + pub modifier: &'a str, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_import_name_type_x86)] +pub(crate) struct ImportNameTypeX86 { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_bundle_needs_static)] +pub(crate) struct BundleNeedsStatic { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_whole_archive_needs_static)] +pub(crate) struct WholeArchiveNeedsStatic { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_as_needed_compatibility)] +pub(crate) struct AsNeededCompatibility { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_import_name_type_raw)] +pub(crate) struct ImportNameTypeRaw { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b46773396fce1..ceb3198edd838 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -14,6 +14,8 @@ use itertools::Itertools; use regex::Regex; use rustc_arena::TypedArena; use rustc_ast::CRATE_NODE_ID; +use rustc_attr_data_structures::NativeLibKind; +use rustc_attr_parsing::eval_config_entry; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; @@ -38,7 +40,6 @@ use rustc_session::config::{ use rustc_session::lint::builtin::LINKER_MESSAGES; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::search_paths::PathKind; -use rustc_session::utils::NativeLibKind; /// For all the linkers we support, and information they might /// need out of the shared crate context before we get rid of it. use rustc_session::{Session, filesearch}; @@ -3010,7 +3011,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) { fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => rustc_attr_parsing::cfg_matches(cfg, sess, CRATE_NODE_ID, None), + Some(ref cfg) => eval_config_entry(sess, cfg, CRATE_NODE_ID, None).as_bool(), None => true, } } diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 74f39022afb7b..8e03c101d5446 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -3,13 +3,13 @@ use std::io::{BufWriter, Write}; use std::path::{Path, PathBuf}; use rustc_abi::Endian; +use rustc_attr_data_structures::NativeLibKind; use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::StableHasher; use rustc_hashes::Hash128; use rustc_session::Session; use rustc_session::cstore::DllImport; -use rustc_session::utils::NativeLibKind; use rustc_span::Symbol; use crate::back::archive::ImportLibraryItem; diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 48565e0b4de47..dcb6067c8ee4b 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -1,10 +1,11 @@ #![allow(non_camel_case_types)] +use rustc_attr_data_structures::PeImportNameType; use rustc_hir::LangItem; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, Instance, TyCtxt}; use rustc_middle::{bug, mir, span_bug}; -use rustc_session::cstore::{DllCallingConvention, DllImport, PeImportNameType}; +use rustc_session::cstore::{DllCallingConvention, DllImport}; use rustc_span::Span; use rustc_target::spec::Target; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 23ed387a3ff97..2bc33eacf12af 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -25,7 +25,7 @@ use std::io; use std::path::{Path, PathBuf}; use std::sync::Arc; -use rustc_ast as ast; +use rustc_attr_data_structures::{CfgEntry, NativeLibKind}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; use rustc_hir::CRATE_HIR_ID; @@ -45,7 +45,6 @@ use rustc_session::Session; use rustc_session::config::{CrateType, OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc_session::cstore::{self, CrateSource}; use rustc_session::lint::builtin::LINKER_MESSAGES; -use rustc_session::utils::NativeLibKind; use rustc_span::Symbol; pub mod assert_module_sources; @@ -187,7 +186,7 @@ pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, pub filename: Option, - pub cfg: Option, + pub cfg: Option, pub verbatim: bool, pub dll_imports: Vec, } diff --git a/compiler/rustc_error_codes/src/error_codes/E0458.md b/compiler/rustc_error_codes/src/error_codes/E0458.md index 1b280cba44f53..651bc37887961 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0458.md +++ b/compiler/rustc_error_codes/src/error_codes/E0458.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + An unknown "kind" was specified for a link attribute. Erroneous code example: -```compile_fail,E0458 +```ignore (no longer emitted) #[link(kind = "wonderful_unicorn")] extern "C" {} // error: unknown kind: `wonderful_unicorn` ``` diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 473ac5e0cea4a..798d789a71024 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -52,6 +52,7 @@ tracing = "0.1" [dev-dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } +rustc_attr_data_structures = { path = "../rustc_attr_data_structures"} # tidy-alphabetical-end [features] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 360b5629e9d6e..cd7718474e0ee 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use std::sync::atomic::AtomicBool; use rustc_abi::Align; +use rustc_attr_data_structures::NativeLibKind; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::emitter::HumanReadableErrorType; use rustc_errors::{ColorConfig, registry}; @@ -20,7 +21,7 @@ use rustc_session::config::{ }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; -use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; +use rustc_session::utils::{CanonicalizedPath, NativeLib}; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, getopts}; use rustc_span::edition::{DEFAULT_EDITION, Edition}; use rustc_span::source_map::{RealFileLoader, SourceMapInputs}; diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 3bef5ca114b89..04992eebf3622 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -1,6 +1,3 @@ -metadata_as_needed_compatibility = - linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds - metadata_async_drop_types_in_dependency = found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}` .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used @@ -11,9 +8,6 @@ metadata_bad_panic_strategy = metadata_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `metadata` to stdout, but stdout is a tty -metadata_bundle_needs_static = - linking modifier `bundle` is only compatible with `static` linking kind - metadata_cannot_find_crate = can't find crate for `{$crate_name}`{$add_info} @@ -60,10 +54,6 @@ metadata_crate_not_panic_runtime = metadata_dl_error = {$path}{$err} -metadata_empty_link_name = - link name must not be empty - .label = empty link name - metadata_empty_renaming_target = an empty renaming target was specified for library `{$lib_name}` @@ -108,15 +98,6 @@ metadata_full_metadata_not_found = metadata_global_alloc_required = no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait -metadata_import_name_type_form = - import name type must be of the form `import_name_type = "string"` - -metadata_import_name_type_raw = - import name type can only be used with link kind `raw-dylib` - -metadata_import_name_type_x86 = - import name type is only supported on x86 - metadata_incompatible_panic_in_drop_strategy = the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}` @@ -143,15 +124,10 @@ metadata_incompatible_target_modifiers_r_missed = mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}` .note = `{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}` .help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely -metadata_incompatible_wasm_link = - `wasm_import_module` is incompatible with other arguments in `#[link]` attributes metadata_install_missing_components = maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview` -metadata_invalid_link_modifier = - invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed - metadata_invalid_meta_files = found invalid metadata files for crate `{$crate_name}`{$add_info} @@ -164,67 +140,18 @@ metadata_lib_framework_apple = metadata_lib_required = crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form -metadata_link_arg_unstable = - link kind `link-arg` is unstable - -metadata_link_cfg_form = - link cfg must be of the form `cfg(/* predicate */)` - -metadata_link_cfg_single_predicate = - link cfg must have a single predicate argument - -metadata_link_cfg_unstable = - link cfg is unstable - -metadata_link_framework_apple = - link kind `framework` is only supported on Apple targets - -metadata_link_kind_form = - link kind must be of the form `kind = "string"` - -metadata_link_modifiers_form = - link modifiers must be of the form `modifiers = "string"` - -metadata_link_name_form = - link name must be of the form `name = "string"` - metadata_link_ordinal_raw_dylib = `#[link_ordinal]` is only supported if link kind is `raw-dylib` -metadata_link_requires_name = - `#[link]` attribute requires a `name = "string"` argument - .label = missing `name` argument - metadata_missing_native_library = could not find native static library `{$libname}`, perhaps an -L flag is missing? metadata_multiple_candidates = multiple candidates for `{$flavor}` dependency `{$crate_name}` found -metadata_multiple_cfgs = - multiple `cfg` arguments in a single `#[link]` attribute - -metadata_multiple_import_name_type = - multiple `import_name_type` arguments in a single `#[link]` attribute - -metadata_multiple_kinds_in_link = - multiple `kind` arguments in a single `#[link]` attribute - -metadata_multiple_link_modifiers = - multiple `modifiers` arguments in a single `#[link]` attribute - -metadata_multiple_modifiers = - multiple `{$modifier}` modifiers in a single `modifiers` argument - -metadata_multiple_names_in_link = - multiple `name` arguments in a single `#[link]` attribute - metadata_multiple_renamings = multiple renamings were specified for library `{$lib_name}` -metadata_multiple_wasm_import = - multiple `wasm_import_module` arguments in a single `#[link]` attribute - metadata_newer_crate_version = found possibly newer version of crate `{$crate_name}`{$add_info} .note = perhaps that crate needs to be recompiled? @@ -263,15 +190,6 @@ metadata_prev_alloc_error_handler = metadata_prev_global_alloc = previous global allocator defined here -metadata_raw_dylib_elf_unstable = - link kind `raw-dylib` is unstable on ELF platforms - -metadata_raw_dylib_no_nul = - link name must not contain NUL characters if link kind is `raw-dylib` - -metadata_raw_dylib_only_windows = - link kind `raw-dylib` is only supported on Windows targets - metadata_raw_dylib_unsupported_abi = ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture @@ -307,26 +225,7 @@ metadata_target_not_installed = metadata_two_panic_runtimes = cannot link together two panic runtimes: {$prev_name} and {$cur_name} -metadata_unexpected_link_arg = - unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type - -metadata_unknown_import_name_type = - unknown import name type `{$import_name_type}`, expected one of: decorated, noprefix, undecorated - -metadata_unknown_link_kind = - unknown link kind `{$kind}`, expected one of: static, dylib, framework, raw-dylib, link-arg - .label = unknown link kind - -metadata_unknown_link_modifier = - unknown linking modifier `{$modifier}`, expected one of: bundle, verbatim, whole-archive, as-needed - metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}` metadata_wasm_c_abi = older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88 - -metadata_wasm_import_form = - wasm import module must be of the form `wasm_import_module = "string"` - -metadata_whole_archive_needs_static = - linking modifier `whole-archive` is only compatible with `static` linking kind diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 4a3b43167cfa4..10b41669d7dfb 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -83,187 +83,6 @@ pub struct IncompatiblePanicInDropStrategy { pub desired_strategy: PanicStrategy, } -#[derive(Diagnostic)] -#[diag(metadata_multiple_names_in_link)] -pub struct MultipleNamesInLink { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_multiple_kinds_in_link)] -pub struct MultipleKindsInLink { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_name_form)] -pub struct LinkNameForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_kind_form)] -pub struct LinkKindForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_modifiers_form)] -pub struct LinkModifiersForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_cfg_form)] -pub struct LinkCfgForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_wasm_import_form)] -pub struct WasmImportForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_empty_link_name, code = E0454)] -pub struct EmptyLinkName { - #[primary_span] - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_framework_apple, code = E0455)] -pub struct LinkFrameworkApple { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_raw_dylib_only_windows, code = E0455)] -pub struct RawDylibOnlyWindows { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_unknown_link_kind, code = E0458)] -pub struct UnknownLinkKind<'a> { - #[primary_span] - #[label] - pub span: Span, - pub kind: &'a str, -} - -#[derive(Diagnostic)] -#[diag(metadata_multiple_link_modifiers)] -pub struct MultipleLinkModifiers { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_multiple_cfgs)] -pub struct MultipleCfgs { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_cfg_single_predicate)] -pub struct LinkCfgSinglePredicate { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_multiple_wasm_import)] -pub struct MultipleWasmImport { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_unexpected_link_arg)] -pub struct UnexpectedLinkArg { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_invalid_link_modifier)] -pub struct InvalidLinkModifier { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_multiple_modifiers)] -pub struct MultipleModifiers<'a> { - #[primary_span] - pub span: Span, - pub modifier: &'a str, -} - -#[derive(Diagnostic)] -#[diag(metadata_bundle_needs_static)] -pub struct BundleNeedsStatic { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_whole_archive_needs_static)] -pub struct WholeArchiveNeedsStatic { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_as_needed_compatibility)] -pub struct AsNeededCompatibility { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_unknown_link_modifier)] -pub struct UnknownLinkModifier<'a> { - #[primary_span] - pub span: Span, - pub modifier: &'a str, -} - -#[derive(Diagnostic)] -#[diag(metadata_incompatible_wasm_link)] -pub struct IncompatibleWasmLink { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_link_requires_name, code = E0459)] -pub struct LinkRequiresName { - #[primary_span] - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_raw_dylib_no_nul)] -pub struct RawDylibNoNul { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(metadata_link_ordinal_raw_dylib)] pub struct LinkOrdinalRawDylib { @@ -706,42 +525,6 @@ pub struct LibFilenameForm<'a> { pub dll_suffix: &'a str, } -#[derive(Diagnostic)] -#[diag(metadata_multiple_import_name_type)] -pub struct MultipleImportNameType { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_import_name_type_form)] -pub struct ImportNameTypeForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_import_name_type_x86)] -pub struct ImportNameTypeX86 { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(metadata_unknown_import_name_type)] -pub struct UnknownImportNameType<'a> { - #[primary_span] - pub span: Span, - pub import_name_type: &'a str, -} - -#[derive(Diagnostic)] -#[diag(metadata_import_name_type_raw)] -pub struct ImportNameTypeRaw { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(metadata_wasm_c_abi)] pub(crate) struct WasmCAbi { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 4d276f814ef25..0bfe994f76973 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -3,24 +3,20 @@ use std::path::{Path, PathBuf}; use rustc_abi::ExternAbi; use rustc_ast::CRATE_NODE_ID; -use rustc_attr_data_structures::{AttributeKind, find_attr}; -use rustc_attr_parsing as attr; +use rustc_attr_data_structures::{AttributeKind, NativeLibKind, PeImportNameType, find_attr}; +use rustc_attr_parsing::eval_config_entry; use rustc_data_structures::fx::FxHashSet; use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_session::Session; use rustc_session::config::CrateType; -use rustc_session::cstore::{ - DllCallingConvention, DllImport, ForeignModule, NativeLib, PeImportNameType, -}; -use rustc_session::parse::feature_err; +use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, NativeLib}; use rustc_session::search_paths::PathKind; -use rustc_session::utils::NativeLibKind; +use rustc_span::Symbol; use rustc_span::def_id::{DefId, LOCAL_CRATE}; -use rustc_span::{Symbol, sym}; -use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents}; +use rustc_target::spec::LinkSelfContainedComponents; -use crate::{errors, fluent_generated}; +use crate::errors; /// The fallback directories are passed to linker, but not used when rustc does the search, /// because in the latter case the set of fallback directories cannot always be determined @@ -191,7 +187,7 @@ pub(crate) fn collect(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> Vec pub(crate) fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None), + Some(ref cfg) => eval_config_entry(sess, cfg, CRATE_NODE_ID, None).as_bool(), None => true, } } @@ -212,289 +208,23 @@ impl<'tcx> Collector<'tcx> { return; } - // Process all of the #[link(..)]-style arguments - let features = self.tcx.features(); - - for m in self.tcx.get_attrs(def_id, sym::link) { - let Some(items) = m.meta_item_list() else { - continue; - }; - - let mut name = None; - let mut kind = None; - let mut modifiers = None; - let mut cfg = None; - let mut wasm_import_module = None; - let mut import_name_type = None; - for item in items.iter() { - match item.name() { - Some(sym::name) => { - if name.is_some() { - sess.dcx().emit_err(errors::MultipleNamesInLink { span: item.span() }); - continue; - } - let Some(link_name) = item.value_str() else { - sess.dcx().emit_err(errors::LinkNameForm { span: item.span() }); - continue; - }; - let span = item.name_value_literal_span().unwrap(); - if link_name.is_empty() { - sess.dcx().emit_err(errors::EmptyLinkName { span }); - } - name = Some((link_name, span)); - } - Some(sym::kind) => { - if kind.is_some() { - sess.dcx().emit_err(errors::MultipleKindsInLink { span: item.span() }); - continue; - } - let Some(link_kind) = item.value_str() else { - sess.dcx().emit_err(errors::LinkKindForm { span: item.span() }); - continue; - }; - - let span = item.name_value_literal_span().unwrap(); - let link_kind = match link_kind.as_str() { - "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, - "dylib" => NativeLibKind::Dylib { as_needed: None }, - "framework" => { - if !sess.target.is_like_darwin { - sess.dcx().emit_err(errors::LinkFrameworkApple { span }); - } - NativeLibKind::Framework { as_needed: None } - } - "raw-dylib" => { - if sess.target.is_like_windows { - // raw-dylib is stable and working on Windows - } else if sess.target.binary_format == BinaryFormat::Elf - && features.raw_dylib_elf() - { - // raw-dylib is unstable on ELF, but the user opted in - } else if sess.target.binary_format == BinaryFormat::Elf - && sess.is_nightly_build() - { - feature_err( - sess, - sym::raw_dylib_elf, - span, - fluent_generated::metadata_raw_dylib_elf_unstable, - ) - .emit(); - } else { - sess.dcx().emit_err(errors::RawDylibOnlyWindows { span }); - } - - NativeLibKind::RawDylib - } - "link-arg" => { - if !features.link_arg_attribute() { - feature_err( - sess, - sym::link_arg_attribute, - span, - fluent_generated::metadata_link_arg_unstable, - ) - .emit(); - } - NativeLibKind::LinkArg - } - kind => { - sess.dcx().emit_err(errors::UnknownLinkKind { span, kind }); - continue; - } - }; - kind = Some(link_kind); - } - Some(sym::modifiers) => { - if modifiers.is_some() { - sess.dcx() - .emit_err(errors::MultipleLinkModifiers { span: item.span() }); - continue; - } - let Some(link_modifiers) = item.value_str() else { - sess.dcx().emit_err(errors::LinkModifiersForm { span: item.span() }); - continue; - }; - modifiers = Some((link_modifiers, item.name_value_literal_span().unwrap())); - } - Some(sym::cfg) => { - if cfg.is_some() { - sess.dcx().emit_err(errors::MultipleCfgs { span: item.span() }); - continue; - } - let Some(link_cfg) = item.meta_item_list() else { - sess.dcx().emit_err(errors::LinkCfgForm { span: item.span() }); - continue; - }; - let [link_cfg] = link_cfg else { - sess.dcx() - .emit_err(errors::LinkCfgSinglePredicate { span: item.span() }); - continue; - }; - let Some(link_cfg) = link_cfg.meta_item_or_bool() else { - sess.dcx() - .emit_err(errors::LinkCfgSinglePredicate { span: item.span() }); - continue; - }; - if !features.link_cfg() { - feature_err( - sess, - sym::link_cfg, - item.span(), - fluent_generated::metadata_link_cfg_unstable, - ) - .emit(); - } - cfg = Some(link_cfg.clone()); - } - Some(sym::wasm_import_module) => { - if wasm_import_module.is_some() { - sess.dcx().emit_err(errors::MultipleWasmImport { span: item.span() }); - continue; - } - let Some(link_wasm_import_module) = item.value_str() else { - sess.dcx().emit_err(errors::WasmImportForm { span: item.span() }); - continue; - }; - wasm_import_module = Some((link_wasm_import_module, item.span())); - } - Some(sym::import_name_type) => { - if import_name_type.is_some() { - sess.dcx() - .emit_err(errors::MultipleImportNameType { span: item.span() }); - continue; - } - let Some(link_import_name_type) = item.value_str() else { - sess.dcx().emit_err(errors::ImportNameTypeForm { span: item.span() }); - continue; - }; - if self.tcx.sess.target.arch != "x86" { - sess.dcx().emit_err(errors::ImportNameTypeX86 { span: item.span() }); - continue; - } - - let link_import_name_type = match link_import_name_type.as_str() { - "decorated" => PeImportNameType::Decorated, - "noprefix" => PeImportNameType::NoPrefix, - "undecorated" => PeImportNameType::Undecorated, - import_name_type => { - sess.dcx().emit_err(errors::UnknownImportNameType { - span: item.span(), - import_name_type, - }); - continue; - } - }; - import_name_type = Some((link_import_name_type, item.span())); - } - _ => { - sess.dcx().emit_err(errors::UnexpectedLinkArg { span: item.span() }); - } - } - } - - // Do this outside the above loop so we don't depend on modifiers coming after kinds - let mut verbatim = None; - if let Some((modifiers, span)) = modifiers { - for modifier in modifiers.as_str().split(',') { - let (modifier, value) = match modifier.strip_prefix(&['+', '-']) { - Some(m) => (m, modifier.starts_with('+')), - None => { - sess.dcx().emit_err(errors::InvalidLinkModifier { span }); - continue; - } - }; - - macro report_unstable_modifier($feature: ident) { - if !features.$feature() { - // FIXME: make this translatable - #[expect(rustc::untranslatable_diagnostic)] - feature_err( - sess, - sym::$feature, - span, - format!("linking modifier `{modifier}` is unstable"), - ) - .emit(); - } - } - let assign_modifier = |dst: &mut Option| { - if dst.is_some() { - sess.dcx().emit_err(errors::MultipleModifiers { span, modifier }); - } else { - *dst = Some(value); - } - }; - match (modifier, &mut kind) { - ("bundle", Some(NativeLibKind::Static { bundle, .. })) => { - assign_modifier(bundle) - } - ("bundle", _) => { - sess.dcx().emit_err(errors::BundleNeedsStatic { span }); - } - - ("verbatim", _) => assign_modifier(&mut verbatim), - - ("whole-archive", Some(NativeLibKind::Static { whole_archive, .. })) => { - assign_modifier(whole_archive) - } - ("whole-archive", _) => { - sess.dcx().emit_err(errors::WholeArchiveNeedsStatic { span }); - } - - ("as-needed", Some(NativeLibKind::Dylib { as_needed })) - | ("as-needed", Some(NativeLibKind::Framework { as_needed })) => { - report_unstable_modifier!(native_link_modifiers_as_needed); - assign_modifier(as_needed) - } - ("as-needed", _) => { - sess.dcx().emit_err(errors::AsNeededCompatibility { span }); - } - - _ => { - sess.dcx().emit_err(errors::UnknownLinkModifier { span, modifier }); - } - } - } - } - - if let Some((_, span)) = wasm_import_module { - if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() { - sess.dcx().emit_err(errors::IncompatibleWasmLink { span }); - } - } - - if wasm_import_module.is_some() { - (name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule)); - } - let Some((name, name_span)) = name else { - sess.dcx().emit_err(errors::LinkRequiresName { span: m.span() }); - continue; - }; - - // Do this outside of the loop so that `import_name_type` can be specified before `kind`. - if let Some((_, span)) = import_name_type { - if kind != Some(NativeLibKind::RawDylib) { - sess.dcx().emit_err(errors::ImportNameTypeRaw { span }); - } - } - - let dll_imports = match kind { - Some(NativeLibKind::RawDylib) => { - if name.as_str().contains('\0') { - sess.dcx().emit_err(errors::RawDylibNoNul { span: name_span }); - } - foreign_items - .iter() - .map(|&child_item| { - self.build_dll_import( - abi, - import_name_type.map(|(import_name_type, _)| import_name_type), - child_item, - ) - }) - .collect() - } + for attr in + find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::Link(links, _) => links) + .iter() + .map(|v| v.iter()) + .flatten() + { + let dll_imports = match attr.kind { + NativeLibKind::RawDylib => foreign_items + .iter() + .map(|&child_item| { + self.build_dll_import( + abi, + attr.import_name_type.map(|(import_name_type, _)| import_name_type), + child_item, + ) + }) + .collect(), _ => { for &child_item in foreign_items { if let Some(span) = find_attr!(self.tcx.get_all_attrs(child_item), AttributeKind::LinkOrdinal {span, ..} => *span) @@ -507,15 +237,20 @@ impl<'tcx> Collector<'tcx> { } }; - let kind = kind.unwrap_or(NativeLibKind::Unspecified); - let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), self.tcx); + let filename = find_bundled_library( + attr.name, + attr.verbatim, + attr.kind, + attr.cfg.is_some(), + self.tcx, + ); self.libs.push(NativeLib { - name, + name: attr.name, filename, - kind, - cfg, + kind: attr.kind, + cfg: attr.cfg.clone(), foreign_module: Some(def_id.to_def_id()), - verbatim, + verbatim: attr.verbatim, dll_imports, }); } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 783d79d978ab6..373a377a5abcd 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -309,6 +309,7 @@ pub fn check_builtin_meta_item( | sym::ignore | sym::must_use | sym::track_caller + | sym::link | sym::link_name | sym::link_ordinal | sym::export_name diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2009ddc1e2d59..65cb35772b0d0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -279,6 +279,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => { self.check_used(*attr_span, target, span); } + Attribute::Parsed(AttributeKind::Link(_, attr_span)) => { + self.check_link(hir_id, *attr_span, span, target) + } &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => { self.check_pass_by_value(attr_span, span, target) } @@ -343,7 +346,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target), [sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target), - [sym::link, ..] => self.check_link(hir_id, attr, span, target), [sym::macro_use, ..] | [sym::macro_escape, ..] => { self.check_macro_use(hir_id, attr, target) } @@ -1659,7 +1661,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// 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) { + fn check_link(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { if target == Target::ForeignMod && let hir::Node::Item(item) = self.tcx.hir_node(hir_id) && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item @@ -1671,7 +1673,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span(), + attr_span, errors::Link { span: (target != Target::ForeignMod).then_some(span) }, ); } diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 0516982aeabb9..a6f8cb73f0c8e 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -10,6 +10,7 @@ getopts = "0.2" rand = "0.9.0" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } +rustc_attr_data_structures = { path = "../rustc_attr_data_structures" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_session/src/config/native_libs.rs b/compiler/rustc_session/src/config/native_libs.rs index f1f0aeb5e599b..dd8effe8cd7c5 100644 --- a/compiler/rustc_session/src/config/native_libs.rs +++ b/compiler/rustc_session/src/config/native_libs.rs @@ -4,11 +4,12 @@ //! (There is also a similar but separate syntax for `#[link]` attributes, //! which have their own parser in `rustc_metadata`.) +use rustc_attr_data_structures::NativeLibKind; use rustc_feature::UnstableFeatures; use crate::EarlyDiagCtxt; use crate::config::UnstableOptions; -use crate::utils::{NativeLib, NativeLibKind}; +use crate::utils::NativeLib; #[cfg(test)] mod tests; diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 4cfc745dec28a..2caae70c4615c 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -6,7 +6,7 @@ use std::any::Any; use std::path::PathBuf; use rustc_abi::ExternAbi; -use rustc_ast as ast; +use rustc_attr_data_structures::{CfgEntry, NativeLibKind, PeImportNameType}; use rustc_data_structures::sync::{self, AppendOnlyIndexVec, FreezeLock}; use rustc_hir::def_id::{ CrateNum, DefId, LOCAL_CRATE, LocalDefId, StableCrateId, StableCrateIdMap, @@ -16,7 +16,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::{Span, Symbol}; use crate::search_paths::PathKind; -use crate::utils::NativeLibKind; // lonely orphan structs and enums looking for a better home @@ -72,7 +71,7 @@ pub struct NativeLib { pub name: Symbol, /// If packed_bundled_libs enabled, actual filename of library is stored. pub filename: Option, - pub cfg: Option, + pub cfg: Option, pub foreign_module: Option, pub verbatim: Option, pub dll_imports: Vec, @@ -88,25 +87,6 @@ impl NativeLib { } } -/// Different ways that the PE Format can decorate a symbol name. -/// From -#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic, PartialEq, Eq)] -pub enum PeImportNameType { - /// IMPORT_ORDINAL - /// Uses the ordinal (i.e., a number) rather than the name. - Ordinal(u16), - /// Same as IMPORT_NAME - /// Name is decorated with all prefixes and suffixes. - Decorated, - /// Same as IMPORT_NAME_NOPREFIX - /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept. - NoPrefix, - /// Same as IMPORT_NAME_UNDECORATE - /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all - /// trailing characters) are skipped. - Undecorated, -} - #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)] pub struct DllImport { pub name: Symbol, diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index e9ddd66b5e8b3..8d3011e122830 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use std::sync::OnceLock; +use rustc_attr_data_structures::NativeLibKind; use rustc_data_structures::profiling::VerboseTimingGuard; use rustc_fs_util::try_canonicalize; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; @@ -17,69 +18,6 @@ impl Session { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] -#[derive(HashStable_Generic)] -pub enum NativeLibKind { - /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC) - Static { - /// Whether to bundle objects from static library into produced rlib - bundle: Option, - /// Whether to link static library without throwing any object files away - whole_archive: Option, - }, - /// Dynamic library (e.g. `libfoo.so` on Linux) - /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). - Dylib { - /// Whether the dynamic library will be linked only if it satisfies some undefined symbols - as_needed: Option, - }, - /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library. - /// On Linux, it refers to a generated shared library stub. - RawDylib, - /// A macOS-specific kind of dynamic libraries. - Framework { - /// Whether the framework will be linked only if it satisfies some undefined symbols - as_needed: Option, - }, - /// Argument which is passed to linker, relative order with libraries and other arguments - /// is preserved - LinkArg, - - /// Module imported from WebAssembly - WasmImportModule, - - /// The library kind wasn't specified, `Dylib` is currently used as a default. - Unspecified, -} - -impl NativeLibKind { - pub fn has_modifiers(&self) -> bool { - match self { - NativeLibKind::Static { bundle, whole_archive } => { - bundle.is_some() || whole_archive.is_some() - } - NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => { - as_needed.is_some() - } - NativeLibKind::RawDylib - | NativeLibKind::Unspecified - | NativeLibKind::LinkArg - | NativeLibKind::WasmImportModule => false, - } - } - - pub fn is_statically_included(&self) -> bool { - matches!(self, NativeLibKind::Static { .. }) - } - - pub fn is_dllimport(&self) -> bool { - matches!( - self, - NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified - ) - } -} - #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] #[derive(HashStable_Generic)] pub struct NativeLib { diff --git a/tests/crashes/120175.rs b/tests/crashes/120175.rs index c6e7203ff9882..e441454bed294 100644 --- a/tests/crashes/120175.rs +++ b/tests/crashes/120175.rs @@ -2,8 +2,9 @@ //@ needs-rustc-debug-assertions #![feature(extern_types)] +#![feature(raw_dylib_elf)] -#[link(name = "bar", import_name_type = "decorated", kind = "raw-dylib")] +#[link(name = "bar", kind = "raw-dylib")] extern "C" { pub type CrossCrate; } diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 5026687b97b05..0b35b17b2867c 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -81,8 +81,7 @@ #[export_stable = 1] //~^ ERROR malformed #[link] -//~^ ERROR attribute must be of the form -//~| WARN this was previously accepted by the compiler +//~^ ERROR malformed #[link_name] //~^ ERROR malformed #[link_section] diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 56f2be353e768..64b6627aca09c 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `cfg` attribute input - --> $DIR/malformed-attrs.rs:102:1 + --> $DIR/malformed-attrs.rs:101:1 | LL | #[cfg] | ^^^^^^ @@ -8,7 +8,7 @@ LL | #[cfg] | help: must be of the form: `#[cfg(predicate)]` error: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:104:1 + --> $DIR/malformed-attrs.rs:103:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | #[cfg_attr(condition, attribute, other_attribute, ...)] | ++++++++++++++++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:211:1 + --> $DIR/malformed-attrs.rs:210:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -38,7 +38,7 @@ LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:90:1 + --> $DIR/malformed-attrs.rs:89:1 | LL | #[coverage] | ^^^^^^^^^^^ @@ -51,49 +51,49 @@ LL | #[coverage(on)] | ++++ error: malformed `no_sanitize` attribute input - --> $DIR/malformed-attrs.rs:92:1 + --> $DIR/malformed-attrs.rs:91:1 | LL | #[no_sanitize] | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` error: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:99:1 + --> $DIR/malformed-attrs.rs:98:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:106:1 + --> $DIR/malformed-attrs.rs:105:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` error: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:108:1 + --> $DIR/malformed-attrs.rs:107:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:111:5 + --> $DIR/malformed-attrs.rs:110:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` error: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:116:1 + --> $DIR/malformed-attrs.rs:115:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` error: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:123:1 + --> $DIR/malformed-attrs.rs:122:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:132:1 + --> $DIR/malformed-attrs.rs:131:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^^^^ @@ -108,67 +108,67 @@ LL + #[must_not_suspend] | error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:134:1 + --> $DIR/malformed-attrs.rs:133:1 | LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` error: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:173:5 + --> $DIR/malformed-attrs.rs:172:5 | LL | #[linkage] | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:178:1 + --> $DIR/malformed-attrs.rs:177:1 | LL | #[allow] | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:180:1 + --> $DIR/malformed-attrs.rs:179:1 | LL | #[expect] | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:182:1 + --> $DIR/malformed-attrs.rs:181:1 | LL | #[warn] | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:184:1 + --> $DIR/malformed-attrs.rs:183:1 | LL | #[deny] | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:186:1 + --> $DIR/malformed-attrs.rs:185:1 | LL | #[forbid] | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` error: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:188:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:203:1 + --> $DIR/malformed-attrs.rs:202:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:207:1 + --> $DIR/malformed-attrs.rs:206:1 | LL | #[no_link()] | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` error: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:209:1 + --> $DIR/malformed-attrs.rs:208:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ LL + #[macro_use] | error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:214:1 + --> $DIR/malformed-attrs.rs:213:1 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^^^^^^^^ @@ -198,31 +198,31 @@ LL + #[macro_export] | error: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:216:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:99:1 + --> $DIR/malformed-attrs.rs:98:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:116:1 + --> $DIR/malformed-attrs.rs:115:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:123:1 + --> $DIR/malformed-attrs.rs:122:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:216:1 + --> $DIR/malformed-attrs.rs:215:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -249,17 +249,8 @@ LL | #[doc] = 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 -error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` - --> $DIR/malformed-attrs.rs:83:1 - | -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! - = note: for more information, see issue #57571 - error: invalid argument - --> $DIR/malformed-attrs.rs:188:1 + --> $DIR/malformed-attrs.rs:187:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -448,20 +439,29 @@ LL | #[export_stable = 1] | | didn't expect any arguments here | help: must be of the form: `#[export_stable]` +error[E0539]: malformed `link` attribute input + --> $DIR/malformed-attrs.rs:83:1 + | +LL | #[link] + | ^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:86:1 + --> $DIR/malformed-attrs.rs:85:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:88:1 + --> $DIR/malformed-attrs.rs:87:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:97:1 + --> $DIR/malformed-attrs.rs:96:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^----^ @@ -470,7 +470,7 @@ LL | #[no_implicit_prelude = 23] | help: must be of the form: `#[no_implicit_prelude]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:119:1 + --> $DIR/malformed-attrs.rs:118:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -487,7 +487,7 @@ LL + #[must_use] | error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:128:1 + --> $DIR/malformed-attrs.rs:127:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -496,7 +496,7 @@ LL | #[rustc_layout_scalar_valid_range_start] | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:130:1 + --> $DIR/malformed-attrs.rs:129:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -505,7 +505,7 @@ LL | #[rustc_layout_scalar_valid_range_end] | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:155:1 + --> $DIR/malformed-attrs.rs:154:1 | LL | #[marker = 3] | ^^^^^^^^^---^ @@ -514,7 +514,7 @@ LL | #[marker = 3] | help: must be of the form: `#[marker]` error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:157:1 + --> $DIR/malformed-attrs.rs:156:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^--^ @@ -523,7 +523,7 @@ LL | #[fundamental()] | help: must be of the form: `#[fundamental]` error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:165:5 + --> $DIR/malformed-attrs.rs:164:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^---^^ @@ -532,7 +532,7 @@ LL | #[unsafe(ffi_pure = 1)] | help: must be of the form: `#[ffi_pure]` error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:167:5 + --> $DIR/malformed-attrs.rs:166:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ @@ -541,7 +541,7 @@ LL | #[link_ordinal] | help: must be of the form: `#[link_ordinal(ordinal)]` error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:171:5 + --> $DIR/malformed-attrs.rs:170:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^---^^ @@ -550,7 +550,7 @@ LL | #[unsafe(ffi_const = 1)] | help: must be of the form: `#[ffi_const]` error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:191:1 + --> $DIR/malformed-attrs.rs:190:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -559,7 +559,7 @@ LL | #[automatically_derived = 18] | help: must be of the form: `#[automatically_derived]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:197:1 + --> $DIR/malformed-attrs.rs:196:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -568,7 +568,7 @@ LL | #[non_exhaustive = 1] | help: must be of the form: `#[non_exhaustive]` error[E0565]: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:143:5 + --> $DIR/malformed-attrs.rs:142:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^---^ @@ -601,7 +601,7 @@ LL | #[repr] | ^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:149:1 + --> $DIR/malformed-attrs.rs:148:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -609,7 +609,7 @@ LL | #[diagnostic::do_not_recommend()] = note: `#[warn(malformed_diagnostic_attributes)]` on by default warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:138:1 + --> $DIR/malformed-attrs.rs:137:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -617,7 +617,7 @@ LL | #[diagnostic::on_unimplemented] = help: at least one of the `message`, `note` and `label` options are expected warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:140:1 + --> $DIR/malformed-attrs.rs:139:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -634,7 +634,7 @@ LL | #[inline = 5] = note: for more information, see issue #57571 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:94:1 + --> $DIR/malformed-attrs.rs:93:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -643,7 +643,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:223:1 + --> $DIR/malformed-attrs.rs:222:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -652,7 +652,7 @@ LL | #[ignore = 1] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:111:23 + --> $DIR/malformed-attrs.rs:110:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -660,7 +660,7 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:111:23: 111:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}` error: aborting due to 75 previous errors; 3 warnings emitted diff --git a/tests/ui/error-codes/E0458.rs b/tests/ui/error-codes/E0458.rs index 35e7e84d4796d..0e35ba43bfb19 100644 --- a/tests/ui/error-codes/E0458.rs +++ b/tests/ui/error-codes/E0458.rs @@ -1,4 +1,4 @@ -#[link(kind = "wonderful_unicorn")] extern "C" {} //~ ERROR E0458 +#[link(kind = "wonderful_unicorn")] extern "C" {} //~ ERROR malformed `link` attribute input [E0539] //~| ERROR E0459 fn main() { diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr index c13ae4e78629a..9551af7e4435a 100644 --- a/tests/ui/error-codes/E0458.stderr +++ b/tests/ui/error-codes/E0458.stderr @@ -1,8 +1,11 @@ -error[E0458]: unknown link kind `wonderful_unicorn`, expected one of: static, dylib, framework, raw-dylib, link-arg - --> $DIR/E0458.rs:1:15 +error[E0539]: malformed `link` attribute input + --> $DIR/E0458.rs:1:1 | LL | #[link(kind = "wonderful_unicorn")] extern "C" {} - | ^^^^^^^^^^^^^^^^^^^ unknown link kind + | ^^^^^^^^^^^^^^-------------------^^ + | | | + | | valid arguments are "static", "dylib", "framework", "raw-dylib" or "link-arg" + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error[E0459]: `#[link]` attribute requires a `name = "string"` argument --> $DIR/E0458.rs:1:1 @@ -12,5 +15,5 @@ LL | #[link(kind = "wonderful_unicorn")] extern "C" {} error: aborting due to 2 previous errors -Some errors have detailed explanations: E0458, E0459. -For more information about an error, try `rustc --explain E0458`. +Some errors have detailed explanations: E0459, E0539. +For more information about an error, try `rustc --explain E0459`. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index d07201ebbd1aa..af95b7cfd24ac 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -61,7 +61,7 @@ #![doc = "2400"] #![cold] //~ WARN attribute should be applied to a function //~^ WARN this was previously accepted -#![link()] //~ WARN attribute should be applied to an `extern` block +#![link(name = "x")] //~ WARN attribute should be applied to an `extern` block //~^ WARN this was previously accepted #![link_name = "1900"] //~^ WARN attribute should be applied to a foreign function @@ -541,38 +541,38 @@ mod link_section { // Note that this is a `check-pass` test, so it will never invoke the linker. -#[link()] +#[link(name = "x")] //~^ WARN attribute should be applied to an `extern` block //~| WARN this was previously accepted mod link { //~^ NOTE not an `extern` block - mod inner { #![link()] } + mod inner { #![link(name = "x")] } //~^ WARN attribute should be applied to an `extern` block //~| WARN this was previously accepted //~| NOTE not an `extern` block - #[link()] fn f() { } + #[link(name = "x")] 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(name = "x")] 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(name = "x")] 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(name = "x")] impl S { } //~^ WARN attribute should be applied to an `extern` block //~| WARN this was previously accepted //~| NOTE not an `extern` block - #[link()] extern "Rust" {} + #[link(name = "x")] extern "Rust" {} //~^ WARN attribute should be applied to an `extern` block //~| WARN this was previously accepted } diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 5d7d1caeeab0b..be3e30c221e24 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -294,13 +294,13 @@ LL | | } warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:1 | -LL | #[link()] - | ^^^^^^^^^ +LL | #[link(name = "x")] + | ^^^^^^^^^^^^^^^^^^^ ... LL | / mod link { LL | | LL | | -LL | | mod inner { #![link()] } +LL | | mod inner { #![link(name = "x")] } ... | LL | | } | |_- not an `extern` block @@ -376,8 +376,8 @@ LL | #![proc_macro_derive()] warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1 | -LL | #![link()] - | ^^^^^^^^^^ not an `extern` block +LL | #![link(name = "x")] + | ^^^^^^^^^^^^^^^^^^^^ not an `extern` block | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -846,48 +846,48 @@ LL | #[link_section = "1800"] impl S { } warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:550:17 | -LL | mod inner { #![link()] } - | ------------^^^^^^^^^^-- not an `extern` block +LL | mod inner { #![link(name = "x")] } + | ------------^^^^^^^^^^^^^^^^^^^^-- not an `extern` block | = 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 an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5 | -LL | #[link()] fn f() { } - | ^^^^^^^^^ ---------- not an `extern` block +LL | #[link(name = "x")] fn f() { } + | ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block | = 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 an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:560:5 | -LL | #[link()] struct S; - | ^^^^^^^^^ --------- not an `extern` block +LL | #[link(name = "x")] struct S; + | ^^^^^^^^^^^^^^^^^^^ --------- not an `extern` block | = 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 an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:565:5 | -LL | #[link()] type T = S; - | ^^^^^^^^^ ----------- not an `extern` block +LL | #[link(name = "x")] type T = S; + | ^^^^^^^^^^^^^^^^^^^ ----------- not an `extern` block | = 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 an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:570:5 | -LL | #[link()] impl S { } - | ^^^^^^^^^ ---------- not an `extern` block +LL | #[link(name = "x")] impl S { } + | ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block | = 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 an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:575:5 | -LL | #[link()] extern "Rust" {} - | ^^^^^^^^^ +LL | #[link(name = "x")] extern "Rust" {} + | ^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! diff --git a/tests/ui/link-native-libs/issue-43925.rs b/tests/ui/link-native-libs/issue-43925.rs index 1a210887154f4..e3ce71352c06b 100644 --- a/tests/ui/link-native-libs/issue-43925.rs +++ b/tests/ui/link-native-libs/issue-43925.rs @@ -1,4 +1,6 @@ -#[link(name = "foo", cfg("rlib"))] //~ ERROR link cfg must have a single predicate argument +#[link(name = "foo", cfg("rlib"))] +//~^ ERROR link cfg is unstable +//~| ERROR `cfg` predicate key must be an identifier extern "C" {} fn main() {} diff --git a/tests/ui/link-native-libs/issue-43925.stderr b/tests/ui/link-native-libs/issue-43925.stderr index 7cc347c6163b5..82d204222dfd0 100644 --- a/tests/ui/link-native-libs/issue-43925.stderr +++ b/tests/ui/link-native-libs/issue-43925.stderr @@ -1,8 +1,18 @@ -error: link cfg must have a single predicate argument +error[E0658]: link cfg is unstable --> $DIR/issue-43925.rs:1:22 | LL | #[link(name = "foo", cfg("rlib"))] | ^^^^^^^^^^^ + | + = help: add `#![feature(link_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: `cfg` predicate key must be an identifier + --> $DIR/issue-43925.rs:1:26 + | +LL | #[link(name = "foo", cfg("rlib"))] + | ^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/link-native-libs/issue-43926.rs b/tests/ui/link-native-libs/issue-43926.rs index 6d3003552dc0d..293ad3f4ec1ad 100644 --- a/tests/ui/link-native-libs/issue-43926.rs +++ b/tests/ui/link-native-libs/issue-43926.rs @@ -1,4 +1,4 @@ -#[link(name = "foo", cfg())] //~ ERROR link cfg must have a single predicate argument +#[link(name = "foo", cfg())] //~ ERROR malformed `link` attribute input extern "C" {} fn main() {} diff --git a/tests/ui/link-native-libs/issue-43926.stderr b/tests/ui/link-native-libs/issue-43926.stderr index 7c5c50a38a93e..53a19771c60db 100644 --- a/tests/ui/link-native-libs/issue-43926.stderr +++ b/tests/ui/link-native-libs/issue-43926.stderr @@ -1,8 +1,12 @@ -error: link cfg must have a single predicate argument - --> $DIR/issue-43926.rs:1:22 +error[E0805]: malformed `link` attribute input + --> $DIR/issue-43926.rs:1:1 | LL | #[link(name = "foo", cfg())] - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^-----^^ + | | | + | | expected a single argument here + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0805`. diff --git a/tests/ui/link-native-libs/link-attr-validation-early.rs b/tests/ui/link-native-libs/link-attr-validation-early.rs index b9a835fb5e921..89a34ac6ca1d4 100644 --- a/tests/ui/link-native-libs/link-attr-validation-early.rs +++ b/tests/ui/link-native-libs/link-attr-validation-early.rs @@ -1,8 +1,6 @@ // Top-level ill-formed -#[link] //~ ERROR attribute must be of the form - //~| WARN this was previously accepted -#[link = "foo"] //~ ERROR attribute must be of the form - //~| WARN this was previously accepted +#[link] //~ ERROR malformed +#[link = "foo"] //~ ERROR malformed extern "C" {} fn main() {} diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr index 24ad9d825f8d3..f6b3ea857afbc 100644 --- a/tests/ui/link-native-libs/link-attr-validation-early.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr @@ -1,21 +1,21 @@ -error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` +error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-early.rs:2:1 | 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! - = note: for more information, see issue #57571 - = note: `#[deny(ill_formed_attribute_input)]` on by default + | | + | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` - --> $DIR/link-attr-validation-early.rs:4:1 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-early.rs:3:1 | LL | #[link = "foo"] | ^^^^^^^^^^^^^^^ - | - = 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 + | | + | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/link-native-libs/link-attr-validation-late.rs b/tests/ui/link-native-libs/link-attr-validation-late.rs index 4eeb8ba4884ff..d2947b5f61aff 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.rs +++ b/tests/ui/link-native-libs/link-attr-validation-late.rs @@ -1,38 +1,36 @@ #![feature(link_cfg)] // Top-level ill-formed -#[link(name = "...", "literal")] //~ ERROR unexpected `#[link]` argument -#[link(name = "...", unknown)] //~ ERROR unexpected `#[link]` argument +#[link(name = "...", "literal")] //~ ERROR malformed `link` attribute input +#[link(name = "...", unknown)] //~ ERROR malformed `link` attribute input extern "C" {} // Duplicate arguments -#[link(name = "foo", name = "bar")] //~ ERROR multiple `name` arguments -#[link(name = "...", kind = "dylib", kind = "bar")] //~ ERROR multiple `kind` arguments -#[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] //~ ERROR multiple `modifiers` arguments -#[link(name = "...", cfg(false), cfg(false))] //~ ERROR multiple `cfg` arguments -#[link(wasm_import_module = "foo", wasm_import_module = "bar")] //~ ERROR multiple `wasm_import_module` arguments +#[link(name = "foo", name = "bar")] //~ ERROR malformed `link` attribute input +#[link(name = "...", kind = "dylib", kind = "bar")] //~ ERROR malformed `link` attribute input +#[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] //~ ERROR malformed `link` attribute input +#[link(name = "...", cfg(false), cfg(false))] //~ ERROR malformed `link` attribute input +#[link(wasm_import_module = "foo", wasm_import_module = "bar")] //~ ERROR malformed `link` attribute input extern "C" {} // Ill-formed arguments -#[link(name)] //~ ERROR link name must be of the form `name = "string"` - //~| ERROR `#[link]` attribute requires a `name = "string"` argument -#[link(name())] //~ ERROR link name must be of the form `name = "string"` - //~| ERROR `#[link]` attribute requires a `name = "string"` argument -#[link(name = "...", kind)] //~ ERROR link kind must be of the form `kind = "string"` -#[link(name = "...", kind())] //~ ERROR link kind must be of the form `kind = "string"` -#[link(name = "...", modifiers)] //~ ERROR link modifiers must be of the form `modifiers = "string"` -#[link(name = "...", modifiers())] //~ ERROR link modifiers must be of the form `modifiers = "string"` -#[link(name = "...", cfg)] //~ ERROR link cfg must be of the form `cfg(/* predicate */)` -#[link(name = "...", cfg = "literal")] //~ ERROR link cfg must be of the form `cfg(/* predicate */)` -#[link(name = "...", cfg("literal"))] //~ ERROR link cfg must have a single predicate argument -#[link(name = "...", wasm_import_module)] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"` -#[link(name = "...", wasm_import_module())] //~ ERROR wasm import module must be of the form `wasm_import_module = "string"` +#[link(name)] //~ ERROR malformed `link` attribute input +#[link(name())] //~ ERROR malformed `link` attribute input +#[link(name = "...", kind)] //~ ERROR malformed `link` attribute input +#[link(name = "...", kind())] //~ ERROR malformed `link` attribute input +#[link(name = "...", modifiers)] //~ ERROR malformed `link` attribute input +#[link(name = "...", modifiers())] //~ ERROR malformed `link` attribute input +#[link(name = "...", cfg)] //~ ERROR malformed `link` attribute input +#[link(name = "...", cfg = "literal")] //~ ERROR malformed `link` attribute input +#[link(name = "...", cfg("literal"))] //~ ERROR `cfg` predicate key must be an identifier +#[link(name = "...", wasm_import_module)] //~ ERROR malformed `link` attribute input +#[link(name = "...", wasm_import_module())] //~ ERROR malformed `link` attribute input extern "C" {} // Basic modifier validation #[link(name = "...", modifiers = "")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix #[link(name = "...", modifiers = "no-plus-minus")] //~ ERROR invalid linking modifier syntax, expected '+' or '-' prefix -#[link(name = "...", modifiers = "+unknown")] //~ ERROR unknown linking modifier `unknown` +#[link(name = "...", modifiers = "+unknown")] //~ ERROR malformed `link` attribute input #[link(name = "...", modifiers = "+verbatim,+verbatim")] //~ ERROR multiple `verbatim` modifiers extern "C" {} diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index f3989c09360fc..8680f4ec768dd 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -1,147 +1,190 @@ -error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type - --> $DIR/link-attr-validation-late.rs:4:22 +error[E0565]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:4:1 | LL | #[link(name = "...", "literal")] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^---------^^ + | | | + | | didn't expect a literal here + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: unexpected `#[link]` argument, expected one of: name, kind, modifiers, cfg, wasm_import_module, import_name_type - --> $DIR/link-attr-validation-late.rs:5:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:5:1 | LL | #[link(name = "...", unknown)] - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^-------^^ + | | | + | | valid arguments are "name", "kind", "modifiers", "cfg", "wasm_import_module" or "import_name_type" + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: multiple `name` arguments in a single `#[link]` attribute - --> $DIR/link-attr-validation-late.rs:9:22 +error[E0538]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:9:1 | LL | #[link(name = "foo", name = "bar")] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^------------^^ + | | | + | | found `name` used as a key more than once + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: multiple `kind` arguments in a single `#[link]` attribute - --> $DIR/link-attr-validation-late.rs:10:38 +error[E0538]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:10:1 | LL | #[link(name = "...", kind = "dylib", kind = "bar")] - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------^^ + | | | + | | found `kind` used as a key more than once + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: multiple `modifiers` arguments in a single `#[link]` attribute - --> $DIR/link-attr-validation-late.rs:11:47 +error[E0538]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:11:1 | LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^ + | | | + | | found `modifiers` used as a key more than once + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: multiple `cfg` arguments in a single `#[link]` attribute - --> $DIR/link-attr-validation-late.rs:12:34 +error[E0538]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:12:1 | LL | #[link(name = "...", cfg(false), cfg(false))] - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ + | | | + | | found `cfg` used as a key more than once + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: multiple `wasm_import_module` arguments in a single `#[link]` attribute - --> $DIR/link-attr-validation-late.rs:13:36 +error[E0538]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:13:1 | LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------^^ + | | | + | | found `wasm_import_module` used as a key more than once + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link name must be of the form `name = "string"` - --> $DIR/link-attr-validation-late.rs:17:8 - | -LL | #[link(name)] - | ^^^^ - -error[E0459]: `#[link]` attribute requires a `name = "string"` argument +error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:17:1 | LL | #[link(name)] - | ^^^^^^^^^^^^^ missing `name` argument + | ^^^^^^^----^^ + | | | + | | expected this to be of the form `name = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link name must be of the form `name = "string"` - --> $DIR/link-attr-validation-late.rs:19:8 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:18:1 | LL | #[link(name())] - | ^^^^^^ + | ^^^^^^^------^^ + | | | + | | expected this to be of the form `name = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error[E0459]: `#[link]` attribute requires a `name = "string"` argument +error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:19:1 | -LL | #[link(name())] - | ^^^^^^^^^^^^^^^ missing `name` argument - -error: link kind must be of the form `kind = "string"` - --> $DIR/link-attr-validation-late.rs:21:22 - | LL | #[link(name = "...", kind)] - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^----^^ + | | | + | | expected this to be of the form `kind = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link kind must be of the form `kind = "string"` - --> $DIR/link-attr-validation-late.rs:22:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:20:1 | LL | #[link(name = "...", kind())] - | ^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | expected this to be of the form `kind = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link modifiers must be of the form `modifiers = "string"` - --> $DIR/link-attr-validation-late.rs:23:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:21:1 | LL | #[link(name = "...", modifiers)] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^---------^^ + | | | + | | expected this to be of the form `modifiers = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link modifiers must be of the form `modifiers = "string"` - --> $DIR/link-attr-validation-late.rs:24:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:22:1 | LL | #[link(name = "...", modifiers())] - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^-----------^^ + | | | + | | expected this to be of the form `modifiers = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link cfg must be of the form `cfg(/* predicate */)` - --> $DIR/link-attr-validation-late.rs:25:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:23:1 | LL | #[link(name = "...", cfg)] - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^---^^ + | | | + | | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link cfg must be of the form `cfg(/* predicate */)` - --> $DIR/link-attr-validation-late.rs:26:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:24:1 | LL | #[link(name = "...", cfg = "literal")] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^---------------^^ + | | | + | | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: link cfg must have a single predicate argument - --> $DIR/link-attr-validation-late.rs:27:22 +error: `cfg` predicate key must be an identifier + --> $DIR/link-attr-validation-late.rs:25:26 | LL | #[link(name = "...", cfg("literal"))] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^ -error: wasm import module must be of the form `wasm_import_module = "string"` - --> $DIR/link-attr-validation-late.rs:28:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:26:1 | LL | #[link(name = "...", wasm_import_module)] - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^------------------^^ + | | | + | | expected this to be of the form `wasm_import_module = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: wasm import module must be of the form `wasm_import_module = "string"` - --> $DIR/link-attr-validation-late.rs:29:22 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:27:1 | LL | #[link(name = "...", wasm_import_module())] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^--------------------^^ + | | | + | | expected this to be of the form `wasm_import_module = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed - --> $DIR/link-attr-validation-late.rs:33:34 + --> $DIR/link-attr-validation-late.rs:31:34 | LL | #[link(name = "...", modifiers = "")] | ^^ error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed - --> $DIR/link-attr-validation-late.rs:34:34 + --> $DIR/link-attr-validation-late.rs:32:34 | LL | #[link(name = "...", modifiers = "no-plus-minus")] | ^^^^^^^^^^^^^^^ -error: unknown linking modifier `unknown`, expected one of: bundle, verbatim, whole-archive, as-needed - --> $DIR/link-attr-validation-late.rs:35:34 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:33:1 | LL | #[link(name = "...", modifiers = "+unknown")] - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ + | | | + | | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error: multiple `verbatim` modifiers in a single `modifiers` argument - --> $DIR/link-attr-validation-late.rs:36:34 + --> $DIR/link-attr-validation-late.rs:34:34 | LL | #[link(name = "...", modifiers = "+verbatim,+verbatim")] | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 24 previous errors +error: aborting due to 22 previous errors -For more information about this error, try `rustc --explain E0459`. +Some errors have detailed explanations: E0538, E0539, E0565. +For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/link-native-libs/modifiers-override-4.rs b/tests/ui/link-native-libs/modifiers-override-4.rs new file mode 100644 index 0000000000000..cc5b07e20cc6e --- /dev/null +++ b/tests/ui/link-native-libs/modifiers-override-4.rs @@ -0,0 +1,12 @@ +#[link(name = "foo")] +#[link( +//~^ ERROR malformed `link` attribute input + name = "bar", + kind = "static", + modifiers = "+whole-archive,-whole-archive", + //~^ ERROR multiple `whole-archive` modifiers in a single `modifiers` argument + modifiers = "+bundle" +)] +extern "C" {} + +fn main() {} diff --git a/tests/ui/link-native-libs/modifiers-override-4.stderr b/tests/ui/link-native-libs/modifiers-override-4.stderr new file mode 100644 index 0000000000000..dcbbfa53e1620 --- /dev/null +++ b/tests/ui/link-native-libs/modifiers-override-4.stderr @@ -0,0 +1,22 @@ +error[E0538]: malformed `link` attribute input + --> $DIR/modifiers-override-4.rs:2:1 + | +LL | / #[link( +LL | | +LL | | name = "bar", +LL | | kind = "static", +... | +LL | | modifiers = "+bundle" + | | --------------------- found `modifiers` used as a key more than once +LL | | )] + | |__^ help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + +error: multiple `whole-archive` modifiers in a single `modifiers` argument + --> $DIR/modifiers-override-4.rs:6:17 + | +LL | modifiers = "+whole-archive,-whole-archive", + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0538`. diff --git a/tests/ui/link-native-libs/modifiers-override.rs b/tests/ui/link-native-libs/modifiers-override.rs index cd2d003664ac2..a44b7d37ed810 100644 --- a/tests/ui/link-native-libs/modifiers-override.rs +++ b/tests/ui/link-native-libs/modifiers-override.rs @@ -4,13 +4,8 @@ #[link( name = "bar", kind = "static", - modifiers = "+whole-archive,-whole-archive", - //~^ ERROR multiple `whole-archive` modifiers in a single `modifiers` argument - modifiers = "+bundle" - //~^ ERROR multiple `modifiers` arguments in a single `#[link]` attribute )] extern "C" {} //~^ ERROR overriding linking modifiers from command line is not supported -//~| ERROR overriding linking modifiers from command line is not supported fn main() {} diff --git a/tests/ui/link-native-libs/modifiers-override.stderr b/tests/ui/link-native-libs/modifiers-override.stderr index 64427651e9f62..3cc99c96c7c30 100644 --- a/tests/ui/link-native-libs/modifiers-override.stderr +++ b/tests/ui/link-native-libs/modifiers-override.stderr @@ -1,28 +1,8 @@ -error: multiple `modifiers` arguments in a single `#[link]` attribute - --> $DIR/modifiers-override.rs:9:5 - | -LL | modifiers = "+bundle" - | ^^^^^^^^^^^^^^^^^^^^^ - -error: multiple `whole-archive` modifiers in a single `modifiers` argument - --> $DIR/modifiers-override.rs:7:17 - | -LL | modifiers = "+whole-archive,-whole-archive", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: overriding linking modifiers from command line is not supported - --> $DIR/modifiers-override.rs:12:1 - | -LL | extern "C" {} - | ^^^^^^^^^^^^^ - error: overriding linking modifiers from command line is not supported - --> $DIR/modifiers-override.rs:12:1 + --> $DIR/modifiers-override.rs:8:1 | LL | extern "C" {} | ^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs index 5982c771033d0..36d466151804d 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs @@ -10,7 +10,7 @@ fn test() {} //~^ ERROR attribute should be applied to a foreign function or static static mut imported_val: i32 = 123; -#[link(name = "exporter", kind = "raw-dylib")] +#[link(name = "exporter")] extern "C" { #[link_ordinal(13)] fn imported_function(); diff --git a/tests/ui/malformed/malformed-regressions.rs b/tests/ui/malformed/malformed-regressions.rs index f0a7aac59c1cc..407920c4e4ece 100644 --- a/tests/ui/malformed/malformed-regressions.rs +++ b/tests/ui/malformed/malformed-regressions.rs @@ -4,9 +4,7 @@ //~^ WARN this was previously accepted #[inline = ""] //~ ERROR valid forms for the attribute are //~^ WARN this was previously accepted -#[link] //~ ERROR attribute must be of the form -//~^ WARN this was previously accepted -#[link = ""] //~ ERROR attribute must be of the form -//~^ WARN this was previously accepted +#[link] //~ ERROR malformed +#[link = ""] //~ ERROR malformed fn main() {} diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 8c22919a1c2f1..6e5d0d3d33eb4 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -8,23 +8,23 @@ LL | #[doc] = note: for more information, see issue #57571 = note: `#[deny(ill_formed_attribute_input)]` on by default -error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` +error[E0539]: malformed `link` attribute input --> $DIR/malformed-regressions.rs:7:1 | 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! - = note: for more information, see issue #57571 + | | + | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` - --> $DIR/malformed-regressions.rs:9:1 +error[E0539]: malformed `link` attribute input + --> $DIR/malformed-regressions.rs:8:1 | 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! - = note: for more information, see issue #57571 + | | + | expected this to be a list + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` --> $DIR/malformed-regressions.rs:3:1 @@ -46,3 +46,4 @@ LL | #[inline = ""] error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/parser/bad-lit-suffixes.rs b/tests/ui/parser/bad-lit-suffixes.rs index 0a01bb84f01a3..31d0fa22e8ab5 100644 --- a/tests/ui/parser/bad-lit-suffixes.rs +++ b/tests/ui/parser/bad-lit-suffixes.rs @@ -38,6 +38,7 @@ fn g() {} #[link(name = "string"suffix)] //~^ ERROR suffixes on string literals are invalid +//~| ERROR `#[link]` attribute requires a `name = "string"` argument extern "C" {} #[rustc_layout_scalar_valid_range_start(0suffix)] diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr index 7876d75c5a427..28464ea2d5374 100644 --- a/tests/ui/parser/bad-lit-suffixes.stderr +++ b/tests/ui/parser/bad-lit-suffixes.stderr @@ -29,7 +29,7 @@ LL | #[link(name = "string"suffix)] | ^^^^^^^^^^^^^^ invalid suffix `suffix` error: invalid suffix `suffix` for number literal - --> $DIR/bad-lit-suffixes.rs:43:41 + --> $DIR/bad-lit-suffixes.rs:44:41 | LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | ^^^^^^^ invalid suffix `suffix` @@ -167,8 +167,14 @@ LL - #[must_use = "string"suffix] LL + #[must_use] | +error[E0459]: `#[link]` attribute requires a `name = "string"` argument + --> $DIR/bad-lit-suffixes.rs:39:1 + | +LL | #[link(name = "string"suffix)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument + error[E0805]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/bad-lit-suffixes.rs:43:1 + --> $DIR/bad-lit-suffixes.rs:44:1 | LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^ @@ -176,7 +182,7 @@ LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | | expected a single argument here | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` -error: aborting due to 22 previous errors; 2 warnings emitted +error: aborting due to 23 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0539, E0805. -For more information about an error, try `rustc --explain E0539`. +Some errors have detailed explanations: E0459, E0539, E0805. +For more information about an error, try `rustc --explain E0459`. diff --git a/tests/ui/wasm/wasm-import-module.rs b/tests/ui/wasm/wasm-import-module.rs index 2b3bca9a411bb..c38fcb1a0006e 100644 --- a/tests/ui/wasm/wasm-import-module.rs +++ b/tests/ui/wasm/wasm-import-module.rs @@ -1,12 +1,12 @@ #![feature(link_cfg)] -#[link(name = "...", wasm_import_module)] //~ ERROR: must be of the form +#[link(name = "...", wasm_import_module)] //~ ERROR: malformed `link` attribute input extern "C" {} -#[link(name = "...", wasm_import_module(x))] //~ ERROR: must be of the form +#[link(name = "...", wasm_import_module(x))] //~ ERROR: malformed `link` attribute input extern "C" {} -#[link(name = "...", wasm_import_module())] //~ ERROR: must be of the form +#[link(name = "...", wasm_import_module())] //~ ERROR: malformed `link` attribute input extern "C" {} #[link(wasm_import_module = "foo", name = "bar")] //~ ERROR: `wasm_import_module` is incompatible with other arguments diff --git a/tests/ui/wasm/wasm-import-module.stderr b/tests/ui/wasm/wasm-import-module.stderr index 84f437941a799..6b9cfa36263e9 100644 --- a/tests/ui/wasm/wasm-import-module.stderr +++ b/tests/ui/wasm/wasm-import-module.stderr @@ -1,20 +1,29 @@ -error: wasm import module must be of the form `wasm_import_module = "string"` - --> $DIR/wasm-import-module.rs:3:22 +error[E0539]: malformed `link` attribute input + --> $DIR/wasm-import-module.rs:3:1 | LL | #[link(name = "...", wasm_import_module)] - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^------------------^^ + | | | + | | expected this to be of the form `wasm_import_module = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: wasm import module must be of the form `wasm_import_module = "string"` - --> $DIR/wasm-import-module.rs:6:22 +error[E0539]: malformed `link` attribute input + --> $DIR/wasm-import-module.rs:6:1 | LL | #[link(name = "...", wasm_import_module(x))] - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^---------------------^^ + | | | + | | expected this to be of the form `wasm_import_module = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` -error: wasm import module must be of the form `wasm_import_module = "string"` - --> $DIR/wasm-import-module.rs:9:22 +error[E0539]: malformed `link` attribute input + --> $DIR/wasm-import-module.rs:9:1 | LL | #[link(name = "...", wasm_import_module())] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^--------------------^^ + | | | + | | expected this to be of the form `wasm_import_module = "..."` + | help: must be of the form: `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes --> $DIR/wasm-import-module.rs:12:8 @@ -36,3 +45,4 @@ LL | #[link(wasm_import_module = "foo", cfg(false))] error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0539`.