diff --git a/Cargo.lock b/Cargo.lock index 686b98cf61281..794e24bd12221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3995,6 +3995,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 0561490344d21..a0052a1f60386 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -40,7 +40,7 @@ use std::sync::Arc; use rustc_ast::node_id::NodeMap; 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; @@ -51,7 +51,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::{DefPathData, DisambiguatorState}; -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, @@ -1166,13 +1166,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/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/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 0be1b9b45b220..ac0bee2b9e29f 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}; +use rustc_data_structures::sync::{DynSend, DynSync}; +use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level}; 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::{AttrId, 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 { @@ -460,6 +461,24 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> { /// must be delayed until after HIR is built. This method will take care of the details of /// that. pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) { + 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: Span, + ) { + self.emit_lint_inner(lint, EmitAttribute::Dynamic(Box::new(callback)), span); + } + + fn emit_lint_inner(&mut self, lint: &'static Lint, kind: EmitAttribute, span: Span) { if !matches!( self.stage.should_emit(), ShouldEmit::ErrorsAndLints { .. } | ShouldEmit::EarlyFatal { also_emit_lints: true } @@ -470,12 +489,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, ) @@ -486,12 +508,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, ) @@ -532,7 +557,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, Span, AttributeLintKind), + pub(crate) emit_lint: &'p mut dyn FnMut(LintId, Span, 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 d4236416dd6aa..27eb74f2d7537 100644 --- a/compiler/rustc_attr_parsing/src/errors.rs +++ b/compiler/rustc_attr_parsing/src/errors.rs @@ -50,3 +50,12 @@ pub(crate) struct UnreachableCfgSelectPredicateWildcard { #[label("always matches")] pub wildcard_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 902f2419c46d5..98419b6ad8946 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -4,7 +4,8 @@ use rustc_ast as ast; use rustc_ast::token::DocFragmentKind; use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety}; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::DiagCtxtHandle; +use rustc_data_structures::sync::{DynSend, DynSync}; +use rustc_errors::{Diag, DiagCtxtHandle, Level}; 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> { @@ -124,7 +134,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) + } + }, ) } @@ -222,11 +239,16 @@ impl<'sess> AttributeParser<'sess, Early> { ) -> T { let mut parser = Self { features, tools: None, parse_only: None, sess, stage: Early { emit_errors } }; - let mut emit_lint = |lint_id: LintId, span: Span, kind: AttributeLintKind| { - sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind) + let mut emit_lint = |lint_id: LintId, span: Span, 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(&attr_path, inner_span, safety, &mut emit_lint) + parser.check_attribute_safety(&attr_path, inner_span, safety, &mut emit_lint); } let attr_id = sess.psess.attr_id_generator.mk_attr_id(); let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext { @@ -285,7 +307,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, Span, AttributeLintKind), + mut emit_lint: impl FnMut(LintId, Span, 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 93eb5a0c3ab73..019d2d8135b4d 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -112,5 +112,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 4cc703c5d0cc4..fa1212bdbbd90 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -1,13 +1,13 @@ use rustc_ast::Safety; +use rustc_errors::Diagnostic; use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP}; 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::context::Stage; -use crate::{AttributeParser, ShouldEmit}; +use crate::{AttributeParser, EmitAttribute, ShouldEmit, errors}; impl<'sess, S: Stage> AttributeParser<'sess, S> { pub fn check_attribute_safety( @@ -15,7 +15,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { attr_path: &AttrPath, attr_span: Span, attr_safety: Safety, - emit_lint: &mut impl FnMut(LintId, Span, AttributeLintKind), + emit_lint: &mut impl FnMut(LintId, Span, EmitAttribute), ) { if matches!(self.stage.should_emit(), ShouldEmit::Nothing) { return; @@ -84,11 +84,17 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { emit_lint( LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE), path_span, - 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_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 7acf95d77d40e..986a684acd09b 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 13e73acf07375..ee0a30f646e54 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 1589a6de220e7..c8cad52e0d784 100644 --- a/compiler/rustc_hir/src/lints.rs +++ b/compiler/rustc_hir/src/lints.rs @@ -1,4 +1,6 @@ use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::sync::{DynSend, DynSync}; +use rustc_errors::{Diag, DiagCtxtHandle, Level}; use rustc_lint_defs::LintId; pub use rustc_lint_defs::{AttributeLintKind, FormatWarning}; use rustc_macros::HashStable_Generic; @@ -21,13 +23,35 @@ pub struct DelayedLints { /// AST lowering to be emitted once HIR is built. #[derive(Debug, HashStable_Generic)] pub enum DelayedLint { - AttributeParsing(AttributeLint), + AttributeParsing(AttributeLint), + Dynamic(DynAttribute), } #[derive(Debug, HashStable_Generic)] -pub struct AttributeLint { +pub struct AttributeLint { pub lint_id: LintId, - pub id: Id, + pub id: HirId, pub span: Span, pub kind: AttributeLintKind, } + +#[derive(HashStable_Generic)] +pub struct DynAttribute { + pub lint_id: LintId, + pub id: HirId, + pub span: Span, + #[stable_hasher(ignore)] + 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_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 43efce545fc28..7fc20783efd88 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, + DiagCallback(&attribute_lint.callback), + ), } } } diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 0f27e04babd46..13c3975a05f6b 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 f52b90382d956..fc256e02a32a3 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3353,19 +3353,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( @@ -3387,24 +3374,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 36070dac276fb..e117e942ec3c8 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, HashStable_Generic)] 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 {