mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Rollup merge of #154432 - GuillaumeGomez:try-rm-AttributeLint, r=JonathanBrouwer
Set up API to make it possible to pass closures instead of `AttributeLint` Part of https://github.com/rust-lang/rust/issues/153099. This PR sets up the base implementations needed to remove `AttributeLintKind` entirely and migrate two variants as examples. r? @JonathanBrouwer
This commit is contained in:
@@ -4004,6 +4004,7 @@ dependencies = [
|
||||
"rustc_ast_pretty",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_messages",
|
||||
"rustc_errors",
|
||||
"rustc_hashes",
|
||||
"rustc_hir_id",
|
||||
"rustc_index",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
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_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 @@ fn lower_attrs_vec(
|
||||
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,
|
||||
}));
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 @@ fn parse_single_test_doc_attr_item<S: Stage>(
|
||||
|
||||
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,
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
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::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 @@
|
||||
ParsedDescription,
|
||||
};
|
||||
use crate::target_checking::AllowedTargets;
|
||||
use crate::{AttributeParser, EmitAttribute};
|
||||
type GroupType<S> = LazyLock<GroupTypeInner<S>>;
|
||||
|
||||
pub(super) struct GroupTypeInner<S: Stage> {
|
||||
@@ -461,11 +462,34 @@ pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuarant
|
||||
/// 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<M: Into<MultiSpan>>(
|
||||
pub(crate) fn emit_lint(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
kind: AttributeLintKind,
|
||||
span: M,
|
||||
span: impl Into<MultiSpan>,
|
||||
) {
|
||||
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<MultiSpan>,
|
||||
) {
|
||||
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<MultiSpan>,
|
||||
) {
|
||||
if !matches!(
|
||||
self.stage.should_emit(),
|
||||
@@ -477,12 +501,15 @@ pub(crate) fn emit_lint<M: Into<MultiSpan>>(
|
||||
}
|
||||
|
||||
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 @@ pub(crate) fn warn_unused_duplicate_future_error(
|
||||
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.
|
||||
|
||||
@@ -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<crate::session_diagnostics::UnsafeAttrOutsideUnsafeSuggestion>,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
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::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 @@ pub fn parse_limited_all(
|
||||
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 @@ pub fn parse_single_args<T, I>(
|
||||
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 @@ pub fn parse_single_args<T, I>(
|
||||
safety,
|
||||
expected_safety,
|
||||
&mut emit_lint,
|
||||
)
|
||||
);
|
||||
}
|
||||
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
|
||||
shared: SharedContext {
|
||||
@@ -266,7 +288,7 @@ pub fn parse_attribute_list(
|
||||
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<Attribute> {
|
||||
let mut attributes = Vec::new();
|
||||
// We store the attributes we intend to discard at the end of this function in order to
|
||||
|
||||
@@ -113,5 +113,5 @@
|
||||
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;
|
||||
|
||||
@@ -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 @@ pub fn check_attribute_safety(
|
||||
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 @@ pub fn check_attribute_safety(
|
||||
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)
|
||||
})),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
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 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
|
||||
}
|
||||
}
|
||||
|
||||
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<F: FnOnce(&mut Diag<'_, ()>)>(pub F);
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
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 @@
|
||||
pub mod emitter;
|
||||
pub mod formatting;
|
||||
pub mod json;
|
||||
pub mod lints;
|
||||
mod lock;
|
||||
pub mod markdown;
|
||||
pub mod timings;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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" }
|
||||
|
||||
@@ -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 @@
|
||||
/// AST lowering to be emitted once HIR is built.
|
||||
#[derive(Debug)]
|
||||
pub enum DelayedLint {
|
||||
AttributeParsing(AttributeLint<HirId>),
|
||||
AttributeParsing(AttributeLint),
|
||||
Dynamic(DynAttribute),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AttributeLint<Id> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
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),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
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)
|
||||
|
||||
@@ -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 UnusedDuplicate {
|
||||
)]
|
||||
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<UnsafeAttrOutsideUnsafeSuggestion>,
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
||||
@@ -654,11 +654,6 @@ pub enum DeprecatedSinceKind {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AttributeLintKind {
|
||||
UnusedDuplicate {
|
||||
this: Span,
|
||||
other: Span,
|
||||
warning: bool,
|
||||
},
|
||||
IllFormedAttributeInput {
|
||||
suggestions: Vec<String>,
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user