Make rustc_attr_parsing::SharedContext::emit_lint take a MultiSpan instead of a Span

This commit is contained in:
Guillaume Gomez
2026-04-10 14:58:23 +02:00
parent 25a54d4ba8
commit 2c827319f6
6 changed files with 21 additions and 15 deletions
+9 -4
View File
@@ -7,7 +7,7 @@
use private::Sealed; use private::Sealed;
use rustc_ast::{AttrStyle, MetaItemLit, NodeId}; use rustc_ast::{AttrStyle, MetaItemLit, NodeId};
use rustc_errors::{Diag, Diagnostic, Level}; use rustc_errors::{Diag, Diagnostic, Level, MultiSpan};
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate}; use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
use rustc_hir::attrs::AttributeKind; use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind; use rustc_hir::lints::AttributeLintKind;
@@ -455,14 +455,19 @@ 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 /// 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 /// must be delayed until after HIR is built. This method will take care of the details of
/// that. /// that.
pub(crate) fn emit_lint(&mut self, lint: &'static Lint, kind: AttributeLintKind, span: Span) { pub(crate) fn emit_lint<M: Into<MultiSpan>>(
&mut self,
lint: &'static Lint,
kind: AttributeLintKind,
span: M,
) {
if !matches!( if !matches!(
self.stage.should_emit(), self.stage.should_emit(),
ShouldEmit::ErrorsAndLints { .. } | ShouldEmit::EarlyFatal { also_emit_lints: true } ShouldEmit::ErrorsAndLints { .. } | ShouldEmit::EarlyFatal { also_emit_lints: true }
) { ) {
return; return;
} }
(self.emit_lint)(LintId::of(lint), span, kind); (self.emit_lint)(LintId::of(lint), span.into(), kind);
} }
pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) { pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
@@ -528,7 +533,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` /// 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. /// 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, MultiSpan, AttributeLintKind),
} }
/// Context given to every attribute parser during finalization. /// Context given to every attribute parser during finalization.
+3 -3
View File
@@ -3,7 +3,7 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::token::DocFragmentKind; use rustc_ast::token::DocFragmentKind;
use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety}; use rustc_ast::{AttrItemKind, AttrStyle, NodeId, Safety};
use rustc_errors::DiagCtxtHandle; use rustc_errors::{DiagCtxtHandle, MultiSpan};
use rustc_feature::{AttributeTemplate, Features}; use rustc_feature::{AttributeTemplate, Features};
use rustc_hir::attrs::AttributeKind; use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind; use rustc_hir::lints::AttributeLintKind;
@@ -195,7 +195,7 @@ pub fn parse_single_args<T, I>(
sess, sess,
stage: Early { emit_errors }, stage: Early { emit_errors },
}; };
let mut emit_lint = |lint_id: LintId, span: Span, kind: AttributeLintKind| { let mut emit_lint = |lint_id: LintId, span: MultiSpan, kind: AttributeLintKind| {
sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind) sess.psess.buffer_lint(lint_id.lint, span, target_node_id, kind)
}; };
if let Some(safety) = attr_safety { if let Some(safety) = attr_safety {
@@ -256,7 +256,7 @@ pub fn parse_attribute_list(
target: Target, target: Target,
omit_doc: OmitDoc, omit_doc: OmitDoc,
lower_span: impl Copy + Fn(Span) -> Span, lower_span: impl Copy + Fn(Span) -> Span,
mut emit_lint: impl FnMut(LintId, Span, AttributeLintKind), mut emit_lint: impl FnMut(LintId, MultiSpan, AttributeLintKind),
) -> Vec<Attribute> { ) -> Vec<Attribute> {
let mut attributes = Vec::new(); let mut attributes = Vec::new();
// We store the attributes we intend to discard at the end of this function in order to // We store the attributes we intend to discard at the end of this function in order to
+3 -2
View File
@@ -1,4 +1,5 @@
use rustc_ast::Safety; use rustc_ast::Safety;
use rustc_errors::MultiSpan;
use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{AttributeSafety, BUILTIN_ATTRIBUTE_MAP};
use rustc_hir::AttrPath; use rustc_hir::AttrPath;
use rustc_hir::lints::AttributeLintKind; use rustc_hir::lints::AttributeLintKind;
@@ -15,7 +16,7 @@ pub fn check_attribute_safety(
attr_path: &AttrPath, attr_path: &AttrPath,
attr_span: Span, attr_span: Span,
attr_safety: Safety, attr_safety: Safety,
emit_lint: &mut impl FnMut(LintId, Span, AttributeLintKind), emit_lint: &mut impl FnMut(LintId, MultiSpan, AttributeLintKind),
) { ) {
if matches!(self.stage.should_emit(), ShouldEmit::Nothing) { if matches!(self.stage.should_emit(), ShouldEmit::Nothing) {
return; return;
@@ -83,7 +84,7 @@ pub fn check_attribute_safety(
} else { } else {
emit_lint( emit_lint(
LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE), LintId::of(UNSAFE_ATTR_OUTSIDE_UNSAFE),
path_span, path_span.into(),
AttributeLintKind::UnsafeAttrOutsideUnsafe { AttributeLintKind::UnsafeAttrOutsideUnsafe {
attribute_name_span: path_span, attribute_name_span: path_span,
sugg_spans: not_from_proc_macro sugg_spans: not_from_proc_macro
+3 -3
View File
@@ -7,7 +7,7 @@
pub use fluent_bundle::types::FluentType; pub use fluent_bundle::types::FluentType;
pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue}; pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
use rustc_macros::{Decodable, Encodable}; use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::Span; use rustc_span::Span;
pub use unic_langid::{LanguageIdentifier, langid}; pub use unic_langid::{LanguageIdentifier, langid};
@@ -28,7 +28,7 @@ pub fn register_functions<R, M>(bundle: &mut fluent_bundle::bundle::FluentBundle
/// diagnostic messages. /// diagnostic messages.
/// ///
/// Intended to be removed once diagnostics are entirely translatable. /// Intended to be removed once diagnostics are entirely translatable.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable_Generic)]
#[rustc_diagnostic_item = "DiagMessage"] #[rustc_diagnostic_item = "DiagMessage"]
pub enum DiagMessage { pub enum DiagMessage {
/// Non-translatable diagnostic message or a message that has been translated eagerly. /// Non-translatable diagnostic message or a message that has been translated eagerly.
@@ -89,7 +89,7 @@ pub struct SpanLabel {
/// the error, and would be rendered with `^^^`. /// the error, and would be rendered with `^^^`.
/// - They can have a *label*. In this case, the label is written next /// - They can have a *label*. In this case, the label is written next
/// to the mark in the snippet when we render. /// to the mark in the snippet when we render.
#[derive(Clone, Debug, Hash, PartialEq, Eq, Encodable, Decodable)] #[derive(Clone, Debug, Hash, PartialEq, Eq, Encodable, Decodable, HashStable_Generic)]
pub struct MultiSpan { pub struct MultiSpan {
primary_spans: Vec<Span>, primary_spans: Vec<Span>,
span_labels: Vec<(Span, DiagMessage)>, span_labels: Vec<(Span, DiagMessage)>,
+2 -2
View File
@@ -1,8 +1,8 @@
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_error_messages::MultiSpan;
use rustc_lint_defs::LintId; use rustc_lint_defs::LintId;
pub use rustc_lint_defs::{AttributeLintKind, FormatWarning}; pub use rustc_lint_defs::{AttributeLintKind, FormatWarning};
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
use rustc_span::Span;
use crate::HirId; use crate::HirId;
@@ -28,6 +28,6 @@ pub enum DelayedLint {
pub struct AttributeLint<Id> { pub struct AttributeLint<Id> {
pub lint_id: LintId, pub lint_id: LintId,
pub id: Id, pub id: Id,
pub span: Span, pub span: MultiSpan,
pub kind: AttributeLintKind, pub kind: AttributeLintKind,
} }
+1 -1
View File
@@ -1037,7 +1037,7 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) {
tcx.emit_node_span_lint( tcx.emit_node_span_lint(
attribute_lint.lint_id.lint, attribute_lint.lint_id.lint,
attribute_lint.id, attribute_lint.id,
attribute_lint.span, attribute_lint.span.clone(),
DecorateAttrLint { DecorateAttrLint {
sess: tcx.sess, sess: tcx.sess,
tcx: Some(tcx), tcx: Some(tcx),