From ded9835c57e5a74f163632d8a3c98a0b8061f1c9 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Wed, 4 Nov 2026 00:53:41 +0100 Subject: [PATCH 1/5] Remove macro_escape --- .../rustc_attr_parsing/src/attributes/macro_attrs.rs | 9 --------- compiler/rustc_attr_parsing/src/context.rs | 1 - compiler/rustc_feature/src/builtin_attrs.rs | 1 - compiler/rustc_resolve/src/build_reduced_graph.rs | 8 +------- compiler/rustc_resolve/src/diagnostics/mod.rs | 9 --------- compiler/rustc_resolve/src/late.rs | 4 +--- 6 files changed, 2 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 5be8df4d141c8..11481196b80fc 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -7,15 +7,6 @@ use rustc_structures::CollapseMacroDebuginfo; use super::prelude::*; use crate::diagnostics::{MacroExportOnDeclMacro, MacroOnlyAttribute}; -pub(crate) struct MacroEscapeParser; -impl NoArgsAttributeParser for MacroEscapeParser { - const PATH: &[Symbol] = &[sym::macro_escape]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = MACRO_USE_ALLOWED_TARGETS; - const STABILITY: AttributeStability = AttributeStability::Stable; - const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::MacroEscape; -} - /// `#[macro_use]` attributes can either: /// - Use all macros from a crate, if provided without arguments /// - Use specific macros from a crate, if provided with arguments `#[macro_use(macro1, macro2)]` diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 547649313ac44..b99ee2840b7c8 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -278,7 +278,6 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 52dba353eb24b..b4fe0d9e7cca1 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -96,7 +96,6 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ // Macros: sym::automatically_derived, sym::macro_use, - sym::macro_escape, // Deprecated synonym for `macro_use`. sym::macro_export, sym::proc_macro, sym::proc_macro_derive, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 1eb438933e489..24aeb1184ab92 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1235,13 +1235,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { /// Returns `true` if this attribute list contains `macro_use`. pub(crate) fn contains_macro_use(&self, attrs: &[ast::Attribute]) -> bool { for attr in attrs { - if attr.has_name(sym::macro_escape) { - let inner_attribute = matches!(attr.style, ast::AttrStyle::Inner); - self.r.dcx().emit_warn(diagnostics::MacroExternDeprecated { - span: attr.span, - inner_attribute, - }); - } else if !attr.has_name(sym::macro_use) { + if !attr.has_name(sym::macro_use) { continue; } diff --git a/compiler/rustc_resolve/src/diagnostics/mod.rs b/compiler/rustc_resolve/src/diagnostics/mod.rs index e33255eec46d8..4f0b73367619d 100644 --- a/compiler/rustc_resolve/src/diagnostics/mod.rs +++ b/compiler/rustc_resolve/src/diagnostics/mod.rs @@ -985,15 +985,6 @@ pub(crate) struct ImportedMacroNotFound { pub(crate) span: Span, } -#[derive(Diagnostic)] -#[diag("`#[macro_escape]` is a deprecated synonym for `#[macro_use]`")] -pub(crate) struct MacroExternDeprecated { - #[primary_span] - pub(crate) span: Span, - #[help("try an outer attribute: `#[macro_use]`")] - pub inner_attribute: bool, -} - #[derive(Diagnostic)] #[diag("arguments to `macro_use` are not allowed here")] pub(crate) struct ArgumentsMacroUseNotAllowed { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6b33279947115..602fb1fa6114e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3117,9 +3117,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { visit::walk_item(this, item); // Maintain macro_rules scopes in the same way as during early resolution // for diagnostics and doc links. - if item.attrs.iter().all(|attr| { - !attr.has_name(sym::macro_use) && !attr.has_name(sym::macro_escape) - }) { + if item.attrs.iter().all(|attr| !attr.has_name(sym::macro_use)) { this.parent_scope.macro_rules = old_macro_rules; } }) From f117d5c8f57e06315e7f7add01ce9afca00e9c97 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Thu, 5 Nov 2026 13:18:42 +0100 Subject: [PATCH 2/5] Raise all the errors --- .../src/attributes/codegen_attrs.rs | 46 +++++---- .../src/attributes/crate_level.rs | 59 +++++------ .../src/attributes/deprecation.rs | 12 +-- .../src/attributes/diagnostic/opaque.rs | 2 +- .../rustc_attr_parsing/src/attributes/doc.rs | 20 +--- .../src/attributes/inline.rs | 19 ++-- .../src/attributes/instruction_set.rs | 2 +- .../src/attributes/link_attrs.rs | 26 ++--- .../src/attributes/lint_helpers.rs | 9 +- .../src/attributes/macro_attrs.rs | 34 +++---- .../rustc_attr_parsing/src/attributes/mod.rs | 5 +- .../src/attributes/must_use.rs | 7 +- .../src/attributes/no_implicit_prelude.rs | 9 +- .../src/attributes/no_link.rs | 10 +- .../src/attributes/non_exhaustive.rs | 7 +- .../rustc_attr_parsing/src/attributes/path.rs | 8 +- .../src/attributes/proc_macro_attrs.rs | 9 +- .../rustc_attr_parsing/src/attributes/repr.rs | 17 +--- .../src/attributes/test_attrs.rs | 40 +++----- compiler/rustc_attr_parsing/src/context.rs | 35 ++++--- .../rustc_attr_parsing/src/diagnostics.rs | 15 ++- .../rustc_attr_parsing/src/target_checking.rs | 4 + compiler/rustc_expand/src/diagnostics.rs | 19 +--- compiler/rustc_expand/src/expand.rs | 97 +++++++------------ compiler/rustc_passes/src/check_attr.rs | 61 ++++-------- 25 files changed, 217 insertions(+), 355 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index e88b1751e4b6c..4c69fb2c26d51 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -15,6 +15,7 @@ use crate::diagnostics::{ ObjcSelectorExpectedStringLiteral, SanitizeInvalidStatic, TargetFeatureOnLangItem, TrackCallerOnLangItem, }; +use crate::target_checking::AllowedResult; use crate::target_checking::Policy::AllowSilent; pub(crate) struct OptimizeParser; @@ -53,8 +54,8 @@ pub(crate) struct ColdParser; impl NoArgsAttributeParser for ColdParser { const PATH: &[Symbol] = &[sym::cold]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), @@ -113,7 +114,7 @@ pub(crate) struct ExportNameParser; impl SingleAttributeParser for ExportNameParser { const PATH: &[rustc_span::Symbol] = &[sym::export_name]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const SAFETY: AttributeSafety = AttributeSafety::Unsafe { note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them", unsafe_since: Some(Edition2024), @@ -221,7 +222,7 @@ impl AttributeParser for NakedParser { if let Some(earlier) = this.span { let span = cx.attr_span; - cx.warn_unused_duplicate(earlier, span); + cx.unused_duplicate(earlier, span); } else { this.span = Some(cx.attr_span); } @@ -235,10 +236,18 @@ impl AttributeParser for NakedParser { Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), - Warn(Target::MacroCall), ]); fn finalize(self, cx: &FinalizeContext<'_, '_>) -> Option { + let span = self.span?; + + if !matches!(NakedParser::ALLOWED_TARGETS.is_allowed(cx.target), AllowedResult::Allowed) { + cx.dcx().span_delayed_bug( + span, + "skipping `naked` attribute incompatibility check for disallowed target", + ); + return None; + } // FIXME(jdonszelmann): upgrade this list to *parsed* attributes // once all of these have parsed forms. That'd make the check much nicer... // @@ -282,8 +291,6 @@ impl AttributeParser for NakedParser { sym::doc, ]; - let span = self.span?; - let Some(tools) = cx.attr_tools else { unreachable!("tools required while parsing attributes"); }; @@ -368,7 +375,7 @@ impl AttributeParser for NakedParser { pub(crate) struct TrackCallerParser; impl NoArgsAttributeParser for TrackCallerParser { const PATH: &[Symbol] = &[sym::track_caller]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -377,10 +384,6 @@ impl NoArgsAttributeParser for TrackCallerParser { Allow(Target::Method(MethodKind::Trait { body: false })), // `#[track_caller]` is inherited from trait methods Allow(Target::ForeignFn), Allow(Target::Closure), - Warn(Target::MacroDef), - Warn(Target::Arm), - Warn(Target::Field), - Warn(Target::MacroCall), ]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller; @@ -417,7 +420,7 @@ impl NoArgsAttributeParser for TrackCallerParser { pub(crate) struct NoMangleParser; impl NoArgsAttributeParser for NoMangleParser { const PATH: &[Symbol] = &[sym::no_mangle]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const SAFETY: AttributeSafety = AttributeSafety::Unsafe { note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them", unsafe_since: Some(Edition2024), @@ -505,14 +508,14 @@ impl AttributeParser for UsedParser { UsedBy::Compiler => &mut group.first_compiler, UsedBy::Linker => { if let Some(prev) = group.first_default { - cx.warn_unused_duplicate(prev, attr_span); + cx.unused_duplicate(prev, attr_span); return; } &mut group.first_linker } UsedBy::Default => { if let Some(prev) = group.first_linker { - cx.warn_unused_duplicate(prev, attr_span); + cx.unused_duplicate(prev, attr_span); return; } &mut group.first_default @@ -520,14 +523,13 @@ impl AttributeParser for UsedParser { }; if let Some(prev) = *target { - cx.warn_unused_duplicate(prev, attr_span); + cx.unused_duplicate(prev, attr_span); } else { *target = Some(attr_span); } }, )]; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Static)]); fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { // If a specific form of `used` is specified, it takes precedence over generic `#[used]`. @@ -551,7 +553,7 @@ fn parse_tf_attribute( }; if list.is_empty() { let attr_span = cx.attr_span; - cx.adcx().warn_empty_attribute(attr_span); + cx.adcx().empty_attribute(attr_span); return features; } for item in list.mixed() { @@ -593,11 +595,7 @@ impl CombineAttributeParser for TargetFeatureParser { Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::TraitImpl)), - Warn(Target::Statement), - Warn(Target::Field), - Warn(Target::Arm), - Warn(Target::MacroDef), - Warn(Target::MacroCall), + Warn(Target::MacroCall), // #158816: 181 regressions from old versions of `v_escape` ]); const STABILITY: AttributeStability = AttributeStability::Stable; diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 4f86895bbd02b..2779bbf9b4567 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -1,7 +1,7 @@ use rustc_attr_ir::WindowsSubsystemKind; use rustc_data_structures::fx::FxIndexSet; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::{DUPLICATE_TOOLS, UNKNOWN_CRATE_TYPES}; +use rustc_lint_defs::builtin::DUPLICATE_TOOLS; use rustc_span::Symbol; use rustc_span::edit_distance::find_best_match_for_name_with_substrings; use rustc_structures::CrateType; @@ -15,10 +15,9 @@ pub(crate) struct CrateNameParser; impl SingleAttributeParser for CrateNameParser { const PATH: &[Symbol] = &[sym::crate_name]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -36,8 +35,7 @@ impl CombineAttributeParser for CrateTypeParser { const PATH: &[Symbol] = &[sym::crate_type]; type Item = CrateType; const CONVERT: ConvertFn = |items, _| AttributeKind::CrateType(items); - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "crate type", "https://doc.rust-lang.org/reference/linkage.html"); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -51,7 +49,7 @@ impl CombineAttributeParser for CrateTypeParser { let crate_type = cx.expect_string_literal(n)?; let Ok(crate_type) = crate_type.try_into() else { - // We don't error on invalid `#![crate_type]` when not applied to a crate + // We error on invalid `#![crate_type]` when not applied to a crate if cx.shared.target == Target::Crate { let candidate = find_best_match_for_name_with_substrings( &CrateType::all_stable().iter().map(|(name, _)| *name).collect::>(), @@ -59,13 +57,9 @@ impl CombineAttributeParser for CrateTypeParser { Some(5), ); let span = n.value_span; - cx.emit_lint( - UNKNOWN_CRATE_TYPES, - UnknownCrateTypes { - sugg: candidate.map(|s| UnknownCrateTypesSuggestion { span, snippet: s }), - }, - span, - ); + cx.emit_err(UnknownCrateTypes { + sugg: candidate.map(|s| UnknownCrateTypesSuggestion { span, snippet: s }), + }); } return None; }; @@ -78,10 +72,9 @@ pub(crate) struct RecursionLimitParser; impl SingleAttributeParser for RecursionLimitParser { const PATH: &[Symbol] = &[sym::recursion_limit]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -110,10 +103,9 @@ pub(crate) struct TypeLengthLimitParser; impl SingleAttributeParser for TypeLengthLimitParser { const PATH: &[Symbol] = &[sym::type_length_limit]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { @@ -154,9 +146,8 @@ pub(crate) struct NoStdParser; impl NoArgsAttributeParser for NoStdParser { const PATH: &[Symbol] = &[sym::no_std]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoStd; } @@ -165,9 +156,8 @@ pub(crate) struct NoMainParser; impl NoArgsAttributeParser for NoMainParser { const PATH: &[Symbol] = &[sym::no_main]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain; } @@ -185,9 +175,8 @@ pub(crate) struct WindowsSubsystemParser; impl SingleAttributeParser for WindowsSubsystemParser { const PATH: &[Symbol] = &[sym::windows_subsystem]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -241,9 +230,8 @@ pub(crate) struct NoBuiltinsParser; impl NoArgsAttributeParser for NoBuiltinsParser { const PATH: &[Symbol] = &[sym::no_builtins]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoBuiltins; } @@ -281,8 +269,7 @@ impl CombineAttributeParser for FeatureParser { const PATH: &[Symbol] = &[sym::feature]; type Item = Ident; const CONVERT: ConvertFn = AttributeKind::Feature; - const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Crate), Error(Target::Param)]); + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &["feature1, feature2, ..."]); const STABILITY: AttributeStability = AttributeStability::Stable; @@ -296,7 +283,7 @@ impl CombineAttributeParser for FeatureParser { if list.is_empty() { let attr_span = cx.attr_span; - cx.adcx().warn_empty_attribute(attr_span); + cx.adcx().empty_attribute(attr_span); } let mut res = Vec::new(); @@ -338,7 +325,7 @@ fn parse_register_tool( if list.is_empty() { let attr_span = cx.attr_span; - cx.adcx().warn_empty_attribute(attr_span); + cx.adcx().empty_attribute(attr_span); } for elem in list.mixed() { diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index da0af9496167d..cb8ab55768abd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -1,7 +1,6 @@ use rustc_ast::LitKind; use rustc_attr_ir::{DeprecatedSince, Deprecation, RustcVersion, VERSION_PLACEHOLDER}; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::UNUSED_ATTRIBUTES; use super::prelude::*; use super::util::parse_version; @@ -34,7 +33,7 @@ fn get( pub(crate) struct DeprecatedParser; impl SingleAttributeParser for DeprecatedParser { const PATH: &[Symbol] = &[sym::deprecated]; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Mod), Allow(Target::Struct), @@ -62,8 +61,7 @@ impl SingleAttributeParser for DeprecatedParser { Allow(Target::Variant), Allow(Target::Impl { of_trait: false }), Allow(Target::Crate), - Error(Target::WherePredicate), - Error(Target::Param), + Warn(Target::MacroCall), // #158816: ~100 regressions from `raw-cpuid`, `gtk`, `trust-dns-resolver` ]); const TEMPLATE: AttributeTemplate = template!( Word, @@ -201,11 +199,7 @@ impl SingleAttributeParser for DeprecatedParser { | Target::AssocTy(AssocCtxt::Impl { of_trait: true }) ) { let attr_span = cx.attr_span; - cx.emit_lint( - UNUSED_ATTRIBUTES, - DeprecatedAnnotationHasNoEffect { span: attr_span }, - attr_span, - ); + cx.emit_err(DeprecatedAnnotationHasNoEffect { span: attr_span }); } Some(AttributeKind::Deprecated { diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs index 0e4a524080149..bf16f7f8a76a7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs @@ -52,7 +52,7 @@ impl OpaqueParser { fn parse<'sess>(&mut self, cx: &mut AcceptContext<'_, 'sess>, args: &ArgParser) { let attr_span = cx.attr_span; if let Some(earlier_span) = self.attr_span { - cx.warn_unused_duplicate(earlier_span, attr_span); + cx.unused_duplicate(earlier_span, attr_span); } self.attr_span = Some(attr_span); diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 1d0aae810d45c..d44c8e5cc4d01 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -28,7 +28,7 @@ use crate::diagnostics::{ use crate::parser::{ ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser, }; -use crate::target_checking::Policy::{Allow, AllowSilent}; +use crate::target_checking::Policy::Allow; fn check_keyword(cx: &mut AcceptContext<'_, '_>, keyword: Symbol, span: Span) -> bool { // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we @@ -286,10 +286,7 @@ impl DocParser { cx.check_target( sym::no_crate_inject.as_str(), - &AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Crate), - AllowSilent(Target::Param), - ]), + &AllowedTargets::AllowList(&[Allow(Target::Crate)]), ); self.attribute.no_crate_inject = Some(path.span()) @@ -679,10 +676,7 @@ impl DocParser { let span = path.span(); cx.check_target( concat!("(", stringify!($ident), ")"), - &AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Crate), - AllowSilent(Target::Param), // Param has a custom error - ]), + &AllowedTargets::AllowList(&[Allow(Target::Crate)]), ); self.attribute.$ident = Some(span); }}; @@ -699,13 +693,7 @@ impl DocParser { return; }; - cx.check_target( - s.as_str(), - &AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Crate), - AllowSilent(Target::Param), // Param has a custom error - ]), - ); + cx.check_target(s.as_str(), &AllowedTargets::AllowList(&[Allow(Target::Crate)])); // FIXME: It's errorring when the attribute is passed multiple times on the command // line. diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index 5dd46bf0922de..54a428cf91cc8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -1,6 +1,5 @@ use rustc_attr_ir::{Attribute, AttributeKind, InlineAttr, find_attr}; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNUSED_ATTRIBUTES}; use super::prelude::*; use crate::diagnostics::{InlineForceInlineConflict, InlineIgnoredForExported, UnusedMultiple}; @@ -28,15 +27,8 @@ impl AttributeParser for InlineParser { Allow(Target::Method(MethodKind::TraitImpl)), Allow(Target::Closure), Allow(Target::Delegation { mac: false }), - Warn(Target::Method(MethodKind::Trait { body: false })), - Warn(Target::ForeignFn), - Warn(Target::Field), - Warn(Target::MacroDef), - Warn(Target::Arm), - Warn(Target::AssocConst(AssocCtxt::Impl { of_trait: false })), - Warn(Target::AssocConst(AssocCtxt::Trait)), - Warn(Target::AssocConst(AssocCtxt::Impl { of_trait: true })), - Warn(Target::MacroCall), + Warn(Target::MacroCall), // #158816: ~13k regressions from many old versions of `itertools`, `hashbrown`, `cgmath`, `ndarray`, `rkyv` etc + // Warn(Target::Method(MethodKind::Trait { body: false })), // #165441 `subtle` ]), ); @@ -59,7 +51,8 @@ impl AttributeParser for InlineParser { } } ArgParser::NameValue(_) => { - cx.adcx().warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT); + cx.adcx() + .expected_specific_argument(inline_span, &[sym::always, sym::never]); return; } }; @@ -70,6 +63,8 @@ impl AttributeParser for InlineParser { cx.emit_err(InlineForceInlineConflict { inline_span, force_inline_span }); } Some((_, first_inline_span)) => { + // affects tinyvec (alloc feature) 1.1.0..=1.13.3 + // and probably many more, cx.warn_unused_duplicate_future_error(first_inline_span, inline_span); } } @@ -149,7 +144,7 @@ impl AttributeParser for InlineParser { ) && !find_attr!(cx.parsed_attrs, Inline(InlineAttr::Never, _)) && exported { - cx.emit_lint(UNUSED_ATTRIBUTES, InlineIgnoredForExported, span); + cx.emit_err(InlineIgnoredForExported { span }); } }, self.0?.1, diff --git a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs index 05c69c3baa180..5e942ea384873 100644 --- a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs +++ b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs @@ -8,7 +8,7 @@ pub(crate) struct InstructionSetParser; impl SingleAttributeParser for InstructionSetParser { const PATH: &[Symbol] = &[sym::instruction_set]; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), Allow(Target::Method(MethodKind::Inherent)), diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 64290871f2743..3ab39a978d2de 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -4,7 +4,7 @@ use rustc_attr_ir::target::AstTarget; use rustc_attr_ir::*; use rustc_errors::msg; use rustc_feature::{AttributeStability, Features}; -use rustc_lint_defs::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNUSED_ATTRIBUTES}; +use rustc_lint_defs::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use rustc_session::Session; use rustc_session::diagnostics::feature_err; use rustc_span::edition::Edition::Edition2024; @@ -28,12 +28,9 @@ pub(crate) struct LinkNameParser; impl SingleAttributeParser for LinkNameParser { const PATH: &[Symbol] = &[sym::link_name]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::ForeignFn), - Allow(Target::ForeignStatic), - Error(Target::Param), - ]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!( NameValueStr: "name", "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute" @@ -75,7 +72,7 @@ impl CombineAttributeParser for LinkParser { r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#, ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"); const ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowListWarnRest(&[Allow(Target::ForeignMod), Error(Target::Param)]); + AllowedTargets::AllowList(&[Allow(Target::ForeignMod)]); const STABILITY: AttributeStability = AttributeStability::Stable; fn extend( @@ -277,7 +274,7 @@ impl CombineAttributeParser for LinkParser { }) }); if matches!(abi, ExternAbi::Rust) { - cx.emit_lint(UNUSED_ATTRIBUTES, Link, attr_span); + cx.emit_err(Link { span: attr_span }); } } } @@ -516,13 +513,13 @@ fn check_link_section_macho(name: Symbol) -> Result<(), InvalidMachoSectionReaso impl SingleAttributeParser for LinkSectionParser { const PATH: &[Symbol] = &[sym::link_section]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; + const SAFETY: AttributeSafety = AttributeSafety::Unsafe { note: "the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them", unsafe_since: Some(Edition2024), }; const STABILITY: AttributeStability = AttributeStability::Stable; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Static), Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -632,11 +629,8 @@ pub(crate) struct LinkOrdinalParser; impl SingleAttributeParser for LinkOrdinalParser { const PATH: &[Symbol] = &[sym::link_ordinal]; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ - Allow(Target::ForeignFn), - Allow(Target::ForeignStatic), - Warn(Target::MacroCall), - ]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!( List: &["ordinal"], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute" diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 4b457e09c9cff..6059d9076bca7 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -83,12 +83,11 @@ impl NoArgsAttributeParser for LintShouldNotBeCalledOnConstItemsParser { pub(crate) struct AutomaticallyDerivedParser; impl NoArgsAttributeParser for AutomaticallyDerivedParser { const PATH: &[Symbol] = &[sym::automatically_derived]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Impl { of_trait: true }), - Error(Target::Crate), - Error(Target::WherePredicate), - Error(Target::Param), + Warn(Target::MacroCall), // #158816: 100+ regressions in `cucumber` + Warn(Target::Const), // #165441: `zerocopy` ]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::AutomaticallyDerived; diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 11481196b80fc..d403c1c0e7fff 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,7 +1,6 @@ use rustc_attr_ir::target::AstTarget; use rustc_attr_ir::{MacroUseArgs, find_attr}; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::INVALID_MACRO_EXPORT_ARGUMENTS; use rustc_structures::CollapseMacroDebuginfo; use super::prelude::*; @@ -26,12 +25,8 @@ const MACRO_USE_TEMPLATE: AttributeTemplate = template!( Word, List: &["name1, name2, ..."], "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute" ); -const MACRO_USE_ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Mod), - Allow(Target::ExternCrate), - Error(Target::WherePredicate), - Error(Target::Param), -]); +const MACRO_USE_ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::ExternCrate)]); impl AttributeParser for MacroUseParser { const ATTRIBUTES: AcceptMapping = &[( @@ -49,21 +44,21 @@ impl AttributeParser for MacroUseParser { "State is UseAll is some so this is not the first attribute", ); // Since there is a `#[macro_use]` import already, give a warning - cx.warn_unused_duplicate(first_span, span); + cx.unused_duplicate(first_span, span); } MacroUseArgs::UseSpecific(_) => { group.state = MacroUseArgs::UseAll; group.first_span = Some(span); // If there is a `#[macro_use]` attribute, warn on all `#[macro_use(...)]` attributes since everything is already imported for specific_use in group.uses_attr_spans.drain(..) { - cx.warn_unused_duplicate(span, specific_use); + cx.unused_duplicate(span, specific_use); } } } } ArgParser::List(list) => { if list.is_empty() { - cx.adcx().warn_empty_attribute(list.span); + cx.adcx().empty_attribute(list.span); return; } @@ -72,7 +67,7 @@ impl AttributeParser for MacroUseParser { let first_span = group.first_span.expect( "State is UseAll is some so this is not the first attribute", ); - cx.warn_unused_duplicate(first_span, span); + cx.unused_duplicate(first_span, span); } MacroUseArgs::UseSpecific(arguments) => { // Store here so if we encounter a `UseAll` later we can still lint this attribute @@ -138,29 +133,22 @@ pub(crate) struct MacroExportParser; impl SingleAttributeParser for MacroExportParser { const PATH: &[Symbol] = &[sym::macro_export]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]); - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::MacroDef), - Error(Target::WherePredicate), - Error(Target::Crate), - Error(Target::Param), - ]); + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { let local_inner_macros = match args { ArgParser::NoArgs => false, ArgParser::List(list) => { - let Some(l) = list.as_single() else { - cx.adcx().warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS); - return None; - }; + let l = cx.expect_single_element_list(args, list.span)?; if l.meta_item_no_args().is_some_and(|m| m.path().word_is(sym::local_inner_macros)) { true } else { - cx.adcx().warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS); + cx.adcx().expected_specific_argument(l.span(), &[sym::local_inner_macros]); return None; } } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 1a9c23150a894..2bcfac8625d54 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -217,6 +217,7 @@ pub(crate) enum OnDuplicate { Warn, /// Duplicates will be a warning, with a note that this will be an error in the future. + #[expect(unused)] WarnButFutureError, /// Give a default error @@ -234,8 +235,8 @@ impl OnDuplicate { unused: Span, ) { match self { - OnDuplicate::Warn => cx.warn_unused_duplicate(used, unused), - OnDuplicate::WarnButFutureError => cx.warn_unused_duplicate_future_error(used, unused), + OnDuplicate::Warn => cx.unused_duplicate(used, unused), + OnDuplicate::WarnButFutureError => cx.unused_duplicate(used, unused), OnDuplicate::Error => { cx.emit_err(UnusedMultiple { this: unused, diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index a093fe0ce53b2..9b817bafca923 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -6,8 +6,8 @@ pub(crate) struct MustUseParser; impl SingleAttributeParser for MustUseParser { const PATH: &[Symbol] = &[sym::must_use]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Enum), Allow(Target::Struct), @@ -20,8 +20,7 @@ impl SingleAttributeParser for MustUseParser { // `unused_must_use` if `Trait` is marked as // `#[must_use]` Allow(Target::Trait), - Error(Target::WherePredicate), - Error(Target::Param), + Warn(Target::Method(MethodKind::TraitImpl)), // affects tinyvec (alloc feature) 1.0.0..=1.13.3 ]); const TEMPLATE: AttributeTemplate = template!( Word, NameValueStr: "reason", diff --git a/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs b/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs index 807bb1202c56c..59b60c49440f1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs @@ -6,12 +6,9 @@ pub(crate) struct NoImplicitPreludeParser; impl NoArgsAttributeParser for NoImplicitPreludeParser { const PATH: &[rustc_span::Symbol] = &[sym::no_implicit_prelude]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Mod), - Allow(Target::Crate), - Error(Target::Param), - ]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoImplicitPrelude; } diff --git a/compiler/rustc_attr_parsing/src/attributes/no_link.rs b/compiler/rustc_attr_parsing/src/attributes/no_link.rs index f35204a4c4be1..f6d0afac77ad1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/no_link.rs +++ b/compiler/rustc_attr_parsing/src/attributes/no_link.rs @@ -7,13 +7,9 @@ use crate::diagnostics::NoLinkAttrUsed; 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 ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowList(&[Allow(Target::ExternCrate)]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoLink; diff --git a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs index b363675d5932f..4ee999bc89d18 100644 --- a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs +++ b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs @@ -9,15 +9,12 @@ pub(crate) struct NonExhaustiveParser; impl NoArgsAttributeParser for NonExhaustiveParser { const PATH: &[Symbol] = &[sym::non_exhaustive]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), Allow(Target::Variant), - Warn(Target::Field), - Warn(Target::Arm), - Warn(Target::MacroDef), - Warn(Target::MacroCall), + Warn(Target::MacroCall), // #158816: 600+ regressions from crossterm 0.18..=0.21 ]); const STABILITY: AttributeStability = AttributeStability::Stable; const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive; diff --git a/compiler/rustc_attr_parsing/src/attributes/path.rs b/compiler/rustc_attr_parsing/src/attributes/path.rs index 9b9abdda97f5f..a82f0d6b102d2 100644 --- a/compiler/rustc_attr_parsing/src/attributes/path.rs +++ b/compiler/rustc_attr_parsing/src/attributes/path.rs @@ -6,12 +6,8 @@ pub(crate) struct PathParser; impl SingleAttributeParser for PathParser { const PATH: &[Symbol] = &[sym::path]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Mod), - Error(Target::Crate), - Error(Target::Param), - ]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Mod)]); const TEMPLATE: AttributeTemplate = template!( NameValueStr: "file", "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute" diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs index f8e3b1bb34bcd..cc40948a1543e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs @@ -1,10 +1,9 @@ use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::AMBIGUOUS_DERIVE_HELPERS; use super::prelude::*; const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets<'_> = - AllowedTargets::AllowList(&[Allow(Target::Fn), Warn(Target::Crate), Warn(Target::MacroCall)]); + AllowedTargets::AllowList(&[Allow(Target::Fn)]); pub(crate) struct ProcMacroParser; impl NoArgsAttributeParser for ProcMacroParser { @@ -120,11 +119,7 @@ fn parse_derive_like( return None; } if rustc_feature::is_builtin_attr_name(ident.name) { - cx.emit_lint( - AMBIGUOUS_DERIVE_HELPERS, - crate::diagnostics::AmbiguousDeriveHelpers, - ident.span, - ); + cx.emit_err(crate::diagnostics::AmbiguousDeriveHelpers { span: ident.span }); } attributes.push(ident.name); } diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index bc4f9d20545fc..2dbeae1f1e036 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -45,12 +45,11 @@ impl CombineAttributeParser for ReprParser { Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), - Warn(Target::MacroCall), ]), ); let attr_span = cx.attr_span; - cx.adcx().warn_empty_attribute(attr_span); + cx.adcx().empty_attribute(attr_span); return vec![]; } @@ -76,7 +75,7 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< ($arg: ident, $constructor: expr) => {{ cx.check_target( concat!("(", stringify!($arg), ")"), - &AllowedTargets::AllowList(&[Allow(Target::Enum), Warn(Target::MacroCall)]), + &AllowedTargets::AllowList(&[Allow(Target::Enum)]), ); cx.expect_no_args(param.args())?; Some($constructor) @@ -91,7 +90,6 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), - Warn(Target::MacroCall), ]), ); let l = cx.expect_list(param.args(), param.span())?; @@ -100,11 +98,7 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< Some(sym::packed) => { cx.check_target( "(packed)", - &AllowedTargets::AllowList(&[ - Allow(Target::Struct), - Allow(Target::Union), - Warn(Target::MacroCall), - ]), + &AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Union)]), ); match param.args() { ArgParser::NoArgs => Some(ReprPacked(Align::ONE)), @@ -123,7 +117,6 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), - Warn(Target::MacroCall), ]), ); cx.expect_no_args(param.args())?; @@ -136,7 +129,6 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< Allow(Target::Struct), Allow(Target::Enum), Allow(Target::Union), - Warn(Target::MacroCall), ]), ); cx.expect_no_args(param.args())?; @@ -162,8 +154,7 @@ fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option< &AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), - Allow(Target::Union), // Feature gated in `rustc_attr_ir_analysis` - Warn(Target::MacroCall), + Allow(Target::Union), // Feature gated in `rustc_hir_analysis` ]), ); cx.expect_no_args(param.args())?; diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index d9b2b38f55cc0..157f49c2f0bb6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -1,19 +1,15 @@ use rustc_attr_ir::RustcAbiAttrKind; use rustc_feature::AttributeStability; -use rustc_lint_defs::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use super::prelude::*; +use crate::context::ExpectStringLiteral; pub(crate) struct IgnoreParser; impl SingleAttributeParser for IgnoreParser { const PATH: &[Symbol] = &[sym::ignore]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Fn), - Error(Target::WherePredicate), - Error(Target::Param), - ]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!( Word, NameValueStr: "reason", "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute" @@ -21,27 +17,17 @@ impl SingleAttributeParser for IgnoreParser { const STABILITY: AttributeStability = AttributeStability::Stable; fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option { + let span = cx.attr_span; Some(AttributeKind::Ignore { - span: cx.attr_span, + span, reason: match args { ArgParser::NoArgs => None, - ArgParser::NameValue(name_value) => { - let Some(str_value) = name_value.value_as_str() else { - cx.adcx().warn_ill_formed_attribute_input(ILL_FORMED_ATTRIBUTE_INPUT); - return None; - }; + ArgParser::NameValue(nv) => { + let str_value = nv.expect_string_literal(cx)?; Some(str_value) } - ArgParser::List(list) => { - let help = - list.as_single().and_then(|item| item.meta_item()).and_then(|item| { - item.args().as_no_args().ok()?; - Some(item.path().to_string()) - }); - cx.adcx().warn_ill_formed_attribute_input_with_help( - ILL_FORMED_ATTRIBUTE_INPUT, - help, - ); + ArgParser::List(_) => { + cx.adcx().expected_no_args(span); return None; } }, @@ -53,12 +39,8 @@ pub(crate) struct ShouldPanicParser; impl SingleAttributeParser for ShouldPanicParser { const PATH: &[Symbol] = &[sym::should_panic]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowListWarnRest(&[ - Allow(Target::Fn), - Error(Target::WherePredicate), - Error(Target::Param), - ]); + + const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!( Word, List: &[r#"expected = "reason""#], NameValueStr: "reason", "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute" diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b99ee2840b7c8..2dba8444e3bc4 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -70,7 +70,7 @@ use crate::attributes::unroll::*; use crate::attributes::{AttributeParser as _, AttributeSafety, Combine, Single, WithoutArgs}; use crate::diagnostics::{ AttributeParseError, AttributeParseErrorReason, AttributeParseErrorSuggestions, - ParsedDescription, UnusedDuplicate, + ParsedDescription, UnusedDuplicate, UnusedMultiple, }; use crate::parser::{ ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItemParser, NameValueParser, @@ -474,6 +474,7 @@ impl<'f, 'sess: 'f> SharedContext<'f, 'sess> { (self.emit_lint)(LintId::of(lint), span.into(), kind); } + #[expect(unused)] pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) { self.emit_lint( UNUSED_ATTRIBUTES, @@ -658,6 +659,22 @@ impl<'f, 'sess: 'f> AcceptContext<'f, 'sess> { { arg.expect_string_literal(self) } + + pub(crate) fn unused_duplicate(&mut self, used_span: Span, unused_span: Span) { + self.cx.emit_err(UnusedMultiple { + this: unused_span, + other: used_span, + name: Symbol::intern( + &self + .attr_path + .segments + .iter() + .map(|i| i.to_string()) + .collect::>() + .join(".."), + ), + }); + } } pub(crate) trait ExpectNameValue { @@ -1143,18 +1160,14 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> { ) } - pub(crate) fn warn_empty_attribute(&mut self, span: Span) { + pub(crate) fn empty_attribute(&mut self, span: Span) { let attr_path = self.attr_path.to_string(); let valid_without_list = self.template.word; - self.emit_lint( - UNUSED_ATTRIBUTES, - crate::diagnostics::EmptyAttributeList { - attr_span: span, - attr_path, - valid_without_list, - }, - span, - ); + self.emit_err(crate::diagnostics::EmptyAttributeList { + attr_span: span, + attr_path, + valid_without_list, + }); } pub(crate) fn warn_ill_formed_attribute_input(&mut self, lint: &'static Lint) { diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 81e99c1d4b231..390e42b59ac24 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -227,7 +227,10 @@ pub(crate) struct DocAutoCfgExpectsHideOrShow; #[derive(Diagnostic)] #[diag("there exists a built-in attribute with the same name")] -pub(crate) struct AmbiguousDeriveHelpers; +pub(crate) struct AmbiguousDeriveHelpers { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag("`#![doc(auto_cfg({$attr_name}(...)))]` only accepts identifiers or `values(...)`")] @@ -988,7 +991,10 @@ pub(crate) struct InlineForceInlineConflict { #[help( "externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`" )] -pub(crate) struct InlineIgnoredForExported; +pub(crate) struct InlineIgnoredForExported { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag("`#[ffi_const]` function cannot be `#[ffi_pure]`", code = E0757)] @@ -1944,7 +1950,10 @@ pub(crate) struct EmptyLinkName { #[warning( "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" )] -pub(crate) struct Link; +pub(crate) struct Link { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag("link kind `framework` is only supported on Apple targets", code = E0455)] diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 89d80b8c82ba7..d30ef8638a168 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -98,6 +98,10 @@ impl<'sess> AttributeParser<'sess> { attribute_args: &str, cx: &mut AcceptContext<'_, 'sess>, ) { + // bootstrapping crimes + if matches!(cx.sess.opts.crate_name, Some("std" | "subtle" | "zerocopy")) { + return; + } if matches!(cx.should_emit, ShouldEmit::Nothing) { return; } diff --git a/compiler/rustc_expand/src/diagnostics.rs b/compiler/rustc_expand/src/diagnostics.rs index 43da7a03a6454..f508bb348a06c 100644 --- a/compiler/rustc_expand/src/diagnostics.rs +++ b/compiler/rustc_expand/src/diagnostics.rs @@ -574,6 +574,7 @@ pub(crate) struct MacroArgsBadDelimSugg { "to document an item produced by a macro, the macro must produce the documentation as part of its expansion" )] pub(crate) struct MacroCallUnusedDocComment { + #[primary_span] #[label("rustdoc does not generate documentation for macro invocations")] pub span: Span, } @@ -602,21 +603,3 @@ pub(crate) struct TrailingMacro { pub is_trailing: bool, pub name: Ident, } - -#[derive(Diagnostic)] -#[diag("unused attribute `{$attr_name}`")] -pub(crate) struct UnusedBuiltinAttribute { - #[note( - "the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`" - )] - pub invoc_span: Span, - pub attr_name: Symbol, - pub macro_name: String, - #[suggestion( - "remove the attribute", - code = "", - applicability = "machine-applicable", - style = "tool-only" - )] - pub attr_span: Span, -} diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index b9c1bb9545d2f..71dce36ae62d1 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; -use std::{iter, mem, slice}; +use std::{iter, mem}; use rustc_ast::mut_visit::*; use rustc_ast::tokenstream::TokenStream; @@ -14,6 +14,7 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust; use rustc_attr_ir::target::{AstTarget, Target}; +use rustc_attr_ir::{Attribute, AttributeKind}; use rustc_attr_parsing::parser::AllowExprMetavar; use rustc_attr_parsing::{ AttributeParser, AttributeSafety, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, @@ -23,7 +24,6 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_errors::PResult; use rustc_feature::Features; use rustc_hir::def::MacroKinds; -use rustc_lint_defs::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS}; use rustc_parse::parser::{ AllowConstBlockItems, AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma, Recovery, token_descr, @@ -2231,66 +2231,43 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { // Run attributes through the attribute parser // since they will not be detected after macro expansion. fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) { - use SyntheticAttr::*; - let mut attrs = attrs.iter().peekable(); - let mut span: Option = None; - while let Some(attr) = attrs.next() { - validate_attr::check_attr(&self.cx.sess.psess, attr); - AttributeParser::parse_limited_all( - self.cx.sess, - slice::from_ref(attr), - None, - AstTarget::MacroCall, - call.span(), - self.cx.current_expansion.lint_node_id, - Some(self.cx.ecfg.features), - ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }, - Some(self.cx.resolver.registered_attr_tools()), - ); - - let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span }; - span = Some(current_span); - - if attrs.peek().is_some_and(|next_attr| next_attr.doc_str().is_some()) { - continue; - } - - if match &attr.kind { - AttrKind::Normal(normal) => normal.item.name() == Some(sym::doc), - AttrKind::DocComment(..) => true, - _ => false, - } { - self.cx.sess.psess.buffer_lint( - UNUSED_DOC_COMMENTS, - current_span, - self.cx.current_expansion.lint_node_id, - crate::diagnostics::MacroCallUnusedDocComment { span: attr.span }, - ); - continue; + let attrs = AttributeParser::parse_limited_all( + self.cx.sess, + attrs, + None, + AstTarget::MacroCall, + call.span(), + self.cx.current_expansion.lint_node_id, + Some(self.cx.ecfg.features), + ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }, + Some(self.cx.resolver.registered_attr_tools()), + ); + let first_doc_span = attrs.iter().find_map(|attr| { + if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = attr { + Some(span) + } else { + None } + }); - match &attr.kind { - AttrKind::Normal(normal) - if rustc_attr_parsing::is_builtin_attr(&normal.item) - && !AttributeParser::is_parsed_attribute(&attr.path()) => - { - let attr_name = attr.name().unwrap(); - self.cx.sess.psess.buffer_lint( - UNUSED_ATTRIBUTES, - attr.span, - self.cx.current_expansion.lint_node_id, - crate::diagnostics::UnusedBuiltinAttribute { - attr_name, - macro_name: pprust::path_to_string(&call.path), - invoc_span: call.path.span, - attr_span: attr.span, - }, - ); - } - AttrKind::Normal(_) => {} - AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) | AttrKind::Generated(..) => {} - AttrKind::DocComment(..) => unreachable!(), // handled above - } + if let Some(first_doc_span) = first_doc_span { + let last_doc_span = attrs + .iter() + .rev() + .find_map(|attr| { + if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = attr { + Some(span) + } else { + None + } + }) + .unwrap(); + let span = first_doc_span.to(*last_doc_span); + self.cx + .sess + .psess + .dcx() + .emit_err(crate::diagnostics::MacroCallUnusedDocComment { span }); } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 41bc7b0a1539f..78cd47999cdc9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -28,9 +28,8 @@ use rustc_hir::{ ItemKind, Mod, Node, ParamName, TraitItem, }; use rustc_lint_defs::builtin::{ - CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, - MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, - UNUSED_ATTRIBUTES, + CONFLICTING_REPR_HINTS, MALFORMED_DIAGNOSTIC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, UNUSED_ATTRIBUTES, }; use rustc_macros::Diagnostic; use rustc_middle::hir::nested_filter; @@ -426,15 +425,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; } - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - span, - diagnostics::Unused { - attr_span: span, - note: diagnostics::UnusedNote::PathOnInlineModule, - }, - ); + self.tcx.dcx().emit_err(diagnostics::Unused { + attr_span: span, + note: diagnostics::UnusedNote::PathOnInlineModule, + }); } fn has_nested_module_path_dependency(&self, module: &Mod<'tcx>) -> bool { @@ -850,28 +844,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_doc_masked(&self, span: Span, hir_id: HirId, target: Target) { if target != Target::ExternCrate { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - span, - diagnostics::DocMaskedOnlyExternCrate { - attr_span: span, - item_span: self.tcx.hir_span(hir_id), - }, - ); + self.tcx.dcx().emit_err(diagnostics::DocMaskedOnlyExternCrate { + attr_span: span, + item_span: self.tcx.hir_span(hir_id), + }); return; } if self.tcx.extern_mod_stmt_cnum(hir_id.owner.def_id).is_none() { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - span, - diagnostics::DocMaskedNotExternCrateSelf { - attr_span: span, - item_span: self.tcx.hir_span(hir_id), - }, - ); + self.tcx.dcx().emit_err(diagnostics::DocMaskedNotExternCrateSelf { + attr_span: span, + item_span: self.tcx.hir_span(hir_id), + }); } } @@ -1213,7 +1197,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_mix_no_mangle_export(&self, hir_id: HirId, attrs: &[Attribute]) { + fn check_mix_no_mangle_export(&self, _: HirId, attrs: &[Attribute]) { if let Some(export_name_span) = find_attr!(attrs, ExportName { span: export_name_span, .. } => *export_name_span) && let Some(no_mangle_span) = @@ -1230,17 +1214,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { "#[export_name]" }; - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, + self.tcx.dcx().emit_err(diagnostics::MixedExportNameAndNoMangle { no_mangle_span, - diagnostics::MixedExportNameAndNoMangle { - no_mangle_span, - export_name_span, - no_mangle_attr, - export_name_attr, - }, - ); + export_name_span, + no_mangle_attr, + export_name_attr, + }); } } From 98a6cbf8b1bd99e52235cbcc05180ff3b88428e1 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 9 Nov 2026 00:28:56 +0100 Subject: [PATCH 3/5] dont pgo cargo --- src/build_helper/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/build_helper/src/lib.rs b/src/build_helper/src/lib.rs index ef52aa58a9904..e8d1037d4d284 100644 --- a/src/build_helper/src/lib.rs +++ b/src/build_helper/src/lib.rs @@ -14,7 +14,6 @@ pub mod util; /// The default set of crates for opt-dist to collect backend (LLVM, Cranelift) profiles. pub const BACKEND_PGO_CRATES: &[&str] = &[ "syn-2.0.101", - "cargo-0.87.1", "serde-1.0.219", "ripgrep-14.1.1", "regex-automata-0.4.8", @@ -26,7 +25,6 @@ pub const BACKEND_PGO_CRATES: &[&str] = &[ pub const RUSTC_PGO_CRATES: &[&str] = &[ "externs", "ctfe-stress-5", - "cargo-0.87.1", "token-stream-stress", "enum-stress", "tuple-stress", From 40fbd2d7dc10a89de70a8de0de38cea92ff8b25e Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 9 Nov 2026 15:00:06 +0100 Subject: [PATCH 4/5] error on ungated track_caller on async fn --- compiler/rustc_ast_lowering/src/expr.rs | 6 ++-- .../src/attributes/codegen_attrs.rs | 20 ++++++++--- compiler/rustc_lint/src/builtin.rs | 34 +++---------------- compiler/rustc_lint/src/diagnostics.rs | 22 +----------- 4 files changed, 24 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 26e3f88614efc..93baccfcd5939 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -966,11 +966,9 @@ impl<'hir> LoweringContext<'_, 'hir> { })) } - /// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to - /// `inner_hir_id` in case the `async_fn_track_caller` feature is enabled. + /// Forwards a possible `#[track_caller]` annotation from `outer_hir_id` to `inner_hir_id`. pub(super) fn maybe_forward_track_caller(&mut self, outer_hir_id: HirId, inner_hir_id: HirId) { - if self.tcx.features().async_fn_track_caller() - && let Some(attrs) = self.curr_owner.attrs.get(&outer_hir_id.local_id) + if let Some(attrs) = self.curr_owner.attrs.get(&outer_hir_id.local_id) && let Some(t) = attrs.iter().find(|a| { matches!( a, diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 4c69fb2c26d51..589b05c3daad1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -1,3 +1,4 @@ +use rustc_attr_ir::target::AstTarget; use rustc_attr_ir::{ CoverageAttrKind, InstrumentFnAttr, OptimizeAttr, RtsanSetting, UsedBy, find_attr, }; @@ -389,8 +390,8 @@ impl NoArgsAttributeParser for TrackCallerParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller; fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { - match cx.target { - Target::Fn => { + match cx.ast_target { + AstTarget::Fn(f) => { // `#[track_caller]` is not valid on weak lang items because they are called via // `extern` declarations and `#[track_caller]` would alter their ABI. if let Some(item) = find_attr!(cx.parsed_attrs, Lang(item) => item) @@ -402,13 +403,24 @@ impl NoArgsAttributeParser for TrackCallerParser { sig_span: cx.target_span, }); } + + if f.sig.header.coroutine_marker.is_some() && !cx.features().async_fn_track_caller() + { + feature_err( + cx.sess(), + sym::async_fn_track_caller, + attr_span, + "`#[track_caller]` on async functions is unstable", + ) + .emit(); + } } - Target::Closure if !cx.features().closure_track_caller() => { + AstTarget::Closure(_) if !cx.features().closure_track_caller() => { feature_err( cx.sess(), sym::closure_track_caller, attr_span, - "`#[track_caller]` on closures is currently unstable", + "`#[track_caller]` on closures is unstable", ) .emit(); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index aa69776374322..1e627eb0bbb93 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -28,8 +28,7 @@ use rustc_errors::{Applicability, Diagnostic, msg}; use rustc_feature::GateIssue; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; -use rustc_hir::intravisit::FnKind as HirFnKind; -use rustc_hir::{self as hir, Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin}; +use rustc_hir::{self as hir, ImplItemImplKind, PatKind, PredicateOrigin}; // Lints from rustc_lint_defs pub use rustc_lint_defs::builtin::*; use rustc_lint_defs::{declare_lint, declare_lint_pass, fcw, impl_lint_pass}; @@ -54,10 +53,9 @@ use crate::diagnostics::{ BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, BuiltinMutablesTransmutes, BuiltinNonShorthandFieldPatterns, BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, - BuiltinTypeAliasBounds, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit, - BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, - BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub, BuiltinWhileTrue, - EqInternalMethodImplemented, InvalidAsmLabel, + BuiltinTypeAliasBounds, BuiltinUnpermittedTypeInit, BuiltinUnpermittedTypeInitSub, + BuiltinUnreachablePub, BuiltinUnsafe, BuiltinUnstableFeatures, BuiltinUnusedDocComment, + BuiltinUnusedDocCommentSub, BuiltinWhileTrue, EqInternalMethodImplemented, InvalidAsmLabel, }; use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}; @@ -1070,29 +1068,7 @@ declare_lint_pass!( UngatedAsyncFnTrackCaller => [UNGATED_ASYNC_FN_TRACK_CALLER] ); -impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller { - fn check_fn( - &mut self, - cx: &LateContext<'_>, - fn_kind: HirFnKind<'_>, - _: &'tcx FnDecl<'_>, - _: &'tcx Body<'_>, - span: Span, - def_id: LocalDefId, - ) { - if fn_kind.asyncness().is_async() - && !cx.tcx.features().async_fn_track_caller() - // Now, check if the function has the `#[track_caller]` attribute - && let Some(attr_span) = find_attr!(cx.tcx, def_id, TrackCaller(span) => *span) - { - cx.emit_span_lint( - UNGATED_ASYNC_FN_TRACK_CALLER, - attr_span, - BuiltinUngatedAsyncFnTrackCaller { label: span, session: &cx.tcx.sess }, - ); - } - } -} +impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {} declare_lint! { /// The `unreachable_pub` lint triggers for `pub` items not reachable from other crates - that diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index 2b1a8132e65e8..d82b806ca9f2a 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -15,9 +15,8 @@ use rustc_hir::intravisit::Visitor; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::inhabitedness::InhabitedPredicate; use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt}; -use rustc_session::Session; use rustc_span::edition::Edition; -use rustc_span::{Ident, Span, Symbol, sym}; +use rustc_span::{Ident, Span, Symbol}; use rustc_structures::LintName; use crate::LateContext; @@ -347,25 +346,6 @@ pub(crate) struct BuiltinMutablesTransmutes; #[diag("use of an unstable feature")] pub(crate) struct BuiltinUnstableFeatures; -// lint_ungated_async_fn_track_caller -pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> { - pub label: Span, - pub session: &'a Session, -} - -impl<'a> Diagnostic<'a> for BuiltinUngatedAsyncFnTrackCaller<'_> { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a> { - let mut diag = Diag::new(dcx, level, "`#[track_caller]` on async functions is a no-op") - .with_span_label(self.label, "this function will not propagate the caller location"); - rustc_session::diagnostics::add_feature_diagnostics( - &mut diag, - self.session, - sym::async_fn_track_caller, - ); - diag - } -} - #[derive(Diagnostic)] #[diag("unreachable `pub` {$what}")] pub(crate) struct BuiltinUnreachablePub<'a> { From 2d97171713c9ecce3a56fb63bbcdcfad31da3225 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Mon, 9 Nov 2026 15:10:22 +0100 Subject: [PATCH 5/5] error on const no_mangle --- .../src/attributes/codegen_attrs.rs | 3 +-- compiler/rustc_lint/src/builtin.rs | 21 +------------------ compiler/rustc_lint/src/diagnostics.rs | 7 ------- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 589b05c3daad1..7fa0be3cc26ba 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -17,7 +17,6 @@ use crate::diagnostics::{ TrackCallerOnLangItem, }; use crate::target_checking::AllowedResult; -use crate::target_checking::Policy::AllowSilent; pub(crate) struct OptimizeParser; @@ -442,7 +441,7 @@ impl NoArgsAttributeParser for NoMangleParser { Allow(Target::Static), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), - AllowSilent(Target::Const), // Handled in the `InvalidNoMangleItems` pass + Error(Target::Const), Error(Target::Closure), Error(Target::Param), ]); diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 1e627eb0bbb93..d80ed636df7c7 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -46,7 +46,7 @@ use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::diagnostics::{ - BuiltinAnonymousParams, BuiltinConstNoMangle, BuiltinDerefNullptr, BuiltinDoubleNegations, + BuiltinAnonymousParams, BuiltinDerefNullptr, BuiltinDoubleNegations, BuiltinDoubleNegationsAddParens, BuiltinEllipsisInclusiveRangePatterns, BuiltinEllipsisInclusiveRangePatternsLint, BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures, @@ -893,25 +893,6 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id); } } - hir::ItemKind::Const(ident, generics, ..) => { - if find_attr!(attrs, NoMangle(..)) { - let suggestion = - if generics.params.is_empty() && generics.where_clause_span.is_empty() { - // account for "pub const" (#45562) - Some(it.span.until(ident.span)) - } else { - None - }; - - // Const items do not refer to a particular location in memory, and therefore - // don't have anything to attach a symbol to - cx.emit_span_lint( - NO_MANGLE_CONST_ITEMS, - it.span, - BuiltinConstNoMangle { suggestion }, - ); - } - } _ => {} } } diff --git a/compiler/rustc_lint/src/diagnostics.rs b/compiler/rustc_lint/src/diagnostics.rs index d82b806ca9f2a..4cf8e9a0af077 100644 --- a/compiler/rustc_lint/src/diagnostics.rs +++ b/compiler/rustc_lint/src/diagnostics.rs @@ -329,13 +329,6 @@ pub(crate) enum BuiltinUnusedDocCommentSub { BlockHelp, } -#[derive(Diagnostic)] -#[diag("const items should never be `#[no_mangle]`")] -pub(crate) struct BuiltinConstNoMangle { - #[suggestion("try a static value", code = "pub static ", applicability = "machine-applicable")] - pub suggestion: Option, -} - #[derive(Diagnostic)] #[diag( "transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell"