From a51a793472fc6ba16247ddc06e366f7993d8ae93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Tue, 14 Oct 2025 17:27:38 +0200 Subject: [PATCH] only check duplicates on old/unparsed attributes --- compiler/rustc_passes/src/check_attr.rs | 33 ++++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index cba6243fa1098..5f0d7cdb59ef0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -393,8 +393,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - let builtin = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); - if hir_id != CRATE_HIR_ID { match attr { Attribute::Parsed(_) => { /* Already validated. */ } @@ -440,8 +438,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - if let Some(BuiltinAttribute { duplicates, .. }) = builtin { - check_duplicates(self.tcx, attr, hir_id, *duplicates, &mut seen); + if let Attribute::Unparsed(unparsed_attr) = attr + && let Some(BuiltinAttribute { duplicates, .. }) = + attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) + { + check_duplicates( + self.tcx, + unparsed_attr.span, + attr, + hir_id, + *duplicates, + &mut seen, + ); } self.check_unused_attribute(hir_id, attr, style) @@ -2481,6 +2489,7 @@ pub(crate) fn provide(providers: &mut Providers) { // FIXME(jdonszelmann): remove, check during parsing fn check_duplicates( tcx: TyCtxt<'_>, + attr_span: Span, attr: &Attribute, hir_id: HirId, duplicates: AttributeDuplicates, @@ -2497,10 +2506,10 @@ fn check_duplicates( match seen.entry(attr_name) { Entry::Occupied(mut entry) => { let (this, other) = if matches!(duplicates, FutureWarnPreceding) { - let to_remove = entry.insert(attr.span()); - (to_remove, attr.span()) + let to_remove = entry.insert(attr_span); + (to_remove, attr_span) } else { - (attr.span(), *entry.get()) + (attr_span, *entry.get()) }; tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, @@ -2517,22 +2526,22 @@ fn check_duplicates( ); } Entry::Vacant(entry) => { - entry.insert(attr.span()); + entry.insert(attr_span); } } } ErrorFollowing | ErrorPreceding => match seen.entry(attr_name) { Entry::Occupied(mut entry) => { let (this, other) = if matches!(duplicates, ErrorPreceding) { - let to_remove = entry.insert(attr.span()); - (to_remove, attr.span()) + let to_remove = entry.insert(attr_span); + (to_remove, attr_span) } else { - (attr.span(), *entry.get()) + (attr_span, *entry.get()) }; tcx.dcx().emit_err(errors::UnusedMultiple { this, other, name: attr_name }); } Entry::Vacant(entry) => { - entry.insert(attr.span()); + entry.insert(attr_span); } }, }