diff --git a/Cargo.lock b/Cargo.lock index bac0aeb37c600..2345f07b10df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4004,6 +4004,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_error_messages", + "rustc_errors", "rustc_hashes", "rustc_hir_id", "rustc_index", diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6d97b50e9528e..1af4127e1d07b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -41,7 +41,7 @@ use std::sync::Arc; use rustc_ast::node_id::NodeMap; use rustc_ast::visit::Visitor; use rustc_ast::{self as ast, *}; -use rustc_attr_parsing::{AttributeParser, Late, OmitDoc}; +use rustc_attr_parsing::{AttributeParser, EmitAttribute, Late, OmitDoc}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; @@ -52,7 +52,7 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::PerParentDisambiguatorState; -use rustc_hir::lints::{AttributeLint, DelayedLint}; +use rustc_hir::lints::{AttributeLint, DelayedLint, DynAttribute}; use rustc_hir::{ self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, @@ -1174,13 +1174,23 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { target, OmitDoc::Lower, |s| l.lower(s), - |lint_id, span, kind| { - self.delayed_lints.push(DelayedLint::AttributeParsing(AttributeLint { - lint_id, - id: target_hir_id, - span, - kind, - })); + |lint_id, span, kind| match kind { + EmitAttribute::Static(attr_kind) => { + self.delayed_lints.push(DelayedLint::AttributeParsing(AttributeLint { + lint_id, + id: target_hir_id, + span, + kind: attr_kind, + })); + } + EmitAttribute::Dynamic(callback) => { + self.delayed_lints.push(DelayedLint::Dynamic(DynAttribute { + lint_id, + id: target_hir_id, + span, + callback, + })); + } }, ) } diff --git a/compiler/rustc_attr_parsing/src/attributes/autodiff.rs b/compiler/rustc_attr_parsing/src/attributes/autodiff.rs index 31e79e118bfaa..1f8c5fe3d3e54 100644 --- a/compiler/rustc_attr_parsing/src/attributes/autodiff.rs +++ b/compiler/rustc_attr_parsing/src/attributes/autodiff.rs @@ -8,8 +8,8 @@ use rustc_hir::{MethodKind, Target}; use rustc_span::{Symbol, sym}; use thin_vec::ThinVec; +use crate::attributes::SingleAttributeParser; use crate::attributes::prelude::Allow; -use crate::attributes::{OnDuplicate, SingleAttributeParser}; use crate::context::{AcceptContext, Stage}; use crate::parser::{ArgParser, MetaItemOrLitParser}; use crate::target_checking::AllowedTargets; @@ -18,7 +18,6 @@ pub(crate) struct RustcAutodiffParser; impl SingleAttributeParser for RustcAutodiffParser { const PATH: &[Symbol] = &[sym::rustc_autodiff]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), diff --git a/compiler/rustc_attr_parsing/src/attributes/body.rs b/compiler/rustc_attr_parsing/src/attributes/body.rs index a1492d7619461..46285c2323b89 100644 --- a/compiler/rustc_attr_parsing/src/attributes/body.rs +++ b/compiler/rustc_attr_parsing/src/attributes/body.rs @@ -6,7 +6,6 @@ pub(crate) struct CoroutineParser; impl NoArgsAttributeParser for CoroutineParser { const PATH: &[Symbol] = &[sym::coroutine]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); const CREATE: fn(rustc_span::Span) -> AttributeKind = |span| AttributeKind::Coroutine(span); } diff --git a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs index 81d5c8f99f45f..32ea506211c91 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs @@ -8,7 +8,6 @@ impl SingleAttributeParser for CfiEncodingParser { Allow(Target::Enum), Allow(Target::Union), ]); - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding"); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 53d02d09bb514..357be2f48f85e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -14,7 +14,6 @@ pub(crate) struct OptimizeParser; impl SingleAttributeParser for OptimizeParser { const PATH: &[Symbol] = &[sym::optimize]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), @@ -62,7 +61,6 @@ pub(crate) struct CoverageParser; impl SingleAttributeParser for CoverageParser { const PATH: &[Symbol] = &[sym::coverage]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Closure), @@ -143,7 +141,6 @@ pub(crate) struct RustcObjcClassParser; impl SingleAttributeParser for RustcObjcClassParser { const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName"); @@ -175,7 +172,6 @@ pub(crate) struct RustcObjcSelectorParser; impl SingleAttributeParser for RustcObjcSelectorParser { const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName"); @@ -591,8 +587,6 @@ impl SingleAttributeParser for SanitizeParser { r#"realtime = "nonblocking|blocking|caller""#, ]); - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { let Some(list) = args.list() else { let attr_span = cx.attr_span; @@ -695,7 +689,6 @@ pub(crate) struct ThreadLocalParser; impl NoArgsAttributeParser for ThreadLocalParser { const PATH: &[Symbol] = &[sym::thread_local]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static), Allow(Target::ForeignStatic)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ThreadLocal; @@ -705,7 +698,6 @@ pub(crate) struct RustcPassIndirectlyInNonRusticAbisParser; impl NoArgsAttributeParser for RustcPassIndirectlyInNonRusticAbisParser { const PATH: &[Symbol] = &[sym::rustc_pass_indirectly_in_non_rustic_abis]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcPassIndirectlyInNonRusticAbis; } @@ -714,7 +706,6 @@ pub(crate) struct RustcEiiForeignItemParser; impl NoArgsAttributeParser for RustcEiiForeignItemParser { const PATH: &[Symbol] = &[sym::rustc_eii_foreign_item]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn), Allow(Target::ForeignStatic)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEiiForeignItem; @@ -724,7 +715,6 @@ pub(crate) struct PatchableFunctionEntryParser; impl SingleAttributeParser for PatchableFunctionEntryParser { const PATH: &[Symbol] = &[sym::patchable_function_entry]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]); diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 774fd0805a7a8..fed4ca7e76ab5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -108,7 +108,6 @@ pub(crate) struct MoveSizeLimitParser; impl SingleAttributeParser for MoveSizeLimitParser { const PATH: &[Symbol] = &[sym::move_size_limit]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -154,7 +153,6 @@ pub(crate) struct PatternComplexityLimitParser; impl SingleAttributeParser for PatternComplexityLimitParser { const PATH: &[Symbol] = &[sym::pattern_complexity_limit]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); @@ -177,7 +175,6 @@ pub(crate) struct NoCoreParser; impl NoArgsAttributeParser for NoCoreParser { const PATH: &[Symbol] = &[sym::no_core]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore; } @@ -204,7 +201,6 @@ pub(crate) struct RustcCoherenceIsCoreParser; impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore; } @@ -247,7 +243,6 @@ pub(crate) struct PanicRuntimeParser; impl NoArgsAttributeParser for PanicRuntimeParser { const PATH: &[Symbol] = &[sym::panic_runtime]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PanicRuntime; } @@ -256,7 +251,6 @@ pub(crate) struct NeedsPanicRuntimeParser; impl NoArgsAttributeParser for NeedsPanicRuntimeParser { const PATH: &[Symbol] = &[sym::needs_panic_runtime]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsPanicRuntime; } @@ -265,7 +259,6 @@ pub(crate) struct ProfilerRuntimeParser; impl NoArgsAttributeParser for ProfilerRuntimeParser { const PATH: &[Symbol] = &[sym::profiler_runtime]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ProfilerRuntime; } @@ -283,7 +276,6 @@ pub(crate) struct RustcPreserveUbChecksParser; impl NoArgsAttributeParser for RustcPreserveUbChecksParser { const PATH: &[Symbol] = &[sym::rustc_preserve_ub_checks]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcPreserveUbChecks; } @@ -292,7 +284,6 @@ pub(crate) struct RustcNoImplicitBoundsParser; impl NoArgsAttributeParser for RustcNoImplicitBoundsParser { const PATH: &[Symbol] = &[sym::rustc_no_implicit_bounds]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNoImplicitBounds; } @@ -301,7 +292,6 @@ pub(crate) struct DefaultLibAllocatorParser; impl NoArgsAttributeParser for DefaultLibAllocatorParser { const PATH: &[Symbol] = &[sym::default_lib_allocator]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::DefaultLibAllocator; } diff --git a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs index 35996904e8c73..e948d120fafb3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/deprecation.rs +++ b/compiler/rustc_attr_parsing/src/attributes/deprecation.rs @@ -34,7 +34,6 @@ fn get( pub(crate) struct DeprecatedParser; impl SingleAttributeParser for DeprecatedParser { const PATH: &[Symbol] = &[sym::deprecated]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ Allow(Target::Fn), Allow(Target::Mod), diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 99f856684abd5..a5b8c0ebe25eb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -1,5 +1,5 @@ use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit}; -use rustc_errors::msg; +use rustc_errors::{Diagnostic, msg}; use rustc_feature::template; use rustc_hir::Target; use rustc_hir::attrs::{ @@ -171,12 +171,15 @@ impl DocParser { if let Some(used_span) = self.attribute.no_crate_inject { let unused_span = path.span(); - cx.emit_lint( + cx.emit_dyn_lint( rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, - AttributeLintKind::UnusedDuplicate { - this: unused_span, - other: used_span, - warning: true, + move |dcx, level| { + rustc_errors::lints::UnusedDuplicate { + this: unused_span, + other: used_span, + warning: true, + } + .into_diag(dcx, level) }, unused_span, ); diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index e5b2fb130a185..32f995753bad3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -67,7 +67,6 @@ pub(crate) struct RustcForceInlineParser; impl SingleAttributeParser for RustcForceInlineParser { const PATH: &[Symbol] = &[sym::rustc_force_inline]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), diff --git a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs index 4003aba76af8e..36e45a763e172 100644 --- a/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs +++ b/compiler/rustc_attr_parsing/src/attributes/instruction_set.rs @@ -15,7 +15,6 @@ impl SingleAttributeParser for InstructionSetParser { Allow(Target::Method(MethodKind::Trait { body: true })), ]); const TEMPLATE: AttributeTemplate = template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"); - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32]; diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index b6ba7f9e21d49..9f48f7f8ab559 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -502,7 +502,6 @@ impl SingleAttributeParser for LinkSectionParser { pub(crate) struct ExportStableParser; impl NoArgsAttributeParser for ExportStableParser { const PATH: &[Symbol] = &[sym::export_stable]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable; } @@ -510,7 +509,6 @@ impl NoArgsAttributeParser for ExportStableParser { pub(crate) struct FfiConstParser; impl NoArgsAttributeParser for FfiConstParser { const PATH: &[Symbol] = &[sym::ffi_const]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None }; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst; @@ -519,7 +517,6 @@ impl NoArgsAttributeParser for FfiConstParser { pub(crate) struct FfiPureParser; impl NoArgsAttributeParser for FfiPureParser { const PATH: &[Symbol] = &[sym::ffi_pure]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None }; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; @@ -528,7 +525,6 @@ impl NoArgsAttributeParser for FfiPureParser { pub(crate) struct RustcStdInternalSymbolParser; impl NoArgsAttributeParser for RustcStdInternalSymbolParser { const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::ForeignFn), @@ -542,7 +538,6 @@ pub(crate) struct LinkOrdinalParser; impl SingleAttributeParser for LinkOrdinalParser { const PATH: &[Symbol] = &[sym::link_ordinal]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::ForeignFn), Allow(Target::ForeignStatic), @@ -583,7 +578,6 @@ pub(crate) struct LinkageParser; impl SingleAttributeParser for LinkageParser { const PATH: &[Symbol] = &[sym::linkage]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -666,7 +660,6 @@ pub(crate) struct NeedsAllocatorParser; impl NoArgsAttributeParser for NeedsAllocatorParser { const PATH: &[Symbol] = &[sym::needs_allocator]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NeedsAllocator; } @@ -675,7 +668,6 @@ pub(crate) struct CompilerBuiltinsParser; impl NoArgsAttributeParser for CompilerBuiltinsParser { const PATH: &[Symbol] = &[sym::compiler_builtins]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CompilerBuiltins; } diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 76bddacd20bf4..db29f193802e1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -3,7 +3,6 @@ use super::prelude::*; pub(crate) struct RustcAsPtrParser; impl NoArgsAttributeParser for RustcAsPtrParser { const PATH: &[Symbol] = &[sym::rustc_as_ptr]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -17,7 +16,6 @@ impl NoArgsAttributeParser for RustcAsPtrParser { pub(crate) struct RustcPubTransparentParser; impl NoArgsAttributeParser for RustcPubTransparentParser { const PATH: &[Symbol] = &[sym::rustc_pub_transparent]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), @@ -29,7 +27,6 @@ impl NoArgsAttributeParser for RustcPubTransparentParser { pub(crate) struct RustcPassByValueParser; impl NoArgsAttributeParser for RustcPassByValueParser { const PATH: &[Symbol] = &[sym::rustc_pass_by_value]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), @@ -41,7 +38,6 @@ impl NoArgsAttributeParser for RustcPassByValueParser { pub(crate) struct RustcShouldNotBeCalledOnConstItemsParser; impl NoArgsAttributeParser for RustcShouldNotBeCalledOnConstItemsParser { const PATH: &[Symbol] = &[sym::rustc_should_not_be_called_on_const_items]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), diff --git a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs index 528090b8673dc..1ad34baeeb886 100644 --- a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs +++ b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs @@ -3,7 +3,6 @@ use super::prelude::*; pub(crate) struct LoopMatchParser; impl NoArgsAttributeParser for LoopMatchParser { const PATH: &[Symbol] = &[sym::loop_match]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Expression)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch; } @@ -11,7 +10,6 @@ impl NoArgsAttributeParser for LoopMatchParser { pub(crate) struct ConstContinueParser; impl NoArgsAttributeParser for ConstContinueParser { const PATH: &[Symbol] = &[sym::const_continue]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Expression)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue; } diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index a0ded93180eb0..7dcf1b3eb0641 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -167,7 +167,6 @@ pub(crate) struct CollapseDebugInfoParser; impl SingleAttributeParser for CollapseDebugInfoParser { const PATH: &[Symbol] = &[sym::collapse_debuginfo]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!( List: &["no", "external", "yes"], "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute" @@ -203,7 +202,6 @@ pub(crate) struct RustcProcMacroDeclsParser; impl NoArgsAttributeParser for RustcProcMacroDeclsParser { const PATH: &[Symbol] = &[sym::rustc_proc_macro_decls]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Static)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcProcMacroDecls; } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 7432d9ca8749c..ba2e2b54e25b5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -128,7 +128,7 @@ pub(crate) trait SingleAttributeParser: 'static { /// Configures what to do when when the same attribute is /// applied more than once on the same syntax node. - const ON_DUPLICATE: OnDuplicate; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const SAFETY: AttributeSafety = AttributeSafety::Normal; const ALLOWED_TARGETS: AllowedTargets; @@ -240,7 +240,7 @@ pub enum AttributeSafety { // pub(crate) trait NoArgsAttributeParser: 'static { const PATH: &[Symbol]; - const ON_DUPLICATE: OnDuplicate; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets; const SAFETY: AttributeSafety = AttributeSafety::Normal; diff --git a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs index a951518129584..5ff637cdb0560 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_not_suspend.rs @@ -4,7 +4,6 @@ pub(crate) struct MustNotSuspendParser; impl SingleAttributeParser for MustNotSuspendParser { const PATH: &[rustc_span::Symbol] = &[sym::must_not_suspend]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), diff --git a/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs b/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs index 597a9515b0048..52c380fbb78d6 100644 --- a/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs +++ b/compiler/rustc_attr_parsing/src/attributes/pin_v2.rs @@ -2,7 +2,7 @@ use rustc_hir::Target; use rustc_hir::attrs::AttributeKind; use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::attributes::NoArgsAttributeParser; use crate::context::Stage; use crate::target_checking::AllowedTargets; use crate::target_checking::Policy::Allow; @@ -11,7 +11,6 @@ pub(crate) struct PinV2Parser; impl NoArgsAttributeParser for PinV2Parser { const PATH: &[Symbol] = &[sym::pin_v2]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), 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 c5bf8737fffb6..7cb59856b8a25 100644 --- a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs @@ -9,7 +9,6 @@ const PROC_MACRO_ALLOWED_TARGETS: AllowedTargets = pub(crate) struct ProcMacroParser; impl NoArgsAttributeParser for ProcMacroParser { const PATH: &[Symbol] = &[sym::proc_macro]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacro; } @@ -17,7 +16,6 @@ impl NoArgsAttributeParser for ProcMacroParser { pub(crate) struct ProcMacroAttributeParser; impl NoArgsAttributeParser for ProcMacroAttributeParser { const PATH: &[Symbol] = &[sym::proc_macro_attribute]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacroAttribute; } @@ -25,7 +23,6 @@ impl NoArgsAttributeParser for ProcMacroAttributeParser { pub(crate) struct ProcMacroDeriveParser; impl SingleAttributeParser for ProcMacroDeriveParser { const PATH: &[Symbol] = &[sym::proc_macro_derive]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = PROC_MACRO_ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!( List: &["TraitName", "TraitName, attributes(name1, name2, ...)"], @@ -45,7 +42,6 @@ impl SingleAttributeParser for ProcMacroDeriveParser { pub(crate) struct RustcBuiltinMacroParser; impl SingleAttributeParser for RustcBuiltinMacroParser { const PATH: &[Symbol] = &[sym::rustc_builtin_macro]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]); const TEMPLATE: AttributeTemplate = template!(List: &["TraitName", "TraitName, attributes(name1, name2, ...)"]); diff --git a/compiler/rustc_attr_parsing/src/attributes/prototype.rs b/compiler/rustc_attr_parsing/src/attributes/prototype.rs index e23e2ba633f7f..b6110f627a8cf 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prototype.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prototype.rs @@ -5,7 +5,6 @@ use rustc_hir::Target; use rustc_hir::attrs::{AttributeKind, MirDialect, MirPhase}; use rustc_span::{Span, Symbol, sym}; -use super::OnDuplicate; use crate::attributes::SingleAttributeParser; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; @@ -18,8 +17,6 @@ pub(crate) struct CustomMirParser; impl SingleAttributeParser for CustomMirParser { const PATH: &[rustc_span::Symbol] = &[sym::custom_mir]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]); diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs index cf4f8eab32460..9590a23ae9341 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_allocator.rs @@ -4,7 +4,6 @@ pub(crate) struct RustcAllocatorParser; impl NoArgsAttributeParser for RustcAllocatorParser { const PATH: &[Symbol] = &[sym::rustc_allocator]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocator; @@ -14,7 +13,6 @@ pub(crate) struct RustcAllocatorZeroedParser; impl NoArgsAttributeParser for RustcAllocatorZeroedParser { const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcAllocatorZeroed; @@ -24,7 +22,6 @@ pub(crate) struct RustcAllocatorZeroedVariantParser; impl SingleAttributeParser for RustcAllocatorZeroedVariantParser { const PATH: &[Symbol] = &[sym::rustc_allocator_zeroed_variant]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "function"); @@ -43,7 +40,6 @@ pub(crate) struct RustcDeallocatorParser; impl NoArgsAttributeParser for RustcDeallocatorParser { const PATH: &[Symbol] = &[sym::rustc_deallocator]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDeallocator; @@ -53,7 +49,6 @@ pub(crate) struct RustcReallocatorParser; impl NoArgsAttributeParser for RustcReallocatorParser { const PATH: &[Symbol] = &[sym::rustc_reallocator]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn), Allow(Target::ForeignFn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcReallocator; diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs index e1b8b3b29bf00..e6f97683c6127 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -10,7 +10,6 @@ pub(crate) struct RustcDumpUserArgsParser; impl NoArgsAttributeParser for RustcDumpUserArgsParser { const PATH: &[Symbol] = &[sym::rustc_dump_user_args]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs; } @@ -19,7 +18,6 @@ pub(crate) struct RustcDumpDefParentsParser; impl NoArgsAttributeParser for RustcDumpDefParentsParser { const PATH: &[Symbol] = &[sym::rustc_dump_def_parents]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents; } @@ -37,7 +35,6 @@ impl SingleAttributeParser for RustcDumpDefPathParser { Allow(Target::ForeignStatic), Allow(Target::Impl { of_trait: false }), ]); - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(Word); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { if let Err(span) = args.no_args() { @@ -52,7 +49,6 @@ pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser; impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser { const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques; } @@ -61,7 +57,6 @@ pub(crate) struct RustcDumpInferredOutlivesParser; impl NoArgsAttributeParser for RustcDumpInferredOutlivesParser { const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Struct), Allow(Target::Enum), @@ -75,7 +70,6 @@ pub(crate) struct RustcDumpItemBoundsParser; impl NoArgsAttributeParser for RustcDumpItemBoundsParser { const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds; } @@ -148,7 +142,6 @@ pub(crate) struct RustcDumpObjectLifetimeDefaultsParser; impl NoArgsAttributeParser for RustcDumpObjectLifetimeDefaultsParser { const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::AssocConst), Allow(Target::AssocTy), @@ -175,7 +168,6 @@ pub(crate) struct RustcDumpPredicatesParser; impl NoArgsAttributeParser for RustcDumpPredicatesParser { const PATH: &[Symbol] = &[sym::rustc_dump_predicates]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::AssocConst), Allow(Target::AssocTy), @@ -212,7 +204,6 @@ impl SingleAttributeParser for RustcDumpSymbolNameParser { Allow(Target::ForeignStatic), Allow(Target::Impl { of_trait: false }), ]); - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(Word); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { if let Err(span) = args.no_args() { @@ -227,7 +218,6 @@ pub(crate) struct RustcDumpVariancesParser; impl NoArgsAttributeParser for RustcDumpVariancesParser { const PATH: &[Symbol] = &[sym::rustc_dump_variances]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Fn), @@ -245,7 +235,6 @@ pub(crate) struct RustcDumpVariancesOfOpaquesParser; impl NoArgsAttributeParser for RustcDumpVariancesOfOpaquesParser { const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques; } @@ -254,7 +243,6 @@ pub(crate) struct RustcDumpVtableParser; impl NoArgsAttributeParser for RustcDumpVtableParser { const PATH: &[Symbol] = &[sym::rustc_dump_vtable]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Impl { of_trait: true }), Allow(Target::TyAlias), diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 6d0d6d6ab99ba..3f4049366f405 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -19,7 +19,6 @@ pub(crate) struct RustcMainParser; impl NoArgsAttributeParser for RustcMainParser { const PATH: &[Symbol] = &[sym::rustc_main]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain; } @@ -28,7 +27,6 @@ pub(crate) struct RustcMustImplementOneOfParser; impl SingleAttributeParser for RustcMustImplementOneOfParser { const PATH: &[Symbol] = &[sym::rustc_must_implement_one_of]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { @@ -74,7 +72,6 @@ pub(crate) struct RustcNeverReturnsNullPtrParser; impl NoArgsAttributeParser for RustcNeverReturnsNullPtrParser { const PATH: &[Symbol] = &[sym::rustc_never_returns_null_ptr]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -88,7 +85,6 @@ pub(crate) struct RustcNoImplicitAutorefsParser; impl NoArgsAttributeParser for RustcNoImplicitAutorefsParser { const PATH: &[Symbol] = &[sym::rustc_no_implicit_autorefs]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -104,7 +100,6 @@ pub(crate) struct RustcLayoutScalarValidRangeStartParser; impl SingleAttributeParser for RustcLayoutScalarValidRangeStartParser { const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_start]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(List: &["start"]); @@ -118,7 +113,6 @@ pub(crate) struct RustcLayoutScalarValidRangeEndParser; impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser { const PATH: &[Symbol] = &[sym::rustc_layout_scalar_valid_range_end]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(List: &["end"]); @@ -132,7 +126,6 @@ pub(crate) struct RustcLegacyConstGenericsParser; impl SingleAttributeParser for RustcLegacyConstGenericsParser { const PATH: &[Symbol] = &[sym::rustc_legacy_const_generics]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const TEMPLATE: AttributeTemplate = template!(List: &["N"]); @@ -176,7 +169,6 @@ pub(crate) struct RustcInheritOverflowChecksParser; impl NoArgsAttributeParser for RustcInheritOverflowChecksParser { const PATH: &[Symbol] = &[sym::rustc_inherit_overflow_checks]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -190,7 +182,6 @@ pub(crate) struct RustcLintOptDenyFieldAccessParser; impl SingleAttributeParser for RustcLintOptDenyFieldAccessParser { const PATH: &[Symbol] = &[sym::rustc_lint_opt_deny_field_access]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]); const TEMPLATE: AttributeTemplate = template!(Word); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { @@ -210,7 +201,6 @@ pub(crate) struct RustcLintOptTyParser; impl NoArgsAttributeParser for RustcLintOptTyParser { const PATH: &[Symbol] = &[sym::rustc_lint_opt_ty]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcLintOptTy; } @@ -359,7 +349,6 @@ pub(crate) struct RustcDeprecatedSafe2024Parser; impl SingleAttributeParser for RustcDeprecatedSafe2024Parser { const PATH: &[Symbol] = &[sym::rustc_deprecated_safe_2024]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -400,7 +389,6 @@ pub(crate) struct RustcConversionSuggestionParser; impl NoArgsAttributeParser for RustcConversionSuggestionParser { const PATH: &[Symbol] = &[sym::rustc_conversion_suggestion]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -415,7 +403,6 @@ pub(crate) struct RustcCaptureAnalysisParser; impl NoArgsAttributeParser for RustcCaptureAnalysisParser { const PATH: &[Symbol] = &[sym::rustc_capture_analysis]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Closure)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCaptureAnalysis; } @@ -424,7 +411,6 @@ pub(crate) struct RustcNeverTypeOptionsParser; impl SingleAttributeParser for RustcNeverTypeOptionsParser { const PATH: &[Symbol] = &[sym::rustc_never_type_options]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &[ r#"fallback = "unit", "never", "no""#, @@ -507,7 +493,6 @@ pub(crate) struct RustcTrivialFieldReadsParser; impl NoArgsAttributeParser for RustcTrivialFieldReadsParser { const PATH: &[Symbol] = &[sym::rustc_trivial_field_reads]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcTrivialFieldReads; } @@ -516,7 +501,6 @@ pub(crate) struct RustcNoMirInlineParser; impl NoArgsAttributeParser for RustcNoMirInlineParser { const PATH: &[Symbol] = &[sym::rustc_no_mir_inline]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -546,7 +530,6 @@ pub(crate) struct RustcLintQueryInstabilityParser; impl NoArgsAttributeParser for RustcLintQueryInstabilityParser { const PATH: &[Symbol] = &[sym::rustc_lint_query_instability]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -561,7 +544,6 @@ pub(crate) struct RustcRegionsParser; impl NoArgsAttributeParser for RustcRegionsParser { const PATH: &[Symbol] = &[sym::rustc_regions]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -577,7 +559,6 @@ pub(crate) struct RustcLintUntrackedQueryInformationParser; impl NoArgsAttributeParser for RustcLintUntrackedQueryInformationParser { const PATH: &[Symbol] = &[sym::rustc_lint_untracked_query_information]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -593,7 +574,6 @@ pub(crate) struct RustcSimdMonomorphizeLaneLimitParser; impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser { const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); @@ -611,7 +591,6 @@ pub(crate) struct RustcScalableVectorParser; impl SingleAttributeParser for RustcScalableVectorParser { const PATH: &[Symbol] = &[sym::rustc_scalable_vector]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const TEMPLATE: AttributeTemplate = template!(Word, List: &["count"]); @@ -636,7 +615,6 @@ pub(crate) struct LangParser; impl SingleAttributeParser for LangParser { const PATH: &[Symbol] = &[sym::lang]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); @@ -662,7 +640,6 @@ pub(crate) struct RustcHasIncoherentInherentImplsParser; impl NoArgsAttributeParser for RustcHasIncoherentInherentImplsParser { const PATH: &[Symbol] = &[sym::rustc_has_incoherent_inherent_impls]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Trait), Allow(Target::Struct), @@ -677,7 +654,6 @@ pub(crate) struct PanicHandlerParser; impl NoArgsAttributeParser for PanicHandlerParser { const PATH: &[Symbol] = &[sym::panic_handler]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes` const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::Lang(LangItem::PanicImpl, span); } @@ -686,7 +662,6 @@ pub(crate) struct RustcNounwindParser; impl NoArgsAttributeParser for RustcNounwindParser { const PATH: &[Symbol] = &[sym::rustc_nounwind]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::ForeignFn), @@ -701,7 +676,6 @@ pub(crate) struct RustcOffloadKernelParser; impl NoArgsAttributeParser for RustcOffloadKernelParser { const PATH: &[Symbol] = &[sym::rustc_offload_kernel]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcOffloadKernel; } @@ -800,7 +774,6 @@ pub(crate) struct RustcNonConstTraitMethodParser; impl NoArgsAttributeParser for RustcNonConstTraitMethodParser { const PATH: &[Symbol] = &[sym::rustc_non_const_trait_method]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Method(MethodKind::Trait { body: true })), Allow(Target::Method(MethodKind::Trait { body: false })), @@ -919,8 +892,6 @@ pub(crate) struct RustcIfThisChangedParser; impl SingleAttributeParser for RustcIfThisChangedParser { const PATH: &[Symbol] = &[sym::rustc_if_this_changed]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ // tidy-alphabetical-start Allow(Target::AssocConst), @@ -1030,7 +1001,6 @@ pub(crate) struct RustcInsignificantDtorParser; impl NoArgsAttributeParser for RustcInsignificantDtorParser { const PATH: &[Symbol] = &[sym::rustc_insignificant_dtor]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Enum), Allow(Target::Struct), @@ -1043,7 +1013,6 @@ pub(crate) struct RustcEffectiveVisibilityParser; impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { const PATH: &[Symbol] = &[sym::rustc_effective_visibility]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Use), Allow(Target::Static), @@ -1082,7 +1051,6 @@ pub(crate) struct RustcDiagnosticItemParser; impl SingleAttributeParser for RustcDiagnosticItemParser { const PATH: &[Symbol] = &[sym::rustc_diagnostic_item]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Trait), Allow(Target::Struct), @@ -1121,7 +1089,6 @@ pub(crate) struct RustcDoNotConstCheckParser; impl NoArgsAttributeParser for RustcDoNotConstCheckParser { const PATH: &[Symbol] = &[sym::rustc_do_not_const_check]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -1136,7 +1103,6 @@ pub(crate) struct RustcNonnullOptimizationGuaranteedParser; impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser { const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed; } @@ -1145,7 +1111,6 @@ pub(crate) struct RustcStrictCoherenceParser; impl NoArgsAttributeParser for RustcStrictCoherenceParser { const PATH: &[Symbol] = &[sym::rustc_strict_coherence]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Trait), Allow(Target::Struct), @@ -1160,7 +1125,6 @@ pub(crate) struct RustcReservationImplParser; impl SingleAttributeParser for RustcReservationImplParser { const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]); @@ -1186,7 +1150,6 @@ pub(crate) struct PreludeImportParser; impl NoArgsAttributeParser for PreludeImportParser { const PATH: &[Symbol] = &[sym::prelude_import]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport; } @@ -1195,7 +1158,6 @@ pub(crate) struct RustcDocPrimitiveParser; impl SingleAttributeParser for RustcDocPrimitiveParser { const PATH: &[Symbol] = &[sym::rustc_doc_primitive]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name"); @@ -1219,7 +1181,6 @@ pub(crate) struct RustcIntrinsicParser; impl NoArgsAttributeParser for RustcIntrinsicParser { const PATH: &[Symbol] = &[sym::rustc_intrinsic]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsic; } @@ -1228,7 +1189,6 @@ pub(crate) struct RustcIntrinsicConstStableIndirectParser; impl NoArgsAttributeParser for RustcIntrinsicConstStableIndirectParser { const PATH: &'static [Symbol] = &[sym::rustc_intrinsic_const_stable_indirect]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcIntrinsicConstStableIndirect; } @@ -1237,7 +1197,6 @@ pub(crate) struct RustcExhaustiveParser; impl NoArgsAttributeParser for RustcExhaustiveParser { const PATH: &'static [Symbol] = &[sym::rustc_must_match_exhaustively]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Enum)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcMustMatchExhaustively; } diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs index d7f624832971f..28091d711a3d5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs +++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs @@ -3,7 +3,6 @@ use super::prelude::*; pub(crate) struct MayDangleParser; impl NoArgsAttributeParser for MayDangleParser { const PATH: &[Symbol] = &[sym::may_dangle]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs` const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle; } diff --git a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs index 4fe0f079bc83c..06087c8a4baa1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/test_attrs.rs @@ -102,7 +102,6 @@ pub(crate) struct ReexportTestHarnessMainParser; impl SingleAttributeParser for ReexportTestHarnessMainParser { const PATH: &[Symbol] = &[sym::reexport_test_harness_main]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); @@ -129,7 +128,6 @@ pub(crate) struct RustcAbiParser; impl SingleAttributeParser for RustcAbiParser { const PATH: &[Symbol] = &[sym::rustc_abi]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]); const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::TyAlias), @@ -179,7 +177,6 @@ pub(crate) struct RustcDelayedBugFromInsideQueryParser; impl NoArgsAttributeParser for RustcDelayedBugFromInsideQueryParser { const PATH: &[Symbol] = &[sym::rustc_delayed_bug_from_inside_query]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDelayedBugFromInsideQuery; } @@ -188,7 +185,6 @@ pub(crate) struct RustcEvaluateWhereClausesParser; impl NoArgsAttributeParser for RustcEvaluateWhereClausesParser { const PATH: &[Symbol] = &[sym::rustc_evaluate_where_clauses]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Fn), Allow(Target::Method(MethodKind::Inherent)), @@ -203,7 +199,6 @@ pub(crate) struct TestRunnerParser; impl SingleAttributeParser for TestRunnerParser { const PATH: &[Symbol] = &[sym::test_runner]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); const TEMPLATE: AttributeTemplate = template!(List: &["path"]); @@ -223,7 +218,6 @@ pub(crate) struct RustcTestMarkerParser; impl SingleAttributeParser for RustcTestMarkerParser { const PATH: &[Symbol] = &[sym::rustc_test_marker]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Const), Allow(Target::Fn), diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index e3f5f30dd4e86..b2a9addfeab3c 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -1,7 +1,7 @@ use std::mem; use super::prelude::*; -use crate::attributes::{NoArgsAttributeParser, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{NoArgsAttributeParser, SingleAttributeParser}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; use crate::target_checking::AllowedTargets; @@ -10,7 +10,6 @@ use crate::target_checking::Policy::{Allow, Warn}; pub(crate) struct RustcSkipDuringMethodDispatchParser; impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser { const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]); @@ -60,7 +59,6 @@ impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser pub(crate) struct RustcParenSugarParser; impl NoArgsAttributeParser for RustcParenSugarParser { const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcParenSugar; } @@ -70,7 +68,6 @@ impl NoArgsAttributeParser for RustcParenSugarParser { pub(crate) struct MarkerParser; impl NoArgsAttributeParser for MarkerParser { const PATH: &[Symbol] = &[sym::marker]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ Allow(Target::Trait), Warn(Target::Field), @@ -83,7 +80,6 @@ impl NoArgsAttributeParser for MarkerParser { pub(crate) struct RustcDenyExplicitImplParser; impl NoArgsAttributeParser for RustcDenyExplicitImplParser { const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDenyExplicitImpl; } @@ -91,7 +87,6 @@ impl NoArgsAttributeParser for RustcDenyExplicitImplParser { pub(crate) struct RustcDynIncompatibleTraitParser; impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait; } @@ -101,7 +96,6 @@ impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { pub(crate) struct RustcSpecializationTraitParser; impl NoArgsAttributeParser for RustcSpecializationTraitParser { const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcSpecializationTrait; } @@ -109,7 +103,6 @@ impl NoArgsAttributeParser for RustcSpecializationTraitParser { pub(crate) struct RustcUnsafeSpecializationMarkerParser; impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser { const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcUnsafeSpecializationMarker; } @@ -119,7 +112,6 @@ impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParse pub(crate) struct RustcCoinductiveParser; impl NoArgsAttributeParser for RustcCoinductiveParser { const PATH: &[Symbol] = &[sym::rustc_coinductive]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoinductive; } @@ -127,7 +119,6 @@ impl NoArgsAttributeParser for RustcCoinductiveParser { pub(crate) struct RustcAllowIncoherentImplParser; impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl; @@ -136,7 +127,6 @@ impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { pub(crate) struct FundamentalParser; impl NoArgsAttributeParser for FundamentalParser { const PATH: &[Symbol] = &[sym::fundamental]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8d92ec50e10c4..aa9284e54d369 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -7,7 +7,8 @@ use std::sync::LazyLock; use private::Sealed; use rustc_ast::{AttrStyle, MetaItemLit, NodeId}; -use rustc_errors::{Diag, Diagnostic, Level, MultiSpan}; +use rustc_data_structures::sync::{DynSend, DynSync}; +use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan}; use rustc_feature::{AttrSuggestionStyle, AttributeTemplate}; use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::AttributeLintKind; @@ -17,7 +18,6 @@ use rustc_session::Session; use rustc_session::lint::{Lint, LintId}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; -use crate::AttributeParser; // Glob imports to avoid big, bitrotty import lists use crate::attributes::allow_unstable::*; use crate::attributes::autodiff::*; @@ -66,6 +66,7 @@ use crate::session_diagnostics::{ ParsedDescription, }; use crate::target_checking::AllowedTargets; +use crate::{AttributeParser, EmitAttribute}; type GroupType = LazyLock>; pub(super) struct GroupTypeInner { @@ -461,11 +462,34 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing /// must be delayed until after HIR is built. This method will take care of the details of /// that. - pub(crate) fn emit_lint>( + pub(crate) fn emit_lint( &mut self, lint: &'static Lint, kind: AttributeLintKind, - span: M, + span: impl Into, + ) { + self.emit_lint_inner(lint, EmitAttribute::Static(kind), span); + } + + /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing + /// must be delayed until after HIR is built. This method will take care of the details of + /// that. + pub(crate) fn emit_dyn_lint< + F: for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static, + >( + &mut self, + lint: &'static Lint, + callback: F, + span: impl Into, + ) { + self.emit_lint_inner(lint, EmitAttribute::Dynamic(Box::new(callback)), span); + } + + fn emit_lint_inner( + &mut self, + lint: &'static Lint, + kind: EmitAttribute, + span: impl Into, ) { if !matches!( self.stage.should_emit(), @@ -477,12 +501,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { } pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) { - self.emit_lint( + self.emit_dyn_lint( rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - AttributeLintKind::UnusedDuplicate { - this: unused_span, - other: used_span, - warning: false, + move |dcx, level| { + rustc_errors::lints::UnusedDuplicate { + this: unused_span, + other: used_span, + warning: false, + } + .into_diag(dcx, level) }, unused_span, ) @@ -493,12 +520,15 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { used_span: Span, unused_span: Span, ) { - self.emit_lint( + self.emit_dyn_lint( rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - AttributeLintKind::UnusedDuplicate { - this: unused_span, - other: used_span, - warning: true, + move |dcx, level| { + rustc_errors::lints::UnusedDuplicate { + this: unused_span, + other: used_span, + warning: true, + } + .into_diag(dcx, level) }, unused_span, ) @@ -569,7 +599,7 @@ pub struct SharedContext<'p, 'sess, S: Stage> { /// The second argument of the closure is a [`NodeId`] if `S` is `Early` and a [`HirId`] if `S` /// is `Late` and is the ID of the syntactical component this attribute was applied to. - pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, AttributeLintKind), + pub(crate) emit_lint: &'p mut dyn FnMut(LintId, MultiSpan, EmitAttribute), } /// Context given to every attribute parser during finalization. diff --git a/compiler/rustc_attr_parsing/src/errors.rs b/compiler/rustc_attr_parsing/src/errors.rs index 4613325a245b7..7049ffae89ab1 100644 --- a/compiler/rustc_attr_parsing/src/errors.rs +++ b/compiler/rustc_attr_parsing/src/errors.rs @@ -57,3 +57,12 @@ pub(crate) struct MustBeNameOfAssociatedFunction { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag("unsafe attribute used without unsafe")] +pub(crate) struct UnsafeAttrOutsideUnsafeLint { + #[label("usage of unsafe attribute")] + pub span: Span, + #[subdiagnostic] + pub suggestion: Option, +} diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 85e714a1a917c..be89d836e3a19 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -3,7 +3,8 @@ use std::convert::identity; use rustc_ast as ast; use rustc_ast::token::DocFragmentKind; use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety}; -use rustc_errors::{DiagCtxtHandle, MultiSpan}; +use rustc_data_structures::sync::{DynSend, DynSync}; +use rustc_errors::{Diag, DiagCtxtHandle, Level, MultiSpan}; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::AttributeLintKind; @@ -19,6 +20,15 @@ use crate::parser::{AllowExprMetavar, ArgParser, PathParser, RefPathParser}; use crate::session_diagnostics::ParsedDescription; use crate::{Early, Late, OmitDoc, ShouldEmit}; +pub enum EmitAttribute { + Static(AttributeLintKind), + Dynamic( + Box< + dyn for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static, + >, + ), +} + /// Context created once, for example as part of the ast lowering /// context, through which all attributes can be lowered. pub struct AttributeParser<'sess, S: Stage = Late> { @@ -119,7 +129,14 @@ impl<'sess> AttributeParser<'sess, Early> { target, OmitDoc::Skip, std::convert::identity, - |lint_id, span, kind| sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind), + |lint_id, span, kind| match kind { + EmitAttribute::Static(kind) => { + sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind) + } + EmitAttribute::Dynamic(callback) => { + sess.psess.dyn_buffer_lint(lint_id.lint, span, target_node_id, callback) + } + }, ) } @@ -199,8 +216,13 @@ impl<'sess> AttributeParser<'sess, Early> { sess, stage: Early { emit_errors }, }; - let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: AttributeLintKind| { - sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind) + let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: EmitAttribute| match kind { + EmitAttribute::Static(kind) => { + sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind) + } + EmitAttribute::Dynamic(callback) => { + sess.psess.dyn_buffer_lint(lint_id.lint, span, target_node_id, callback) + } }; if let Some(safety) = attr_safety { parser.check_attribute_safety( @@ -209,7 +231,7 @@ impl<'sess> AttributeParser<'sess, Early> { safety, expected_safety, &mut emit_lint, - ) + ); } let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext { shared: SharedContext { @@ -266,7 +288,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { target: Target, omit_doc: OmitDoc, lower_span: impl Copy + Fn(Span) -> Span, - mut emit_lint: impl FnMut(LintId, MultiSpan, AttributeLintKind), + mut emit_lint: impl FnMut(LintId, MultiSpan, EmitAttribute), ) -> Vec { let mut attributes = Vec::new(); // We store the attributes we intend to discard at the end of this function in order to diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index 1b08ed3c49b78..73618dbfbf30c 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -113,5 +113,5 @@ pub use attributes::cfg::{ pub use attributes::cfg_select::*; pub use attributes::util::{is_builtin_attr, parse_version}; pub use context::{Early, Late, OmitDoc, ShouldEmit}; -pub use interface::AttributeParser; +pub use interface::{AttributeParser, EmitAttribute}; pub use session_diagnostics::ParsedDescription; diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index 26212ee5f4ca2..6566aaa557057 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -1,14 +1,13 @@ use rustc_ast::Safety; -use rustc_errors::MultiSpan; +use rustc_errors::{Diagnostic, MultiSpan}; use rustc_hir::AttrPath; -use rustc_hir::lints::AttributeLintKind; use rustc_session::lint::LintId; use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE; use rustc_span::Span; use crate::attributes::AttributeSafety; use crate::context::Stage; -use crate::{AttributeParser, ShouldEmit}; +use crate::{AttributeParser, EmitAttribute, ShouldEmit, errors}; impl<'sess, S: Stage> AttributeParser<'sess, S> { pub fn check_attribute_safety( @@ -17,7 +16,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attr_span: Span, attr_safety: Safety, expected_safety: AttributeSafety, - emit_lint: &mut impl FnMut(LintId, MultiSpan, AttributeLintKind), + emit_lint: &mut impl FnMut(LintId, MultiSpan, EmitAttribute), ) { if matches!(self.stage.should_emit(), ShouldEmit::Nothing) { return; @@ -80,11 +79,17 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { emit_lint( LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE), path_span.into(), - AttributeLintKind::UnsafeAttrOutsideUnsafe { - attribute_name_span: path_span, - sugg_spans: not_from_proc_macro - .then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())), - }, + EmitAttribute::Dynamic(Box::new(move |dcx, level| { + errors::UnsafeAttrOutsideUnsafeLint { + span: path_span, + suggestion: not_from_proc_macro + .then(|| (diag_span.shrink_to_lo(), diag_span.shrink_to_hi())) + .map(|(left, right)| { + crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion { left, right } + }), + } + .into_diag(dcx, level) + })), ) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 89e008f06ebc8..49a1817311627 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -678,7 +678,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span: Span) { match error { GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => { - self.add_borrow_suggestions(err, span); + self.add_borrow_suggestions(err, span, !binds_to.is_empty()); if binds_to.is_empty() { let place_ty = move_from.ty(self.body, self.infcx.tcx).ty; let place_desc = match self.describe_place(move_from.as_ref()) { @@ -787,29 +787,67 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } - fn add_borrow_suggestions(&self, err: &mut Diag<'_>, span: Span) { + fn add_borrow_suggestions( + &self, + err: &mut Diag<'_>, + span: Span, + is_destructuring_pattern_move: bool, + ) { match self.infcx.tcx.sess.source_map().span_to_snippet(span) { Ok(snippet) if snippet.starts_with('*') => { let sp = span.with_lo(span.lo() + BytePos(1)); let inner = self.find_expr(sp); let mut is_raw_ptr = false; + let mut is_ref = false; + let mut is_destructuring_assignment = false; + let mut is_nested_deref = false; if let Some(inner) = inner { + is_nested_deref = + matches!(inner.kind, hir::ExprKind::Unary(hir::UnOp::Deref, _)); let typck_result = self.infcx.tcx.typeck(self.mir_def_id()); if let Some(inner_type) = typck_result.node_type_opt(inner.hir_id) { if matches!(inner_type.kind(), ty::RawPtr(..)) { is_raw_ptr = true; + } else if matches!(inner_type.kind(), ty::Ref(..)) { + is_ref = true; } } + is_destructuring_assignment = + self.infcx.tcx.hir_parent_iter(inner.hir_id).any(|(_, node)| { + matches!( + node, + hir::Node::LetStmt(&hir::LetStmt { + source: hir::LocalSource::AssignDesugar, + .. + }) + ) + }); } // If the `inner` is a raw pointer, do not suggest removing the "*", see #126863 // FIXME: need to check whether the assigned object can be a raw pointer, see `tests/ui/borrowck/issue-20801.rs`. - if !is_raw_ptr { + if is_raw_ptr { + return; + } + + if !is_destructuring_pattern_move || is_ref { err.span_suggestion_verbose( span.with_hi(span.lo() + BytePos(1)), "consider removing the dereference here", String::new(), Applicability::MaybeIncorrect, ); + } else if !is_destructuring_assignment && !is_nested_deref { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "consider borrowing here", + '&', + Applicability::MaybeIncorrect, + ); + } else { + err.span_help( + span, + "destructuring assignment cannot borrow from this expression; consider using a `let` binding instead", + ); } } _ => { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 8fe71aaf86a86..ecde304aabfc2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -7,6 +7,7 @@ use std::panic; use std::path::PathBuf; use std::thread::panicking; +use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg}; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_macros::{Decodable, Encodable}; @@ -118,6 +119,28 @@ where } } +impl<'a> Diagnostic<'a, ()> + for Box< + dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSync + DynSend + 'static, + > +{ + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + self(dcx, level) + } +} + +pub struct DiagCallback<'a>( + pub &'a Box< + dyn for<'b> Fn(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSend + DynSync + 'static, + >, +); + +impl<'a, 'b> Diagnostic<'a, ()> for DiagCallback<'b> { + fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { + (self.0)(dcx, level) + } +} + /// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait. pub struct DiagDecorator)>(pub F); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index d17a4d6de42f5..f4874652f6ace 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -36,8 +36,8 @@ pub use anstyle::{ pub use codes::*; pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; pub use diagnostic::{ - BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic, - EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic, + BugAbort, Diag, DiagCallback, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, + Diagnostic, EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic, }; pub use diagnostic_impls::{ DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter, @@ -77,6 +77,7 @@ mod diagnostic_impls; pub mod emitter; pub mod formatting; pub mod json; +pub mod lints; mod lock; pub mod markdown; pub mod timings; diff --git a/compiler/rustc_errors/src/lints.rs b/compiler/rustc_errors/src/lints.rs new file mode 100644 index 0000000000000..9c93a09bf764c --- /dev/null +++ b/compiler/rustc_errors/src/lints.rs @@ -0,0 +1,15 @@ +use rustc_macros::Diagnostic; +use rustc_span::Span; + +#[derive(Diagnostic)] +#[diag("unused attribute")] +pub struct UnusedDuplicate { + #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] + pub this: Span, + #[note("attribute also specified here")] + pub other: Span, + #[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" + )] + pub warning: bool, +} diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index f1cd660a8f5b4..c9e54c9bf71d8 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -13,6 +13,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } +rustc_errors = { path = "../rustc_errors" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir_id = { path = "../rustc_hir_id" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_hir/src/lints.rs b/compiler/rustc_hir/src/lints.rs index 5c2ae98eb870f..d7bd9f874dd22 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -1,4 +1,6 @@ +use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_error_messages::MultiSpan; +use rustc_errors::{Diag, DiagCtxtHandle, Level}; use rustc_lint_defs::LintId; pub use rustc_lint_defs::{AttributeLintKind, FormatWarning}; @@ -14,13 +16,33 @@ pub type DelayedLints = Box<[DelayedLint]>; /// AST lowering to be emitted once HIR is built. #[derive(Debug)] pub enum DelayedLint { - AttributeParsing(AttributeLint), + AttributeParsing(AttributeLint), + Dynamic(DynAttribute), } #[derive(Debug)] -pub struct AttributeLint { +pub struct AttributeLint { pub lint_id: LintId, - pub id: Id, + pub id: HirId, pub span: MultiSpan, pub kind: AttributeLintKind, } + +pub struct DynAttribute { + pub lint_id: LintId, + pub id: HirId, + pub span: MultiSpan, + pub callback: Box< + dyn for<'a> Fn(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + DynSync + 'static, + >, +} + +impl std::fmt::Debug for DynAttribute { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DynAttribute") + .field("lint_id", &self.lint_id) + .field("id", &self.id) + .field("span", &self.span) + .finish() + } +} diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index eef7f9ba495ac..97d53a9d5aa5c 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -1,6 +1,6 @@ //! Method lookup: the secret sauce of Rust. See the [rustc dev guide] for more information. //! -//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/method-lookup.html +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir-typeck/method-lookup.html mod confirm; mod prelude_edition_lints; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 72d3afd5426f9..bd2ab2834dbc2 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -13,6 +13,7 @@ use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal, par_fns}; use rustc_data_structures::thousands; +use rustc_errors::DiagCallback; use rustc_errors::timings::TimingSection; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; @@ -1044,6 +1045,12 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) { }, ); } + DelayedLint::Dynamic(attribute_lint) => tcx.emit_node_span_lint( + attribute_lint.lint_id.lint, + attribute_lint.id, + attribute_lint.span.clone(), + DiagCallback(&attribute_lint.callback), + ), } } } diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 361ba4989dda3..7340ba0b2f391 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -35,9 +35,6 @@ pub struct DecorateAttrLint<'a, 'sess, 'tcx> { impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { match self.diagnostic { - &AttributeLintKind::UnusedDuplicate { this, other, warning } => { - lints::UnusedDuplicate { this, other, warning }.into_diag(dcx, level) - } AttributeLintKind::IllFormedAttributeInput { suggestions, docs, help } => { lints::IllFormedAttributeInput { num_suggestions: suggestions.len(), @@ -82,15 +79,6 @@ impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> { target, } .into_diag(dcx, level), - &AttributeLintKind::UnsafeAttrOutsideUnsafe { attribute_name_span, sugg_spans } => { - lints::UnsafeAttrOutsideUnsafeLint { - span: attribute_name_span, - suggestion: sugg_spans.map(|(left, right)| { - lints::UnsafeAttrOutsideUnsafeSuggestion { left, right } - }), - } - .into_diag(dcx, level) - } &AttributeLintKind::UnexpectedCfgName(name, value) => { check_cfg::unexpected_cfg_name(self.sess, self.tcx, name, value) .into_diag(dcx, level) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 099e918f70a43..20d88505f042d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3365,19 +3365,6 @@ pub(crate) struct InvalidAttrStyle { pub target: &'static str, } -#[derive(Diagnostic)] -#[diag("unused attribute")] -pub(crate) struct UnusedDuplicate { - #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] - pub this: Span, - #[note("attribute also specified here")] - pub other: Span, - #[warning( - "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" - )] - pub warning: bool, -} - #[derive(Diagnostic)] #[diag("malformed `doc` attribute input")] #[warning( @@ -3399,24 +3386,6 @@ pub(crate) struct ExpectedNoArgs; )] pub(crate) struct ExpectedNameValue; -#[derive(Diagnostic)] -#[diag("unsafe attribute used without unsafe")] -pub(crate) struct UnsafeAttrOutsideUnsafeLint { - #[label("usage of unsafe attribute")] - pub span: Span, - #[subdiagnostic] - pub suggestion: Option, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion("wrap the attribute in `unsafe(...)`", applicability = "machine-applicable")] -pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { - #[suggestion_part(code = "unsafe(")] - pub left: Span, - #[suggestion_part(code = ")")] - pub right: Span, -} - #[derive(Diagnostic)] #[diag("doc alias is duplicated")] pub(crate) struct DocAliasDuplicated { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index cb9fd38c5da57..ea5006c7f03f3 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -654,11 +654,6 @@ pub enum DeprecatedSinceKind { #[derive(Debug)] pub enum AttributeLintKind { - UnusedDuplicate { - this: Span, - other: Span, - warning: bool, - }, IllFormedAttributeInput { suggestions: Vec, docs: Option<&'static str>, @@ -682,10 +677,6 @@ pub enum AttributeLintKind { target: &'static str, target_span: Span, }, - UnsafeAttrOutsideUnsafe { - attribute_name_span: Span, - sugg_spans: Option<(Span, Span)>, - }, UnexpectedCfgName((Symbol, Span), Option<(Symbol, Span)>), UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>), DuplicateDocAlias { diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 28d432736ed66..ad256c2e97be2 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1264,7 +1264,7 @@ def parse_args(args): # Pass allow_abbrev=False to remove support for inexact matches (e.g., # `--json` turning on `--json-output`). The argument list here is partial, - # most flags are matched in the Rust bootstrap code. This prevents the the + # most flags are matched in the Rust bootstrap code. This prevents the # default ambiguity checks in argparse from functioning correctly. parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False) parser.add_argument("-h", "--help", action="store_true") diff --git a/tests/ui/attributes/malformed-no-std.rs b/tests/ui/attributes/malformed-no-std.rs index 2e618a13d41fd..7383bcb2de348 100644 --- a/tests/ui/attributes/malformed-no-std.rs +++ b/tests/ui/attributes/malformed-no-std.rs @@ -12,10 +12,10 @@ //~^ ERROR malformed `no_core` attribute input #![no_core("bar")] //~^ ERROR malformed `no_core` attribute input -//~| WARN unused attribute +//~| ERROR multiple `no_core` attributes #![no_core(foo = "bar")] //~^ ERROR malformed `no_core` attribute input -//~| WARN unused attribute +//~| ERROR multiple `no_core` attributes #[deny(unused_attributes)] #[no_std] diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr index d46eaf7368e84..07963e6256648 100644 --- a/tests/ui/attributes/malformed-no-std.stderr +++ b/tests/ui/attributes/malformed-no-std.stderr @@ -68,6 +68,18 @@ LL - #![no_core("bar")] LL + #![no_core] | +error: multiple `no_core` attributes + --> $DIR/malformed-no-std.rs:13:1 + | +LL | #![no_core("bar")] + | ^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/malformed-no-std.rs:11:1 + | +LL | #![no_core = "foo"] + | ^^^^^^^^^^^^^^^^^^^ + error[E0565]: malformed `no_core` attribute input --> $DIR/malformed-no-std.rs:16:1 | @@ -82,6 +94,18 @@ LL - #![no_core(foo = "bar")] LL + #![no_core] | +error: multiple `no_core` attributes + --> $DIR/malformed-no-std.rs:16:1 + | +LL | #![no_core(foo = "bar")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/malformed-no-std.rs:11:1 + | +LL | #![no_core = "foo"] + | ^^^^^^^^^^^^^^^^^^^ + error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` --> $DIR/malformed-no-std.rs:21:1 | @@ -136,30 +160,6 @@ note: attribute also specified here LL | #![no_std = "foo"] | ^^^^^^^^^^^^^^^^^^ -warning: unused attribute - --> $DIR/malformed-no-std.rs:13:1 - | -LL | #![no_core("bar")] - | ^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/malformed-no-std.rs:11:1 - | -LL | #![no_core = "foo"] - | ^^^^^^^^^^^^^^^^^^^ - -warning: unused attribute - --> $DIR/malformed-no-std.rs:16:1 - | -LL | #![no_core(foo = "bar")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/malformed-no-std.rs:11:1 - | -LL | #![no_core = "foo"] - | ^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 8 previous errors; 4 warnings emitted +error: aborting due to 10 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/suggestions/borrow-from-overloaded-deref-assign-issue-154826.rs b/tests/ui/suggestions/borrow-from-overloaded-deref-assign-issue-154826.rs new file mode 100644 index 0000000000000..77bd286697ebf --- /dev/null +++ b/tests/ui/suggestions/borrow-from-overloaded-deref-assign-issue-154826.rs @@ -0,0 +1,12 @@ +// Regression test for #154826. + +use std::rc::Rc; + +struct NonCopy; + +fn main() { + let b: NonCopy; + (b,) = *Rc::new((NonCopy,)); + //~^ ERROR cannot move out of an `Rc` + //~| HELP destructuring assignment cannot borrow from this expression; consider using a `let` binding instead +} diff --git a/tests/ui/suggestions/borrow-from-overloaded-deref-assign-issue-154826.stderr b/tests/ui/suggestions/borrow-from-overloaded-deref-assign-issue-154826.stderr new file mode 100644 index 0000000000000..8022e7384f3e1 --- /dev/null +++ b/tests/ui/suggestions/borrow-from-overloaded-deref-assign-issue-154826.stderr @@ -0,0 +1,25 @@ +error[E0507]: cannot move out of an `Rc` + --> $DIR/borrow-from-overloaded-deref-assign-issue-154826.rs:9:12 + | +LL | (b,) = *Rc::new((NonCopy,)); + | - ^^^^^^^^^^^^^^^^^^^^ + | | + | data moved here because the place has type `NonCopy`, which does not implement the `Copy` trait + | +help: destructuring assignment cannot borrow from this expression; consider using a `let` binding instead + --> $DIR/borrow-from-overloaded-deref-assign-issue-154826.rs:9:12 + | +LL | (b,) = *Rc::new((NonCopy,)); + | ^^^^^^^^^^^^^^^^^^^^ +note: if `NonCopy` implemented `Clone`, you could clone the value + --> $DIR/borrow-from-overloaded-deref-assign-issue-154826.rs:5:1 + | +LL | struct NonCopy; + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | (b,) = *Rc::new((NonCopy,)); + | - you could clone this value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/suggestions/borrow-from-overloaded-deref-issue-154826.rs b/tests/ui/suggestions/borrow-from-overloaded-deref-issue-154826.rs new file mode 100644 index 0000000000000..2d5df0ca214c3 --- /dev/null +++ b/tests/ui/suggestions/borrow-from-overloaded-deref-issue-154826.rs @@ -0,0 +1,12 @@ +// Regression test for #154826. + +use std::sync::LazyLock; + +static V: LazyLock<(Vec,)> = LazyLock::new(|| (vec![],)); + +fn main() { + let (v,) = *V; + //~^ ERROR cannot move out of dereference of `LazyLock<(Vec,)>` + //~| HELP consider borrowing here + let _: &Vec<_> = &v; +} diff --git a/tests/ui/suggestions/borrow-from-overloaded-deref-issue-154826.stderr b/tests/ui/suggestions/borrow-from-overloaded-deref-issue-154826.stderr new file mode 100644 index 0000000000000..2ae3cf143fc57 --- /dev/null +++ b/tests/ui/suggestions/borrow-from-overloaded-deref-issue-154826.stderr @@ -0,0 +1,16 @@ +error[E0507]: cannot move out of dereference of `LazyLock<(Vec,)>` + --> $DIR/borrow-from-overloaded-deref-issue-154826.rs:8:16 + | +LL | let (v,) = *V; + | - ^^ + | | + | data moved here because `v` has type `Vec`, which does not implement the `Copy` trait + | +help: consider borrowing here + | +LL | let (v,) = &*V; + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/suggestions/issue-102892.stderr b/tests/ui/suggestions/issue-102892.stderr index 38f19b3321887..ed7a88c6422e2 100644 --- a/tests/ui/suggestions/issue-102892.stderr +++ b/tests/ui/suggestions/issue-102892.stderr @@ -61,12 +61,12 @@ LL | let (a, b) = **arc; // suggests putting `&**arc` here; with that, fixed | | ...and here | data moved here | - = note: move occurs because these variables have types that don't implement the `Copy` trait -help: consider removing the dereference here - | -LL - let (a, b) = **arc; // suggests putting `&**arc` here; with that, fixed! -LL + let (a, b) = *arc; // suggests putting `&**arc` here; with that, fixed! +help: destructuring assignment cannot borrow from this expression; consider using a `let` binding instead + --> $DIR/issue-102892.rs:11:18 | +LL | let (a, b) = **arc; // suggests putting `&**arc` here; with that, fixed! + | ^^^^^ + = note: move occurs because these variables have types that don't implement the `Copy` trait error: aborting due to 4 previous errors