From 4bd0e65bde6fdfc9b1e456336c1b30cb35e4c51e Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Mon, 15 Dec 2025 10:47:58 +0100 Subject: [PATCH 1/6] Port `#[rustc_legacy_const_generics]` to use attribute parser --- compiler/rustc_ast_lowering/src/lib.rs | 36 ++--- .../src/attributes/rustc_internal.rs | 46 +++++++ compiler/rustc_attr_parsing/src/context.rs | 7 +- .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir/src/attrs/pretty_printing.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 1 - compiler/rustc_passes/messages.ftl | 3 - compiler/rustc_passes/src/check_attr.rs | 64 +++------ compiler/rustc_passes/src/errors.rs | 7 - compiler/rustc_resolve/src/lib.rs | 63 ++++----- src/librustdoc/clean/mod.rs | 38 +++--- ...d-rustc_legacy_const_generics-arguments.rs | 20 +-- ...stc_legacy_const_generics-arguments.stderr | 125 +++++++++++------- 14 files changed, 227 insertions(+), 189 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 10093da97fe34..d0871b0b98f45 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -237,25 +237,27 @@ impl SpanLowerer { #[extension(trait ResolverAstLoweringExt)] impl ResolverAstLowering { fn legacy_const_generic_args(&self, expr: &Expr) -> Option> { - if let ExprKind::Path(None, path) = &expr.kind { - // Don't perform legacy const generics rewriting if the path already - // has generic arguments. - if path.segments.last().unwrap().args.is_some() { - return None; - } + let ExprKind::Path(None, path) = &expr.kind else { + return None; + }; - if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? { - // We only support cross-crate argument rewriting. Uses - // within the same crate should be updated to use the new - // const generics style. - if def_id.is_local() { - return None; - } + // Don't perform legacy const generics rewriting if the path already + // has generic arguments. + if path.segments.last().unwrap().args.is_some() { + return None; + } - if let Some(v) = self.legacy_const_generic_args.get(&def_id) { - return v.clone(); - } - } + let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; + + // We only support cross-crate argument rewriting. Uses + // within the same crate should be updated to use the new + // const generics style. + if def_id.is_local() { + return None; + } + + if let Some(v) = self.legacy_const_generic_args.get(&def_id) { + return v.clone(); } None diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 4be141651ae64..f04d4ceea35a1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,3 +1,5 @@ +use rustc_ast::{LitIntType, LitKind, MetaItemLit}; + use super::prelude::*; use super::util::parse_single_integer; use crate::session_diagnostics::RustcScalableVectorCountOutOfRange; @@ -41,6 +43,50 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser } } +pub(crate) struct RustcLegacyConstGenericsParser; + +impl SingleAttributeParser for RustcLegacyConstGenericsParser { + const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const TEMPLATE: AttributeTemplate = template!(List: &["N"]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let ArgParser::List(meta_items) = args else { + cx.expected_list(cx.attr_span, args); + return None; + }; + + let mut parsed_indexes = ThinVec::new(); + let mut errored = false; + + for possible_index in meta_items.mixed() { + if let MetaItemOrLitParser::Lit(MetaItemLit { + kind: LitKind::Int(index, LitIntType::Unsuffixed), + .. + }) = possible_index + { + parsed_indexes.push((index.0 as usize, possible_index.span())); + } else { + cx.expected_integer_literal(possible_index.span()); + errored = true; + } + } + if errored { + return None; + } else if parsed_indexes.is_empty() { + cx.expected_at_least_one_argument(args.span()?); + return None; + } + + Some(AttributeKind::RustcLegacyConstGenerics { + fn_indexes: parsed_indexes, + attr_span: cx.attr_span, + }) + } +} + pub(crate) struct RustcObjectLifetimeDefaultParser; impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9c7006f840241..242e0c013bc08 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -59,9 +59,9 @@ use crate::attributes::proc_macro_attrs::{ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ - RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser, - RustcObjectLifetimeDefaultParser, RustcScalableVectorParser, - RustcSimdMonomorphizeLaneLimitParser, + RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, + RustcLegacyConstGenericsParser, RustcMainParser, RustcObjectLifetimeDefaultParser, + RustcScalableVectorParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -209,6 +209,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5f38eaf4d5f4c..177a4247e6f01 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -869,6 +869,9 @@ pub enum AttributeKind { /// Represents `#[rustc_layout_scalar_valid_range_start]`. RustcLayoutScalarValidRangeStart(Box, Span), + /// Represents `#[rustc_legacy_const_generics]` + RustcLegacyConstGenerics { fn_indexes: ThinVec<(usize, Span)>, attr_span: Span }, + /// Represents `#[rustc_main]`. RustcMain, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 90fb0497a5b20..10b7af14aeae5 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -92,6 +92,7 @@ impl AttributeKind { RustcCoherenceIsCore(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, + RustcLegacyConstGenerics { .. } => Yes, RustcMain => No, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, diff --git a/compiler/rustc_hir/src/attrs/pretty_printing.rs b/compiler/rustc_hir/src/attrs/pretty_printing.rs index 8bd267a1c2563..f8ac2a547ca8f 100644 --- a/compiler/rustc_hir/src/attrs/pretty_printing.rs +++ b/compiler/rustc_hir/src/attrs/pretty_printing.rs @@ -169,7 +169,7 @@ macro_rules! print_tup { print_tup!(A B C D E F G H); print_skip!(Span, (), ErrorGuaranteed); -print_disp!(u16, u128, bool, NonZero, Limit); +print_disp!(u16, u128, usize, bool, NonZero, Limit); print_debug!( Symbol, Ident, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 91e6e6326c095..2021f175cd848 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -197,7 +197,6 @@ pub struct ResolverGlobalCtxt { #[derive(Debug)] pub struct ResolverAstLowering { pub legacy_const_generic_args: FxHashMap>>, - /// Resolutions for nodes that have a single resolution. pub partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 21191085253bd..0f206edcc7758 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -478,9 +478,6 @@ passes_rustc_legacy_const_generics_index_exceed = *[other] arguments } -passes_rustc_legacy_const_generics_index_negative = - arguments should be non-negative integers - passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics .label = non-const generic parameter diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e836277e9761a..f4896a8ca878a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,9 +10,10 @@ use std::collections::hash_map::Entry; use std::slice; use rustc_abi::{Align, ExternAbi, Size}; -use rustc_ast::{AttrStyle, LitKind, MetaItemKind, ast}; +use rustc_ast::{AttrStyle, MetaItemKind, ast}; use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, @@ -211,6 +212,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => { self.check_macro_export(hir_id, *span, target) }, + Attribute::Parsed(AttributeKind::RustcLegacyConstGenerics{attr_span, fn_indexes}) => { + self.check_rustc_legacy_const_generics(item, *attr_span, fn_indexes) + }, Attribute::Parsed(AttributeKind::Doc(attr)) => self.check_doc_attrs(attr, hir_id, target), Attribute::Parsed(AttributeKind::EiiImpls(impls)) => { self.check_eii_impl(impls, target) @@ -306,9 +310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_never_returns_null_ptr, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } - [sym::rustc_legacy_const_generics, ..] => { - self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item) - } [sym::rustc_lint_query_instability, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } @@ -1218,33 +1219,17 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, - hir_id: HirId, - attr: &Attribute, - span: Span, - target: Target, item: Option>, + attr_span: Span, + index_list: &ThinVec<(usize, Span)>, ) { - let is_function = matches!(target, Target::Fn); - if !is_function { - self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { - attr_span: attr.span(), - defn_span: span, - on_crate: hir_id == CRATE_HIR_ID, - }); - return; - } - - let Some(list) = attr.meta_item_list() else { - // The attribute form is validated on AST. - return; - }; - let Some(ItemLike::Item(Item { kind: ItemKind::Fn { sig: FnSig { decl, .. }, generics, .. }, .. })) = item else { - bug!("should be a function item"); + // No error here, since it's already given by the parser + return; }; for param in generics.params { @@ -1252,7 +1237,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hir::GenericParamKind::Const { .. } => {} _ => { self.dcx().emit_err(errors::RustcLegacyConstGenericsOnly { - attr_span: attr.span(), + attr_span, param_span: param.span, }); return; @@ -1260,34 +1245,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if list.len() != generics.params.len() { + if index_list.len() != generics.params.len() { self.dcx().emit_err(errors::RustcLegacyConstGenericsIndex { - attr_span: attr.span(), + attr_span, generics_span: generics.span, }); return; } - let arg_count = decl.inputs.len() as u128 + generics.params.len() as u128; - let mut invalid_args = vec![]; - for meta in list { - if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) { - if *val >= arg_count { - let span = meta.span(); - self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed { - span, - arg_count: arg_count as usize, - }); - return; - } - } else { - invalid_args.push(meta.span()); + let arg_count = decl.inputs.len() + generics.params.len(); + for (index, span) in index_list { + if *index >= arg_count { + self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexExceed { + span: *span, + arg_count, + }); } } - - if !invalid_args.is_empty() { - self.dcx().emit_err(errors::RustcLegacyConstGenericsIndexNegative { invalid_args }); - } } /// Helper function for checking that the provided attribute is only applied to a function or diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7abd2c703aeb4..8ead69da9916c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -290,13 +290,6 @@ pub(crate) struct RustcLegacyConstGenericsIndexExceed { pub arg_count: usize, } -#[derive(Diagnostic)] -#[diag(passes_rustc_legacy_const_generics_index_negative)] -pub(crate) struct RustcLegacyConstGenericsIndexNegative { - #[primary_span] - pub invalid_args: Vec, -} - #[derive(Diagnostic)] #[diag(passes_rustc_dirty_clean)] pub(crate) struct RustcDirtyClean { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b3141406e467e..d373d6136b523 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -44,7 +44,7 @@ use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::{ self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs, - LitKind, NodeId, Path, attr, + NodeId, Path, attr, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; @@ -54,7 +54,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::BUILTIN_ATTRIBUTES; -use rustc_hir::attrs::StrippedCfgItem; +use rustc_hir::attrs::{AttributeKind, StrippedCfgItem}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{ self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, MacroKinds, NonMacroAttrKind, PartialRes, @@ -62,7 +62,7 @@ use rustc_hir::def::{ }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::DisambiguatorState; -use rustc_hir::{PrimTy, TraitCandidate}; +use rustc_hir::{PrimTy, TraitCandidate, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::CStore; use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; @@ -1676,8 +1676,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { node_id_to_def_id, disambiguator: DisambiguatorState::new(), placeholder_field_indices: Default::default(), - invocation_parents, legacy_const_generic_args: Default::default(), + invocation_parents, item_generics_num_lifetimes: Default::default(), trait_impls: Default::default(), confused_type_with_std_module: Default::default(), @@ -2396,40 +2396,33 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// `#[rustc_legacy_const_generics]` and returns the argument index list /// from the attribute. fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option> { - if let ExprKind::Path(None, path) = &expr.kind { - // Don't perform legacy const generics rewriting if the path already - // has generic arguments. - if path.segments.last().unwrap().args.is_some() { - return None; - } - - let res = self.partial_res_map.get(&expr.id)?.full_res()?; - if let Res::Def(def::DefKind::Fn, def_id) = res { - // We only support cross-crate argument rewriting. Uses - // within the same crate should be updated to use the new - // const generics style. - if def_id.is_local() { - return None; - } + let ExprKind::Path(None, path) = &expr.kind else { + return None; + }; + // Don't perform legacy const generics rewriting if the path already + // has generic arguments. + if path.segments.last().unwrap().args.is_some() { + return None; + } - if let Some(v) = self.legacy_const_generic_args.get(&def_id) { - return v.clone(); - } + let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; - let attr = self.tcx.get_attr(def_id, sym::rustc_legacy_const_generics)?; - let mut ret = Vec::new(); - for meta in attr.meta_item_list()? { - match meta.lit()?.kind { - LitKind::Int(a, _) => ret.push(a.get() as usize), - _ => panic!("invalid arg index"), - } - } - // Cache the lookup to avoid parsing attributes for an item multiple times. - self.legacy_const_generic_args.insert(def_id, Some(ret.clone())); - return Some(ret); - } + // We only support cross-crate argument rewriting. Uses + // within the same crate should be updated to use the new + // const generics style. + if def_id.is_local() { + return None; } - None + + let indexes = find_attr!( + // we can use parsed attrs here since for other crates they're already available + self.tcx.get_all_attrs(def_id), + AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes + ) + .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect()); + + self.legacy_const_generic_args.insert(def_id, indexes.clone()); + indexes } fn resolve_main(&mut self) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dd5c50d2ba37c..764b3a0acdb6f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1,7 +1,7 @@ //! This module defines the primary IR[^1] used in rustdoc together with the procedures that //! transform rustc data types into it. //! -//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][ast]. +//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][rustc_ast]. //! //! There are two kinds of transformation — *cleaning* — procedures: //! @@ -38,6 +38,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, In use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::codes::*; use rustc_errors::{FatalError, struct_span_code_err}; +use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, DocAttribute, DocInline}; use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; @@ -54,7 +55,6 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_trait_selection::traits::wf::object_region_bounds; use tracing::{debug, instrument}; use utils::*; -use {rustc_ast as ast, rustc_hir as hir}; pub(crate) use self::cfg::{CfgInfo, extract_cfg_from_attrs}; pub(crate) use self::types::*; @@ -1026,26 +1026,20 @@ fn clean_fn_or_proc_macro<'tcx>( /// `rustc_legacy_const_generics`. More information in /// . fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attribute]) { - for meta_item_list in attrs - .iter() - .filter(|a| a.has_name(sym::rustc_legacy_const_generics)) - .filter_map(|a| a.meta_item_list()) - { - for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.lit()).enumerate() { - match literal.kind { - ast::LitKind::Int(a, _) => { - let GenericParamDef { name, kind, .. } = func.generics.params.remove(0); - if let GenericParamDefKind::Const { ty, .. } = kind { - func.decl.inputs.insert( - a.get() as _, - Parameter { name: Some(name), type_: *ty, is_const: true }, - ); - } else { - panic!("unexpected non const in position {pos}"); - } - } - _ => panic!("invalid arg index"), - } + let Some(indexes) = + find_attr!(attrs, AttributeKind::RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes) + else { + return; + }; + + for (pos, (index, _)) in indexes.iter().enumerate() { + let GenericParamDef { name, kind, .. } = func.generics.params.remove(0); + if let GenericParamDefKind::Const { ty, .. } = kind { + func.decl + .inputs + .insert(*index, Parameter { name: Some(name), type_: *ty, is_const: true }); + } else { + panic!("unexpected non const in position {pos}"); } } } diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs index 73a0363904aeb..03a28fac95def 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs @@ -9,20 +9,24 @@ fn foo2() {} #[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments fn foo3(_: u8) {} -#[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers +#[rustc_legacy_const_generics(a)] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo4() {} -#[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers +#[rustc_legacy_const_generics(1, a, 2, b)] +//~^ ERROR malformed `rustc_legacy_const_generics` attribute input +//~^^ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo5() {} -#[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function +#[rustc_legacy_const_generics(0)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on structs struct S; -#[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes +#[rustc_legacy_const_generics(0usize)] +//~^ ERROR suffixed literals are not allowed in attributes +//~^^ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo6() {} extern "C" { - #[rustc_legacy_const_generics(1)] //~ ERROR attribute should be applied to a function + #[rustc_legacy_const_generics(1)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on foreign functions fn foo7(); //~ ERROR foreign items may not have const parameters } @@ -30,14 +34,14 @@ extern "C" { fn foo8() {} impl S { - #[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function + #[rustc_legacy_const_generics(0)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on inherent methods fn foo9() {} } -#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute +#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn bar1() {} -#[rustc_legacy_const_generics = 1] //~ ERROR malformed `rustc_legacy_const_generics` attribute +#[rustc_legacy_const_generics = 1] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn bar2() {} fn main() {} diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr index 1ced1433fe955..e4da6c86c83e5 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr @@ -1,22 +1,88 @@ +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:12:1 + | +LL | #[rustc_legacy_const_generics(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:1 + | +LL | #[rustc_legacy_const_generics(1, a, 2, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:1 + | +LL | #[rustc_legacy_const_generics(1, a, 2, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on structs + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:20:1 + | +LL | #[rustc_legacy_const_generics(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + error: suffixed literals are not allowed in attributes - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:21:31 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:23:31 | LL | #[rustc_legacy_const_generics(0usize)] | ^^^^^^ | = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) -error: malformed `rustc_legacy_const_generics` attribute input - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:37:1 +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:23:1 + | +LL | #[rustc_legacy_const_generics(0usize)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on foreign functions + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:5 + | +LL | #[rustc_legacy_const_generics(1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on inherent methods + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:37:5 + | +LL | #[rustc_legacy_const_generics(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:41:1 | LL | #[rustc_legacy_const_generics] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` -error: malformed `rustc_legacy_const_generics` attribute input - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:40:1 +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:44:1 | LL | #[rustc_legacy_const_generics = 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | expected this to be a list + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` error: #[rustc_legacy_const_generics] must have one index for each generic parameter --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:1 @@ -38,58 +104,23 @@ error: index exceeds number of arguments LL | #[rustc_legacy_const_generics(2)] | ^ there are only 2 arguments -error: arguments should be non-negative integers - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:12:31 - | -LL | #[rustc_legacy_const_generics(a)] - | ^ - -error: arguments should be non-negative integers - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:34 - | -LL | #[rustc_legacy_const_generics(1, a, 2, b)] - | ^ ^ - -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:18:1 - | -LL | #[rustc_legacy_const_generics(0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | struct S; - | --------- not a function definition - error: #[rustc_legacy_const_generics] functions must only have const generics - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:1 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:1 | LL | #[rustc_legacy_const_generics(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | fn foo8() {} | - non-const generic parameter -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:5 - | -LL | #[rustc_legacy_const_generics(0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn foo9() {} - | ---------------------------- not a function definition - -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:5 - | -LL | #[rustc_legacy_const_generics(1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn foo7(); - | -------------------------- not a function definition - error[E0044]: foreign items may not have const parameters - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:30:5 | LL | fn foo7(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters | = help: replace the const parameters with concrete consts -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors -For more information about this error, try `rustc --explain E0044`. +Some errors have detailed explanations: E0044, E0539. +For more information about an error, try `rustc --explain E0044`. From 793d990d11fa7bf38677d27c88eccea6e360a783 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Tue, 16 Dec 2025 21:33:28 +0100 Subject: [PATCH 2/6] Emit a proper error if we fail to find libEnzyme --- compiler/rustc_codegen_llvm/messages.ftl | 3 ++- compiler/rustc_codegen_llvm/src/errors.rs | 5 +++++ compiler/rustc_codegen_llvm/src/lib.rs | 5 ++++- .../rustc_codegen_llvm/src/llvm/enzyme_ffi.rs | 18 ++++++++---------- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 0e7b00d0bcb70..b3ef9840f5dc2 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,9 +1,10 @@ +codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. Did you install it via rustup? + codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err} - codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture codegen_llvm_from_llvm_diag = {$message} diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index dd9fde0b08c6f..f2e147b1ee0ad 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -32,6 +32,11 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { } } +#[cfg(feature = "llvm_enzyme")] +#[derive(Diagnostic)] +#[diag(codegen_llvm_autodiff_component_unavailable)] +pub(crate) struct AutoDiffComponentUnavailable; + #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] pub(crate) struct AutoDiffWithoutLto; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c51b334d95e16..4d0f8dbb9302a 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -13,6 +13,7 @@ #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(macro_derive)] +#![feature(once_cell_try)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] // tidy-alphabetical-end @@ -247,7 +248,9 @@ impl CodegenBackend for LlvmCodegenBackend { use crate::back::lto::enable_autodiff_settings; if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { - drop(llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot)); + if let Err(_) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable); + } enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 28923bf2743e4..956a4e43a7de0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -199,15 +199,13 @@ pub(crate) mod Enzyme_AD { /// Safe to call multiple times - subsequent calls are no-ops due to OnceLock. pub(crate) fn get_or_init( sysroot: &rustc_session::config::Sysroot, - ) -> MutexGuard<'static, Self> { - ENZYME_INSTANCE - .get_or_init(|| { - Self::call_dynamic(sysroot) - .unwrap_or_else(|e| bug!("failed to load Enzyme: {e}")) - .into() - }) - .lock() - .unwrap() + ) -> Result, Box> { + let mtx: &'static Mutex = ENZYME_INSTANCE.get_or_try_init(|| { + let w = Self::call_dynamic(sysroot)?; + Ok::<_, Box>(Mutex::new(w)) + })?; + + Ok(mtx.lock().unwrap()) } /// Get the EnzymeWrapper instance. Panics if not initialized. @@ -475,7 +473,7 @@ pub(crate) mod Fallback_AD { impl EnzymeWrapper { pub(crate) fn get_or_init( _sysroot: &rustc_session::config::Sysroot, - ) -> MutexGuard<'static, Self> { + ) -> Result, Box> { unimplemented!("Enzyme not available: build with llvm_enzyme feature") } From 6847bd0facd27b6a3a2d81eb457d1afb33352539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 20:38:23 +0100 Subject: [PATCH 3/6] Revert 147888 --- src/bootstrap/src/core/config/toml/llvm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/toml/llvm.rs b/src/bootstrap/src/core/config/toml/llvm.rs index 9523f80214849..9751837a88794 100644 --- a/src/bootstrap/src/core/config/toml/llvm.rs +++ b/src/bootstrap/src/core/config/toml/llvm.rs @@ -117,7 +117,7 @@ pub fn check_incompatible_options_for_ci_llvm( enable_warnings, download_ci_llvm: _, build_config, - enzyme: _, + enzyme, } = ci_llvm_config; err!(current_llvm_config.optimize, optimize); @@ -139,6 +139,7 @@ pub fn check_incompatible_options_for_ci_llvm( err!(current_llvm_config.clang, clang); err!(current_llvm_config.build_config, build_config); err!(current_llvm_config.plugins, plugins); + err!(current_llvm_config.enzyme, enzyme); warn!(current_llvm_config.enable_warnings, enable_warnings); From 7463b150441f8a43f59b284a42af4ce6cffe6a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 16 Dec 2025 20:40:29 +0100 Subject: [PATCH 4/6] Print warning if LLVM CMake directory does not exist --- src/bootstrap/src/core/build_steps/llvm.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index db2a76c4a2dff..51a791daef280 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -925,7 +925,7 @@ impl Step for Enzyme { } let target = self.target; - let LlvmResult { host_llvm_config, .. } = builder.ensure(Llvm { target: self.target }); + let LlvmResult { host_llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target }); static STAMP_HASH_MEMO: OnceLock = OnceLock::new(); let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| { @@ -955,15 +955,20 @@ impl Step for Enzyme { return out_dir; } + if !builder.config.dry_run() && !llvm_cmake_dir.is_dir() { + builder.info(&format!( + "WARNING: {} does not exist, Enzyme build will likely fail", + llvm_cmake_dir.display() + )); + } + trace!(?target, "(re)building enzyme artifacts"); builder.info(&format!("Building Enzyme for {target}")); t!(stamp.remove()); let _time = helpers::timeit(builder); t!(fs::create_dir_all(&out_dir)); - builder - .config - .update_submodule(Path::new("src").join("tools").join("enzyme").to_str().unwrap()); + builder.config.update_submodule("src/tools/enzyme"); let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/")); configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]); @@ -983,7 +988,7 @@ impl Step for Enzyme { .define("LLVM_ENABLE_ASSERTIONS", "ON") .define("ENZYME_EXTERNAL_SHARED_LIB", "ON") .define("ENZYME_BC_LOADER", "OFF") - .define("LLVM_DIR", builder.llvm_out(target)); + .define("LLVM_DIR", llvm_cmake_dir); cfg.build(); From 52bcaabdb865063439395db3bdc08cf29693a071 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Tue, 16 Dec 2025 22:06:29 +0100 Subject: [PATCH 5/6] Port `#[no_link]` to use attribute parser --- .../rustc_attr_parsing/src/attributes/mod.rs | 1 + .../src/attributes/no_link.rs | 14 ++ compiler/rustc_attr_parsing/src/context.rs | 2 + .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + compiler/rustc_passes/messages.ftl | 9 - compiler/rustc_passes/src/check_attr.rs | 28 +-- compiler/rustc_passes/src/errors.rs | 15 -- tests/ui/attributes/malformed-attrs.stderr | 17 +- ...sue-43106-gating-of-builtin-attrs-error.rs | 22 +-- ...43106-gating-of-builtin-attrs-error.stderr | 176 +++++++++--------- .../lint/unused/unused-attr-duplicate.stderr | 24 +-- 12 files changed, 141 insertions(+), 171 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/no_link.rs diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 64f29a4729c3d..f7290bd7e6f25 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -47,6 +47,7 @@ pub(crate) mod loop_match; pub(crate) mod macro_attrs; pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; +pub(crate) mod no_link; pub(crate) mod non_exhaustive; pub(crate) mod path; pub(crate) mod pin_v2; diff --git a/compiler/rustc_attr_parsing/src/attributes/no_link.rs b/compiler/rustc_attr_parsing/src/attributes/no_link.rs new file mode 100644 index 0000000000000..43cd1c5406e98 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/no_link.rs @@ -0,0 +1,14 @@ +use super::prelude::*; + +pub(crate) struct NoLinkParser; +impl NoArgsAttributeParser for NoLinkParser { + const PATH: &[Symbol] = &[sym::no_link]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::ExternCrate), + Warn(Target::Field), + Warn(Target::Arm), + Warn(Target::MacroDef), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoLink; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9c7006f840241..7b60ff731bd32 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -50,6 +50,7 @@ use crate::attributes::macro_attrs::{ }; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; +use crate::attributes::no_link::NoLinkParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; use crate::attributes::path::PathParser as PathAttributeParser; use crate::attributes::pin_v2::PinV2Parser; @@ -240,6 +241,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 5f38eaf4d5f4c..64192f6f457e8 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -803,6 +803,9 @@ pub enum AttributeKind { /// Represents `#[no_implicit_prelude]` NoImplicitPrelude(Span), + /// Represents `#[no_link]` + NoLink, + /// Represents `#[no_mangle]` NoMangle(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 90fb0497a5b20..d51aea80101ad 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -70,6 +70,7 @@ impl AttributeKind { Naked(..) => No, NoCore(..) => No, NoImplicitPrelude(..) => No, + NoLink => No, NoMangle(..) => Yes, // Needed for rustdoc NoStd(..) => No, NonExhaustive(..) => Yes, // Needed for rustdoc diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 21191085253bd..5f792883826c0 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -240,11 +240,6 @@ passes_has_incoherent_inherent_impl = `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits .label = only adts, extern types and traits are supported -passes_ignored_attr_with_macro = - `#[{$sym}]` is ignored on struct fields, match arms and macro defs - .warn = {-passes_previously_accepted} - .note = {-passes_see_issue(issue: "80564")} - passes_ignored_derived_impls = `{$name}` has {$trait_list_len -> [one] a derived impl @@ -379,10 +374,6 @@ passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, union, or trait .label = is not a struct, enum, union, or trait -passes_no_link = - attribute should be applied to an `extern crate` item - .label = not an `extern crate` item - passes_no_main_function = `main` function not found in crate `{$crate_name}` .here_is_main = here is a function named `main` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index e836277e9761a..735cf0ee5c33c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -250,6 +250,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::LinkSection { .. } | AttributeKind::MacroUse { .. } | AttributeKind::MacroEscape( .. ) + | AttributeKind::NoLink | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcScalableVector { .. } @@ -299,7 +300,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_diagnostic_on_const(attr.span(), hir_id, target, item) } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), - [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target), [sym::rustc_no_implicit_autorefs, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } @@ -456,15 +456,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_mix_no_mangle_export(hir_id, attrs); } - fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr_span, - errors::IgnoredAttrWithMacro { sym }, - ); - } - fn check_eii_impl(&self, impls: &[EiiImpl], target: Target) { for EiiImpl { span, inner_span, eii_macro, impl_marked_unsafe, is_default: _ } in impls { match target { @@ -1198,23 +1189,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ); } - /// Checks if `#[no_link]` is applied to an `extern crate`. - fn check_no_link(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { - match target { - Target::ExternCrate => {} - // FIXME(#80564): We permit struct fields, match arms and macro defs to have an - // `#[no_link]` attribute with just a lint, because we previously - // erroneously allowed it and some crates used it accidentally, to be compatible - // with crates depending on them, we can't throw an error here. - Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_link"); - } - _ => { - self.dcx().emit_err(errors::NoLink { attr_span: attr.span(), span }); - } - } - } - /// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument. fn check_rustc_legacy_const_generics( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 7abd2c703aeb4..ea3cef258c58c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -80,12 +80,6 @@ pub(crate) struct OuterCrateLevelAttrSuggestion { #[diag(passes_inner_crate_level_attr)] pub(crate) struct InnerCrateLevelAttr; -#[derive(LintDiagnostic)] -#[diag(passes_ignored_attr_with_macro)] -pub(crate) struct IgnoredAttrWithMacro<'a> { - pub sym: &'a str, -} - #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_fn)] pub(crate) struct AttrShouldBeAppliedToFn { @@ -254,15 +248,6 @@ pub(crate) struct Link { pub span: Option, } -#[derive(Diagnostic)] -#[diag(passes_no_link)] -pub(crate) struct NoLink { - #[primary_span] - pub attr_span: Span, - #[label] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(passes_rustc_legacy_const_generics_only)] pub(crate) struct RustcLegacyConstGenericsOnly { diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 0cd88e2541949..228ea12cba8be 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -147,14 +147,6 @@ error: malformed `thread_local` attribute input LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` -error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:214:1 - | -LL | #[no_link()] - | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` - | - = note: for more information, visit - error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type --> $DIR/malformed-attrs.rs:105:1 | @@ -626,6 +618,15 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` +error[E0565]: malformed `no_link` attribute input + --> $DIR/malformed-attrs.rs:214:1 + | +LL | #[no_link()] + | ^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[no_link]` + error[E0539]: malformed `macro_use` attribute input --> $DIR/malformed-attrs.rs:216:1 | diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index 0b0dd80f01151..c819e8763ef45 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -1,4 +1,3 @@ -//~ NOTE: not an `extern crate` item // This is testing whether various builtin attributes signals an // error or warning when put in "weird" places. // @@ -29,7 +28,7 @@ //~| WARN cannot be used on crates //~| WARN previously accepted #![no_link] -//~^ ERROR: attribute should be applied to an `extern crate` item +//~^ ERROR: `#[no_link]` attribute cannot be used on crates #![export_name = "2200"] //~^ ERROR: attribute cannot be used on //~| NOTE takes precedence @@ -60,29 +59,22 @@ mod inline { } #[no_link] -//~^ ERROR attribute should be applied to an `extern crate` item +//~^ ERROR `#[no_link]` attribute cannot be used on modules mod no_link { - //~^ NOTE not an `extern crate` item - mod inner { #![no_link] } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on modules #[no_link] fn f() { } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on functions #[no_link] struct S; - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on structs #[no_link]type T = S; - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on type aliases #[no_link] impl S { } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on inherent impl blocks } #[export_name = "2200"] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 013e529238112..b4086e3ed9168 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -1,5 +1,5 @@ error[E0658]: use of an internal attribute - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1 | LL | #![rustc_main] | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![rustc_main] = note: the `#[rustc_main]` attribute is used internally to specify test entry point function error: `#[macro_export]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:10:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:9:1 | LL | #![macro_export] | ^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![macro_export] = help: `#[macro_export]` can only be applied to macro defs error: `#[rustc_main]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1 | LL | #![rustc_main] | ^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #![rustc_main] = help: `#[rustc_main]` can only be applied to functions error: `#[path]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:20:1 | LL | #![path = "3800"] | ^^^^^^^^^^^^^^^^^ @@ -33,15 +33,23 @@ LL | #![path = "3800"] = help: `#[path]` can only be applied to modules error: `#[automatically_derived]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:22:1 | LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[automatically_derived]` can only be applied to trait impl blocks +error: `#[no_link]` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:30:1 + | +LL | #![no_link] + | ^^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + error: `#[export_name]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:33:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +57,7 @@ LL | #![export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[inline]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:35:1 | LL | #![inline] | ^^^^^^^^^^ @@ -57,7 +65,7 @@ LL | #![inline] = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:38:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:1 | LL | #[inline] | ^^^^^^^^^ @@ -65,7 +73,7 @@ LL | #[inline] = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:43:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:42:17 | LL | mod inner { #![inline] } | ^^^^^^^^^^ @@ -73,7 +81,7 @@ LL | mod inner { #![inline] } = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:52:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5 | LL | #[inline] struct S; | ^^^^^^^^^ @@ -81,7 +89,7 @@ LL | #[inline] struct S; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:5 | LL | #[inline] type T = S; | ^^^^^^^^^ @@ -89,15 +97,63 @@ LL | #[inline] type T = S; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:58:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:57:5 | LL | #[inline] impl S { } | ^^^^^^^^^ | = help: `#[inline]` can only be applied to functions +error: `#[no_link]` attribute cannot be used on modules + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:61:1 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on modules + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:17 + | +LL | mod inner { #![no_link] } + | ^^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on functions + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:5 + | +LL | #[no_link] fn f() { } + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on structs + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:5 + | +LL | #[no_link] struct S; + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on type aliases + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5 + | +LL | #[no_link]type T = S; + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on inherent impl blocks + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5 + | +LL | #[no_link] impl S { } + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +161,7 @@ LL | #[export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:17 | LL | mod inner { #![export_name="2200"] } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +169,7 @@ LL | mod inner { #![export_name="2200"] } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +177,7 @@ LL | #[export_name = "2200"] struct S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:99:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +185,7 @@ LL | #[export_name = "2200"] type T = S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:102:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:94:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,29 +193,15 @@ LL | #[export_name = "2200"] impl S { } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on required trait methods - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:9 | LL | #[export_name = "2200"] fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[export_name]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:62:1 - | -LL | #[no_link] - | ^^^^^^^^^^ -LL | -LL | / mod no_link { -LL | | -LL | | -LL | | mod inner { #![no_link] } -... | -LL | | } - | |_- not an `extern crate` item - error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:8 | LL | #[repr(C)] | ^ @@ -172,7 +214,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:129:8 | LL | #[repr(Rust)] | ^^^^ @@ -184,20 +226,14 @@ LL | | mod inner { #![repr(Rust)] } LL | | } | |_- not a struct, enum, or union -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:31:1 - | -LL | #![no_link] - | ^^^^^^^^^^^ not an `extern crate` item - warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:24:1 | LL | #![no_mangle] | ^^^^^^^^^^^^^ `#[no_mangle]` is ignored | note: `#[export_name]` takes precedence - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:33:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -208,7 +244,7 @@ LL - #![no_mangle] | error: `repr` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![repr()] | ^^^^^^^^^^ @@ -222,86 +258,56 @@ LL - #![repr()] LL + #[repr()] | -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:17 - | -LL | mod inner { #![no_link] } - | ------------^^^^^^^^^^^-- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:71:5 - | -LL | #[no_link] fn f() { } - | ^^^^^^^^^^ ---------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:75:5 - | -LL | #[no_link] struct S; - | ^^^^^^^^^^ --------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:79:5 - | -LL | #[no_link]type T = S; - | ^^^^^^^^^^----------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:5 - | -LL | #[no_link] impl S { } - | ^^^^^^^^^^ ---------- not an `extern crate` item - error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:117:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:25 | LL | mod inner { #![repr(C)] } | --------------------^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:12 | LL | #[repr(C)] fn f() { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:12 | LL | #[repr(C)] type T = S; | ^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:12 | LL | #[repr(C)] impl S { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:25 | LL | mod inner { #![repr(Rust)] } | --------------------^^^^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:145:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 | LL | #[repr(Rust)] fn f() { } | ^^^^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:143:12 | LL | #[repr(Rust)] type T = S; | ^^^^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:12 | LL | #[repr(Rust)] impl S { } | ^^^^ ---------- not a struct, enum, or union error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ @@ -311,7 +317,7 @@ LL | #[inline = "2100"] fn f() { } = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![repr()] | ^^^^^^^^^^ help: remove this attribute @@ -319,7 +325,7 @@ LL | #![repr()] = note: using `repr` with an empty list has no effect warning: `#[no_mangle]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:24:1 | LL | #![no_mangle] | ^^^^^^^^^^^^^ @@ -333,7 +339,7 @@ Some errors have detailed explanations: E0517, E0658. For more information about an error, try `rustc --explain E0517`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 86506dba5f08b..54ed351d43486 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -16,18 +16,6 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:37:1 - | -LL | #[no_link] - | ^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:36:1 - | -LL | #[no_link] - | ^^^^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:34:1 | @@ -40,6 +28,18 @@ note: attribute also specified here LL | #![no_builtins] | ^^^^^^^^^^^^^^^ +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:37:1 + | +LL | #[no_link] + | ^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:36:1 + | +LL | #[no_link] + | ^^^^^^^^^^ + error: unused attribute --> $DIR/unused-attr-duplicate.rs:41:1 | From b09a9d006243e40b34e2597b1a4734f5b4188e8e Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Tue, 16 Dec 2025 22:45:56 +0100 Subject: [PATCH 6/6] add tests making sure to FCW warn on `field`, `arm`, and `macro def` --- ...sue-43106-gating-of-builtin-attrs-error.rs | 24 ++++++- ...43106-gating-of-builtin-attrs-error.stderr | 71 +++++++++++++------ 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index c819e8763ef45..1560f2b5f4a77 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -64,17 +64,35 @@ mod no_link { mod inner { #![no_link] } //~^ ERROR `#[no_link]` attribute cannot be used on modules - #[no_link] fn f() { } - //~^ ERROR `#[no_link]` attribute cannot be used on functions + #[no_link] fn f() { + //~^ ERROR `#[no_link]` attribute cannot be used on functions + match () { + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on match arms [unused_attributes] + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + _ => () + } + } - #[no_link] struct S; + #[no_link] //~^ ERROR `#[no_link]` attribute cannot be used on structs + struct S { + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on struct fields [unused_attributes] + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + field: () + } #[no_link]type T = S; //~^ ERROR `#[no_link]` attribute cannot be used on type aliases #[no_link] impl S { } //~^ ERROR `#[no_link]` attribute cannot be used on inherent impl blocks + + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on macro defs + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + macro_rules! m{() => {}} } #[export_name = "2200"] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index b4086e3ed9168..662776e580267 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -123,21 +123,21 @@ LL | mod inner { #![no_link] } error: `#[no_link]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:5 | -LL | #[no_link] fn f() { } +LL | #[no_link] fn f() { | ^^^^^^^^^^ | = help: `#[no_link]` can only be applied to extern crates error: `#[no_link]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:77:5 | -LL | #[no_link] struct S; +LL | #[no_link] | ^^^^^^^^^^ | = help: `#[no_link]` can only be applied to extern crates error: `#[no_link]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:73:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:5 | LL | #[no_link]type T = S; | ^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | #[no_link]type T = S; = help: `#[no_link]` can only be applied to extern crates error: `#[no_link]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:89:5 | LL | #[no_link] impl S { } | ^^^^^^^^^^ @@ -153,7 +153,7 @@ LL | #[no_link] impl S { } = help: `#[no_link]` can only be applied to extern crates error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -161,7 +161,7 @@ LL | #[export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:101:17 | LL | mod inner { #![export_name="2200"] } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | mod inner { #![export_name="2200"] } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -177,7 +177,7 @@ LL | #[export_name = "2200"] struct S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ LL | #[export_name = "2200"] type T = S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:94:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:112:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | #[export_name = "2200"] impl S { } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on required trait methods - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:116:9 | LL | #[export_name = "2200"] fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -201,7 +201,7 @@ LL | #[export_name = "2200"] fn foo(); = help: `#[export_name]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:8 | LL | #[repr(C)] | ^ @@ -214,7 +214,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:129:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:8 | LL | #[repr(Rust)] | ^^^^ @@ -259,49 +259,49 @@ LL + #[repr()] | error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:25 | LL | mod inner { #![repr(C)] } | --------------------^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:12 | LL | #[repr(C)] fn f() { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 | LL | #[repr(C)] type T = S; | ^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:12 | LL | #[repr(C)] impl S { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:25 | LL | mod inner { #![repr(Rust)] } | --------------------^^^^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 | LL | #[repr(Rust)] fn f() { } | ^^^^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:143:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:161:12 | LL | #[repr(Rust)] type T = S; | ^^^^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:165:12 | LL | #[repr(Rust)] impl S { } | ^^^^ ---------- not a struct, enum, or union @@ -316,6 +316,33 @@ LL | #[inline = "2100"] fn f() { } = note: for more information, see issue #57571 = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default +warning: `#[no_link]` attribute cannot be used on match arms + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:13 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + +warning: `#[no_link]` attribute cannot be used on struct fields + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:9 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + +warning: `#[no_link]` attribute cannot be used on macro defs + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:92:5 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + warning: unused attribute --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | @@ -333,7 +360,7 @@ LL | #![no_mangle] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_mangle]` can be applied to functions and statics -error: aborting due to 37 previous errors; 3 warnings emitted +error: aborting due to 37 previous errors; 6 warnings emitted Some errors have detailed explanations: E0517, E0658. For more information about an error, try `rustc --explain E0517`.