From 1f6b7314a2cd3f4f20158b6df6358899cd5d5947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 17 May 2024 12:41:39 +0200 Subject: [PATCH 1/4] Make lint diagnostics responsible for storing their span --- compiler/rustc_errors/src/diagnostic.rs | 4 +- compiler/rustc_lint/src/context.rs | 17 +----- .../src/diagnostics/diagnostic.rs | 52 +++++++++++++++++-- .../src/diagnostics/diagnostic_builder.rs | 19 +++---- compiler/rustc_macros/src/diagnostics/mod.rs | 3 +- compiler/rustc_middle/src/ty/context.rs | 23 ++------ 6 files changed, 64 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 4352de3ad25fe..8035651048a8b 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -195,8 +195,10 @@ pub trait SubdiagMessageOp = /// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic]. #[rustc_diagnostic_item = "LintDiagnostic"] pub trait LintDiagnostic<'a, G: EmissionGuarantee> { - /// Decorate and emit a lint. + /// Decorate a lint. fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>); + + fn span(&self) -> Option; } #[derive(Clone, Debug, Encodable, Decodable)] diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 39f90a8e9ed14..23f95853f265e 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -574,19 +574,6 @@ pub trait LintContext { decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), ); - /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`, - /// typically generated by `#[derive(LintDiagnostic)]`). - fn emit_span_lint>( - &self, - lint: &'static Lint, - span: S, - decorator: impl for<'a> LintDiagnostic<'a, ()>, - ) { - self.opt_span_lint(lint, Some(span), |lint| { - decorator.decorate_lint(lint); - }); - } - /// Emit a lint at the appropriate level, with an associated span. /// /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature @@ -603,8 +590,8 @@ pub trait LintContext { /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> LintDiagnostic<'a, ()>) { - self.opt_span_lint(lint, None as Option, |lint| { - decorator.decorate_lint(lint); + self.opt_span_lint(lint, decorator.span(), |diag| { + decorator.decorate_lint(diag); }); } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 185d070496694..fb917b2f9e450 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -3,10 +3,11 @@ use std::cell::RefCell; use proc_macro2::TokenStream; -use quote::quote; +use quote::{quote, quote_spanned}; use syn::spanned::Spanned; use synstructure::Structure; +use super::utils::FieldInnerTy; use crate::diagnostics::diagnostic_builder::DiagnosticDeriveKind; use crate::diagnostics::error::{DiagnosticDeriveError, span_err}; use crate::diagnostics::utils::SetOnce; @@ -17,15 +18,16 @@ pub(crate) struct DiagnosticDerive<'a> { } impl<'a> DiagnosticDerive<'a> { + const KIND: DiagnosticDeriveKind = DiagnosticDeriveKind::Diagnostic; + pub(crate) fn new(structure: Structure<'a>) -> Self { Self { structure } } pub(crate) fn into_tokens(self) -> TokenStream { let DiagnosticDerive { mut structure } = self; - let kind = DiagnosticDeriveKind::Diagnostic; let slugs = RefCell::new(Vec::new()); - let implementation = kind.each_variant(&mut structure, |mut builder, variant| { + let implementation = Self::KIND.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); @@ -101,15 +103,16 @@ pub(crate) struct LintDiagnosticDerive<'a> { } impl<'a> LintDiagnosticDerive<'a> { + const KIND: DiagnosticDeriveKind = DiagnosticDeriveKind::LintDiagnostic; + pub(crate) fn new(structure: Structure<'a>) -> Self { Self { structure } } pub(crate) fn into_tokens(self) -> TokenStream { let LintDiagnosticDerive { mut structure } = self; - let kind = DiagnosticDeriveKind::LintDiagnostic; let slugs = RefCell::new(Vec::new()); - let implementation = kind.each_variant(&mut structure, |mut builder, variant| { + let implementation = Self::KIND.each_variant(&mut structure, |mut builder, variant| { let preamble = builder.preamble(variant); let body = builder.body(variant); @@ -151,6 +154,41 @@ impl<'a> LintDiagnosticDerive<'a> { } }); + let span = Self::KIND.each_variant(&mut structure, |_, variant| { + variant + .bindings() + .iter() + .find_map(|binding_info| { + let field = binding_info.ast(); + + field.attrs.iter().find_map(|attr| { + if attr.path().segments.last().unwrap().ident != "primary_span" + || !matches!(attr.meta, syn::Meta::Path(_)) + { + return None; + } + + let ident = &binding_info.binding; + + // Generate `.clone()` unconditionally as the inner type may + // contain a `MultiSpan` which is not `Copy`. + Some(match FieldInnerTy::from_type(&field.ty) { + FieldInnerTy::Plain(_) | FieldInnerTy::Vec(_) => { + quote_spanned! {field.ty.span()=> + std::option::Option::Some(#ident.clone().into()) + } + } + FieldInnerTy::Option(_) => { + quote_spanned! {field.ty.span()=> + #ident.clone().into() + } + } + }) + }) + }) + .unwrap_or_else(|| quote! { std::option::Option::None }) + }); + // FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here? #[allow(keyword_idents_2024)] let mut imp = structure.gen_impl(quote! { @@ -162,6 +200,10 @@ impl<'a> LintDiagnosticDerive<'a> { ) { #implementation; } + + fn span(&self) -> std::option::Option { + #span + } } }); for test in slugs.borrow().iter().map(|s| generate_test(s, &structure)) { diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 72f1e5992472d..b8d6f0a5b0816 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -328,20 +328,13 @@ impl DiagnosticDeriveVariantBuilder { // `arg` call will not be generated. (Meta::Path(_), "skip_arg") => return Ok(quote! {}), (Meta::Path(_), "primary_span") => { - match self.kind { - DiagnosticDeriveKind::Diagnostic => { - report_error_if_not_applied_to_span(attr, &info)?; + report_error_if_not_applied_to_span(attr, &info)?; - return Ok(quote! { - diag.span(#binding); - }); - } - DiagnosticDeriveKind::LintDiagnostic => { - throw_invalid_attr!(attr, |diag| { - diag.help("the `primary_span` field attribute is not valid for lint diagnostics") - }) - } - } + return Ok(match self.kind { + DiagnosticDeriveKind::Diagnostic => quote! { diag.span(#binding); }, + // Handled separately in `LintDiagnosticDerive::into_tokens`. + DiagnosticDeriveKind::LintDiagnostic => quote! {}, + }); } (Meta::Path(_), "subdiagnostic") => { return Ok(quote! { diag.subdiagnostic(#binding); }); diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 0f7b89215097e..cf1400fa07a3f 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -70,6 +70,7 @@ pub(super) fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream { /// method: Symbol, /// success_ordering: Symbol, /// fail_ordering: Symbol, +/// #[primary_span] /// #[label(fail_label)] /// fail_order_arg_span: Span, /// #[label(success_label)] @@ -91,7 +92,7 @@ pub(super) fn diagnostic_derive(mut s: Structure<'_>) -> TokenStream { /// Then, later, to emit the error: /// /// ```ignore (rust) -/// cx.emit_span_lint(INVALID_ATOMIC_ORDERING, fail_order_arg_span, AtomicOrderingInvalidLint { +/// tcx.emit_lint(INVALID_ATOMIC_ORDERING, AtomicOrderingInvalidLint { /// method, /// success_ordering, /// fail_ordering, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b682524ae39f4..2d6f6c24b6e96 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2909,22 +2909,6 @@ impl<'tcx> TyCtxt<'tcx> { T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs)) } - /// Emit a lint at `span` from a lint struct (some type that implements `LintDiagnostic`, - /// typically generated by `#[derive(LintDiagnostic)]`). - #[track_caller] - pub fn emit_node_span_lint( - self, - lint: &'static Lint, - hir_id: HirId, - span: impl Into, - decorator: impl for<'a> LintDiagnostic<'a, ()>, - ) { - let (level, src) = self.lint_level_at_node(lint, hir_id); - lint_level(self.sess, lint, level, src, Some(span.into()), |lint| { - decorator.decorate_lint(lint); - }) - } - /// Emit a lint at the appropriate level for a hir node, with an associated span. /// /// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature @@ -2989,9 +2973,10 @@ impl<'tcx> TyCtxt<'tcx> { id: HirId, decorator: impl for<'a> LintDiagnostic<'a, ()>, ) { - self.node_lint(lint, id, |lint| { - decorator.decorate_lint(lint); - }) + let (level, src) = self.lint_level_at_node(lint, id); + lint_level(self.sess, lint, level, src, decorator.span(), |diag| { + decorator.decorate_lint(diag) + }); } /// Emit a lint at the appropriate level for a hir node. From 48dc9c9426688b516663e9480606db55f118874a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 17 May 2024 12:43:05 +0200 Subject: [PATCH 2/4] Update all lint diagnostics to store their span --- compiler/rustc_borrowck/src/lib.rs | 2 +- .../rustc_borrowck/src/session_diagnostics.rs | 4 +- .../rustc_const_eval/src/const_eval/error.rs | 4 +- .../src/const_eval/machine.rs | 5 +- compiler/rustc_const_eval/src/errors.rs | 2 + .../src/check/compare_impl_item/refine.rs | 4 +- compiler/rustc_hir_analysis/src/check/errs.rs | 6 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +- .../src/coherence/orphan.rs | 16 +- compiler/rustc_hir_analysis/src/errors.rs | 5 + .../src/hir_ty_lowering/dyn_compatibility.rs | 7 +- compiler/rustc_hir_typeck/src/cast.rs | 24 +- compiler/rustc_hir_typeck/src/errors.rs | 39 +- compiler/rustc_hir_typeck/src/fallback.rs | 25 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- compiler/rustc_lint/src/async_closures.rs | 6 +- compiler/rustc_lint/src/async_fn_in_trait.rs | 10 +- compiler/rustc_lint/src/builtin.rs | 201 ++++--- .../rustc_lint/src/context/diagnostics.rs | 11 +- .../src/deref_into_dyn_supertrait.rs | 4 +- .../rustc_lint/src/drop_forget_useless.rs | 31 +- .../src/enum_intrinsics_non_enums.rs | 5 +- compiler/rustc_lint/src/expect.rs | 11 +- .../src/for_loops_over_fallibles.rs | 3 +- compiler/rustc_lint/src/foreign_modules.rs | 28 +- .../src/hidden_unicode_codepoints.rs | 4 +- compiler/rustc_lint/src/if_let_rescope.rs | 5 +- .../rustc_lint/src/impl_trait_overcaptures.rs | 16 +- compiler/rustc_lint/src/internal.rs | 67 ++- compiler/rustc_lint/src/invalid_from_utf8.rs | 12 +- compiler/rustc_lint/src/let_underscore.rs | 12 +- compiler/rustc_lint/src/levels.rs | 62 +- compiler/rustc_lint/src/lints.rs | 542 +++++++++++++++--- ..._expr_fragment_specifier_2024_migration.rs | 8 +- compiler/rustc_lint/src/map_unit_fn.rs | 6 +- compiler/rustc_lint/src/methods.rs | 4 +- .../src/multiple_supertrait_upcastable.rs | 8 +- compiler/rustc_lint/src/non_ascii_idents.rs | 15 +- compiler/rustc_lint/src/non_fmt_panic.rs | 16 +- compiler/rustc_lint/src/non_local_def.rs | 26 +- compiler/rustc_lint/src/nonstandard_style.rs | 8 +- compiler/rustc_lint/src/noop_method_call.rs | 26 +- .../src/opaque_hidden_inferred_bound.rs | 27 +- compiler/rustc_lint/src/pass_by_value.rs | 5 +- compiler/rustc_lint/src/precedence.rs | 23 +- compiler/rustc_lint/src/ptr_nulls.rs | 27 +- .../rustc_lint/src/redundant_semicolon.rs | 5 +- compiler/rustc_lint/src/reference_casting.rs | 9 +- compiler/rustc_lint/src/shadowed_into_iter.rs | 7 +- compiler/rustc_lint/src/static_mut_refs.rs | 2 +- .../rustc_lint/src/tail_expr_drop_order.rs | 14 +- compiler/rustc_lint/src/traits.rs | 5 +- compiler/rustc_lint/src/types.rs | 131 ++--- compiler/rustc_lint/src/types/literal.rs | 17 +- compiler/rustc_lint/src/unit_bindings.rs | 3 +- .../src/unqualified_local_imports.rs | 8 +- compiler/rustc_lint/src/unused.rs | 39 +- compiler/rustc_middle/src/lint.rs | 8 +- compiler/rustc_middle/src/middle/stability.rs | 10 +- .../rustc_mir_build/src/check_unsafety.rs | 38 +- compiler/rustc_mir_build/src/errors.rs | 34 +- compiler/rustc_mir_build/src/lints.rs | 2 +- .../src/thir/pattern/check_match.rs | 45 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 5 +- .../src/check_const_item_mutation.rs | 10 +- .../src/check_undefined_transmutes.rs | 5 +- compiler/rustc_mir_transform/src/coroutine.rs | 5 +- compiler/rustc_mir_transform/src/errors.rs | 25 +- .../src/ffi_unwind_calls.rs | 2 +- .../src/function_item_references.rs | 9 +- .../src/known_panics_lint.rs | 2 +- .../src/collector/move_check.rs | 2 +- compiler/rustc_monomorphize/src/errors.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 339 +++++------ compiler/rustc_passes/src/dead.rs | 16 +- compiler/rustc_passes/src/errors.rs | 195 +++++-- compiler/rustc_passes/src/liveness.rs | 64 +-- compiler/rustc_passes/src/naked_functions.rs | 7 +- compiler/rustc_passes/src/stability.rs | 22 +- compiler/rustc_pattern_analysis/src/errors.rs | 15 +- compiler/rustc_pattern_analysis/src/lints.rs | 13 +- compiler/rustc_pattern_analysis/src/rustc.rs | 18 +- compiler/rustc_privacy/src/errors.rs | 6 +- compiler/rustc_privacy/src/lib.rs | 26 +- .../traits/on_unimplemented.rs | 75 +-- 85 files changed, 1530 insertions(+), 1092 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 698fdafc93616..a9f7996fc150c 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -401,7 +401,7 @@ fn do_mir_borrowck<'tcx>( let mut_span = tcx.sess.source_map().span_until_non_whitespace(span); - tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span }) + tcx.emit_node_lint(UNUSED_MUT, lint_root, VarNeedNotMut { span, mut_span }) } let tainted_by_errors = mbcx.emit_errors(); diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 627444a4ce5b8..d335652fced48 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -50,8 +50,10 @@ pub(crate) struct GenericDoesNotLiveLongEnough { #[derive(LintDiagnostic)] #[diag(borrowck_var_does_not_need_mut)] pub(crate) struct VarNeedNotMut { - #[suggestion(style = "short", applicability = "machine-applicable", code = "")] + #[primary_span] pub span: Span, + #[suggestion(style = "short", applicability = "machine-applicable", code = "")] + pub mut_span: Span, } #[derive(Diagnostic)] #[diag(borrowck_var_cannot_escape_closure)] diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 6686413bf0254..35949111405bf 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -170,11 +170,11 @@ pub(super) fn lint<'tcx, L>( tcx: TyCtxtAt<'tcx>, machine: &CompileTimeMachine<'tcx>, lint: &'static rustc_session::lint::Lint, - decorator: impl FnOnce(Vec) -> L, + decorator: impl FnOnce(Span, Vec) -> L, ) where L: for<'a> rustc_errors::LintDiagnostic<'a, ()>, { let (span, frames) = get_span_and_frames(tcx, &machine.stack); - tcx.emit_node_span_lint(lint, machine.best_lint_scope(*tcx), span, decorator(frames)); + tcx.emit_node_lint(lint, machine.best_lint_scope(*tcx), decorator(span, frames)); } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 2db43a0f787eb..095c67aee74a0 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -622,11 +622,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { .0 .is_error(); let span = ecx.cur_span(); - ecx.tcx.emit_node_span_lint( + ecx.tcx.emit_node_lint( rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL, hir_id, - span, - LongRunning { item_span: ecx.tcx.span }, + LongRunning { span, item_span: ecx.tcx.span }, ); // If this was a hard error, don't bother continuing evaluation. if is_error { diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 211668cf055c6..d3b5db7323e25 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -197,6 +197,8 @@ pub(crate) struct InteriorMutableRefEscaping { #[diag(const_eval_long_running)] #[note] pub struct LongRunning { + #[primary_span] + pub span: Span, #[help] pub item_span: Span, } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index 2d6b9813271e2..217cadad11590 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -297,11 +297,11 @@ fn report_mismatched_rpitit_signature<'tcx>( }); let span = unmatched_bound.unwrap_or(span); - tcx.emit_node_span_lint( + tcx.emit_node_lint( if is_internal { REFINING_IMPL_TRAIT_INTERNAL } else { REFINING_IMPL_TRAIT_REACHABLE }, tcx.local_def_id_to_hir_id(impl_m_def_id.expect_local()), - span, crate::errors::ReturnPositionImplTraitInTraitRefined { + span, impl_return_span, trait_return_span, pre, diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 64307407b73e3..ba1acdd29b6bc 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -79,10 +79,6 @@ fn handle_static_mut_ref( } else { (errors::MutRefSugg::Shared { lo, hi }, "shared") }; - tcx.emit_node_span_lint(STATIC_MUT_REFS, hir_id, span, errors::RefOfMutStatic { - span, - sugg, - shared, - }); + tcx.emit_node_lint(STATIC_MUT_REFS, hir_id, errors::RefOfMutStatic { span, sugg, shared }); } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d70e8673c5203..d1279dec2ef84 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2334,11 +2334,10 @@ fn lint_redundant_lifetimes<'tcx>( && outlives_env.free_region_map().sub_free_regions(tcx, victim, candidate) { shadowed.insert(victim); - tcx.emit_node_span_lint( + tcx.emit_node_lint( rustc_lint_defs::builtin::REDUNDANT_LIFETIMES, tcx.local_def_id_to_hir_id(def_id.expect_local()), - tcx.def_span(def_id), - RedundantLifetimeArgsLint { candidate, victim }, + RedundantLifetimeArgsLint { span: tcx.def_span(def_id), candidate, victim }, ); } } @@ -2349,6 +2348,8 @@ fn lint_redundant_lifetimes<'tcx>( #[diag(hir_analysis_redundant_lifetime_args)] #[note] struct RedundantLifetimeArgsLint<'tcx> { + #[primary_span] + pub span: Span, /// The lifetime we have found to be redundant. victim: ty::Region<'tcx>, // The lifetime we can replace the victim with. diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 04770469132bb..18f60d80b35ff 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -494,18 +494,18 @@ fn lint_uncovered_ty_params<'tcx>( let name = tcx.item_name(param_def_id); match local_ty { - Some(local_type) => tcx.emit_node_span_lint( + Some(local_type) => tcx.emit_node_lint( UNCOVERED_PARAM_IN_PROJECTION, hir_id, - span, errors::TyParamFirstLocalLint { span, note: (), param: name, local_type }, ), - None => tcx.emit_node_span_lint( - UNCOVERED_PARAM_IN_PROJECTION, - hir_id, - span, - errors::TyParamSomeLint { span, note: (), param: name }, - ), + None => { + tcx.emit_node_lint(UNCOVERED_PARAM_IN_PROJECTION, hir_id, errors::TyParamSomeLint { + span, + note: (), + param: name, + }) + } }; } } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 77e81af3ca9a1..25362203cb25b 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1132,6 +1132,7 @@ pub(crate) enum LateBoundInApit { #[diag(hir_analysis_unused_associated_type_bounds)] #[note] pub(crate) struct UnusedAssociatedTypeBounds { + #[primary_span] #[suggestion(code = "")] pub span: Span, } @@ -1141,6 +1142,8 @@ pub(crate) struct UnusedAssociatedTypeBounds { #[note] #[note(hir_analysis_feedback_note)] pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> { + #[primary_span] + pub span: Span, #[suggestion(applicability = "maybe-incorrect", code = "{pre}{return_ty}{post}")] pub impl_return_span: Span, #[label] @@ -1398,6 +1401,7 @@ pub(crate) struct TyParamFirstLocal<'tcx> { #[diag(hir_analysis_ty_param_first_local, code = E0210)] #[note] pub(crate) struct TyParamFirstLocalLint<'tcx> { + #[primary_span] #[label] pub span: Span, #[note(hir_analysis_case_note)] @@ -1422,6 +1426,7 @@ pub(crate) struct TyParamSome { #[diag(hir_analysis_ty_param_some, code = E0210)] #[note] pub(crate) struct TyParamSomeLint { + #[primary_span] #[label] pub span: Span, #[note(hir_analysis_only_note)] diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 2cee7c77aa538..f8e09842e795b 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -193,16 +193,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a // corresponding `Projection` clause for def_ids in associated_types.values_mut() { - for (projection_bound, span) in &projection_bounds { + for &(projection_bound, span) in &projection_bounds { let def_id = projection_bound.projection_def_id(); // FIXME(#120456) - is `swap_remove` correct? def_ids.swap_remove(&def_id); if tcx.generics_require_sized_self(def_id) { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNUSED_ASSOCIATED_TYPE_BOUNDS, hir_id, - *span, - crate::errors::UnusedAssociatedTypeBounds { span: *span }, + crate::errors::UnusedAssociatedTypeBounds { span }, ); } } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 483a8d1d9a9dc..b87d57a073e96 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -663,7 +663,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { }; let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); - fcx.tcx.emit_node_span_lint(lint, self.expr.hir_id, self.span, errors::TrivialCast { + fcx.tcx.emit_node_lint(lint, self.expr.hir_id, errors::TrivialCast { + span: self.span, numeric, expr_ty, cast_ty, @@ -934,11 +935,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { .collect::>(); if !added.is_empty() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( lint::builtin::PTR_CAST_ADD_AUTO_TO_OBJECT, self.expr.hir_id, - self.span, errors::PtrCastAddAutoToObject { + span: self.span, traits_len: added.len(), traits: { let mut traits: Vec<_> = added @@ -1097,11 +1098,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); - fcx.tcx.emit_node_span_lint( + fcx.tcx.emit_node_lint( lint::builtin::CENUM_IMPL_DROP_CAST, self.expr.hir_id, - self.span, - errors::CastEnumDrop { expr_ty, cast_ty }, + errors::CastEnumDrop { span: self.span, expr_ty, cast_ty }, ); } } @@ -1130,12 +1130,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { (false, false) => errors::LossyProvenancePtr2IntSuggestion::Other { cast_span }, }; - let lint = errors::LossyProvenancePtr2Int { expr_ty, cast_ty, sugg }; - fcx.tcx.emit_node_span_lint( + fcx.tcx.emit_node_lint( lint::builtin::LOSSY_PROVENANCE_CASTS, self.expr.hir_id, - self.span, - lint, + errors::LossyProvenancePtr2Int { span: self.span, expr_ty, cast_ty, sugg }, ); } @@ -1146,12 +1144,10 @@ impl<'a, 'tcx> CastCheck<'tcx> { }; let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let cast_ty = fcx.resolve_vars_if_possible(self.cast_ty); - let lint = errors::LossyProvenanceInt2Ptr { expr_ty, cast_ty, sugg }; - fcx.tcx.emit_node_span_lint( + fcx.tcx.emit_node_lint( lint::builtin::FUZZY_PROVENANCE_CASTS, self.expr.hir_id, - self.span, - lint, + errors::LossyProvenanceInt2Ptr { span: self.span, expr_ty, cast_ty, sugg }, ); } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index cceaabaff65b6..94a1c5f100952 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -169,25 +169,42 @@ pub(crate) struct MissingParenthesesInRange { pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] - Call, + Call { + #[primary_span] + span: Span, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] - Method, + Method { + #[primary_span] + span: Span, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] - Path, + Path { + #[primary_span] + span: Span, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] - UnionField, + UnionField { + #[primary_span] + span: Span, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] - Deref, + Deref { + #[primary_span] + span: Span, + }, } #[derive(LintDiagnostic)] #[help] #[diag(hir_typeck_dependency_on_unit_never_type_fallback)] pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { + #[primary_span] + pub span: Span, #[note] pub obligation_span: Span, pub obligation: ty::Predicate<'tcx>, @@ -247,6 +264,8 @@ impl Subdiagnostic for TypeMismatchFruTypo { #[diag(hir_typeck_lossy_provenance_int2ptr)] #[help] pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { + #[primary_span] + pub span: Span, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, #[subdiagnostic] @@ -256,6 +275,8 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> { #[derive(LintDiagnostic)] #[diag(hir_typeck_ptr_cast_add_auto_to_object)] pub(crate) struct PtrCastAddAutoToObject { + #[primary_span] + pub span: Span, pub traits_len: usize, pub traits: DiagSymbolList, } @@ -273,6 +294,8 @@ pub(crate) struct LossyProvenanceInt2PtrSuggestion { #[diag(hir_typeck_lossy_provenance_ptr2int)] #[help] pub(crate) struct LossyProvenancePtr2Int<'tcx> { + #[primary_span] + pub span: Span, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, #[subdiagnostic] @@ -520,6 +543,8 @@ pub(crate) struct SuggestPtrNullMut { #[diag(hir_typeck_trivial_cast)] #[help] pub(crate) struct TrivialCast<'tcx> { + #[primary_span] + pub span: Span, pub numeric: bool, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, @@ -560,6 +585,8 @@ pub(crate) struct CannotCastToBool<'tcx> { #[derive(LintDiagnostic)] #[diag(hir_typeck_cast_enum_drop)] pub(crate) struct CastEnumDrop<'tcx> { + #[primary_span] + pub span: Span, pub expr_ty: Ty<'tcx>, pub cast_ty: Ty<'tcx>, } @@ -684,6 +711,8 @@ pub(crate) struct SelfCtorFromOuterItem { #[derive(LintDiagnostic)] #[diag(hir_typeck_self_ctor_from_outer_item)] pub(crate) struct SelfCtorFromOuterItemLint { + #[primary_span] + pub span: Span, #[label] pub impl_span: Span, #[subdiagnostic] diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 4fd508ab896e7..84a926186a7ab 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -457,18 +457,25 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .collect::>(); for (hir_id, span, reason) in affected_unsafe_infer_vars { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, hir_id, - span, match reason { - UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call, - UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method, - UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path, + UnsafeUseReason::Call => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Call { span } + } + UnsafeUseReason::Method => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Method { span } + } + UnsafeUseReason::Path => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Path { span } + } UnsafeUseReason::UnionField => { - errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField + errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField { span } + } + UnsafeUseReason::Deref => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { span } } - UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref, }, ); } @@ -512,11 +519,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> { && let [ref mut never_error, ..] = never_errors.as_mut_slice() { self.adjust_fulfillment_error_for_expr_obligation(never_error); - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, self.tcx.local_def_id_to_hir_id(self.body_id), - self.tcx.def_span(self.body_id), errors::DependencyOnUnitNeverTypeFallback { + span: self.tcx.def_span(self.body_id), obligation_span: never_error.obligation.cause.span, obligation: never_error.obligation.predicate, }, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d2d311ef5654f..ef9af9347f71b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1148,11 +1148,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); return (Ty::new_error(self.tcx, guar), res); } else { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( SELF_CONSTRUCTOR_FROM_OUTER_ITEM, hir_id, - path_span, errors::SelfCtorFromOuterItemLint { + span: path_span, impl_span: tcx.def_span(impl_def_id), sugg, }, diff --git a/compiler/rustc_lint/src/async_closures.rs b/compiler/rustc_lint/src/async_closures.rs index 2a821b7110316..2398805d8ec3e 100644 --- a/compiler/rustc_lint/src/async_closures.rs +++ b/compiler/rustc_lint/src/async_closures.rs @@ -96,11 +96,11 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage { let deletion_span = cx.tcx.sess.source_map().span_extend_while_whitespace(async_decl_span); - cx.tcx.emit_node_span_lint( + cx.tcx.emit_node_lint( CLOSURE_RETURNING_ASYNC_BLOCK, expr.hir_id, - fn_decl_span, ClosureReturningAsyncBlock { + span: fn_decl_span, async_decl_span, sugg: AsyncClosureSugg { deletion_span, @@ -114,6 +114,8 @@ impl<'tcx> LateLintPass<'tcx> for AsyncClosureUsage { #[derive(LintDiagnostic)] #[diag(lint_closure_returning_async_block)] struct ClosureReturningAsyncBlock { + #[primary_span] + span: Span, #[label] async_decl_span: Span, #[subdiagnostic] diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs index 9923f05df3c73..361ffb20a11e5 100644 --- a/compiler/rustc_lint/src/async_fn_in_trait.rs +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -118,12 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait { opaq_def.def_id, " + Send", ); - cx.tcx.emit_node_span_lint( - ASYNC_FN_IN_TRAIT, - item.hir_id(), - async_span, - AsyncFnInTraitDiag { sugg }, - ); + cx.tcx.emit_node_lint(ASYNC_FN_IN_TRAIT, item.hir_id(), AsyncFnInTraitDiag { + span: async_span, + sugg, + }); } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 5c5cd99345ef1..8d56296681654 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -120,10 +120,7 @@ impl EarlyLintPass for WhileTrue { "{}loop", label.map_or_else(String::new, |label| format!("{}: ", label.ident,)) ); - cx.emit_span_lint(WHILE_TRUE, condition_span, BuiltinWhileTrue { - suggestion: condition_span, - replace, - }); + cx.emit_lint(WHILE_TRUE, BuiltinWhileTrue { span: condition_span, replace }); } } } @@ -189,12 +186,11 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns { if cx.tcx.find_field_index(ident, variant) == Some(cx.typeck_results().field_index(fieldpat.hir_id)) { - cx.emit_span_lint( + cx.emit_lint( NON_SHORTHAND_FIELD_PATTERNS, - fieldpat.span, BuiltinNonShorthandFieldPatterns { + span: fieldpat.span, ident, - suggestion: fieldpat.span, prefix: binding_annot.prefix_str(), }, ); @@ -247,25 +243,22 @@ declare_lint! { declare_lint_pass!(UnsafeCode => [UNSAFE_CODE]); impl UnsafeCode { - fn report_unsafe( - &self, - cx: &EarlyContext<'_>, - span: Span, - decorate: impl for<'a> LintDiagnostic<'a, ()>, - ) { + fn report_unsafe(&self, cx: &EarlyContext<'_>, decorate: impl for<'a> LintDiagnostic<'a, ()>) { // This comes from a macro that has `#[allow_internal_unsafe]`. - if span.allows_unsafe() { + if let Some(span) = decorate.span() + && span.primary_spans().iter().all(|span| span.allows_unsafe()) + { return; } - cx.emit_span_lint(UNSAFE_CODE, span, decorate); + cx.emit_lint(UNSAFE_CODE, decorate); } } impl EarlyLintPass for UnsafeCode { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { if attr.has_name(sym::allow_internal_unsafe) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::AllowInternalUnsafe); + self.report_unsafe(cx, BuiltinUnsafe::AllowInternalUnsafe { span: attr.span }); } } @@ -274,7 +267,7 @@ impl EarlyLintPass for UnsafeCode { if let ast::ExprKind::Block(ref blk, _) = e.kind { // Don't warn about generated blocks; that'll just pollute the output. if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) { - self.report_unsafe(cx, blk.span, BuiltinUnsafe::UnsafeBlock); + self.report_unsafe(cx, BuiltinUnsafe::UnsafeBlock { span: blk.span }); } } } @@ -282,48 +275,48 @@ impl EarlyLintPass for UnsafeCode { fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { match it.kind { ast::ItemKind::Trait(box ast::Trait { safety: ast::Safety::Unsafe(_), .. }) => { - self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeTrait); + self.report_unsafe(cx, BuiltinUnsafe::UnsafeTrait { span: it.span }); } ast::ItemKind::Impl(box ast::Impl { safety: ast::Safety::Unsafe(_), .. }) => { - self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeImpl); + self.report_unsafe(cx, BuiltinUnsafe::UnsafeImpl { span: it.span }); } ast::ItemKind::Fn(..) => { if let Some(attr) = attr::find_by_name(&it.attrs, sym::no_mangle) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleFn); + self.report_unsafe(cx, BuiltinUnsafe::NoMangleFn { span: attr.span }); } if let Some(attr) = attr::find_by_name(&it.attrs, sym::export_name) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameFn); + self.report_unsafe(cx, BuiltinUnsafe::ExportNameFn { span: attr.span }); } if let Some(attr) = attr::find_by_name(&it.attrs, sym::link_section) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::LinkSectionFn); + self.report_unsafe(cx, BuiltinUnsafe::LinkSectionFn { span: attr.span }); } } ast::ItemKind::Static(..) => { if let Some(attr) = attr::find_by_name(&it.attrs, sym::no_mangle) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleStatic); + self.report_unsafe(cx, BuiltinUnsafe::NoMangleStatic { span: attr.span }); } if let Some(attr) = attr::find_by_name(&it.attrs, sym::export_name) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameStatic); + self.report_unsafe(cx, BuiltinUnsafe::ExportNameStatic { span: attr.span }); } if let Some(attr) = attr::find_by_name(&it.attrs, sym::link_section) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::LinkSectionStatic); + self.report_unsafe(cx, BuiltinUnsafe::LinkSectionStatic { span: attr.span }); } } ast::ItemKind::GlobalAsm(..) => { - self.report_unsafe(cx, it.span, BuiltinUnsafe::GlobalAsm); + self.report_unsafe(cx, BuiltinUnsafe::GlobalAsm { span: it.span }); } ast::ItemKind::ForeignMod(ForeignMod { safety, .. }) => { if let Safety::Unsafe(_) = safety { - self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeExternBlock); + self.report_unsafe(cx, BuiltinUnsafe::UnsafeExternBlock { span: it.span }); } } @@ -334,10 +327,10 @@ impl EarlyLintPass for UnsafeCode { fn check_impl_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) { if let ast::AssocItemKind::Fn(..) = it.kind { if let Some(attr) = attr::find_by_name(&it.attrs, sym::no_mangle) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleMethod); + self.report_unsafe(cx, BuiltinUnsafe::NoMangleMethod { span: attr.span }); } if let Some(attr) = attr::find_by_name(&it.attrs, sym::export_name) { - self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameMethod); + self.report_unsafe(cx, BuiltinUnsafe::ExportNameMethod { span: attr.span }); } } } @@ -352,13 +345,12 @@ impl EarlyLintPass for UnsafeCode { body, ) = fk { - let decorator = match ctxt { + self.report_unsafe(cx, match ctxt { FnCtxt::Foreign => return, - FnCtxt::Free => BuiltinUnsafe::DeclUnsafeFn, - FnCtxt::Assoc(_) if body.is_none() => BuiltinUnsafe::DeclUnsafeMethod, - FnCtxt::Assoc(_) => BuiltinUnsafe::ImplUnsafeMethod, - }; - self.report_unsafe(cx, span, decorator); + FnCtxt::Free => BuiltinUnsafe::DeclUnsafeFn { span }, + FnCtxt::Assoc(_) if body.is_none() => BuiltinUnsafe::DeclUnsafeMethod { span }, + FnCtxt::Assoc(_) => BuiltinUnsafe::ImplUnsafeMethod { span }, + }); } } } @@ -435,7 +427,8 @@ impl MissingDoc { let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id)); let has_doc = attrs.iter().any(has_doc); if !has_doc { - cx.emit_span_lint(MISSING_DOCS, cx.tcx.def_span(def_id), BuiltinMissingDoc { + cx.emit_lint(MISSING_DOCS, BuiltinMissingDoc { + span: cx.tcx.def_span(def_id), article, desc, }); @@ -634,7 +627,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { ) .is_ok() { - cx.emit_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, BuiltinMissingCopyImpl); + cx.emit_lint(MISSING_COPY_IMPLEMENTATIONS, BuiltinMissingCopyImpl { span: item.span }); } } } @@ -719,7 +712,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { .next() .is_some(); if !has_impl { - cx.emit_span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, BuiltinMissingDebugImpl { + cx.emit_lint(MISSING_DEBUG_IMPLEMENTATIONS, BuiltinMissingDebugImpl { + span: item.span, tcx: cx.tcx, def_id: debug, }); @@ -797,11 +791,11 @@ impl EarlyLintPass for AnonymousParameters { } else { ("", Applicability::HasPlaceholders) }; - cx.emit_span_lint( - ANONYMOUS_PARAMETERS, - arg.pat.span, - BuiltinAnonymousParams { suggestion: (arg.pat.span, appl), ty_snip }, - ); + cx.emit_lint(ANONYMOUS_PARAMETERS, BuiltinAnonymousParams { + span: arg.pat.span, + suggestion: (arg.pat.span, appl), + ty_snip, + }); } } } @@ -844,7 +838,8 @@ impl EarlyLintPass for DeprecatedAttr { BuiltinDeprecatedAttrLinkSuggestion::Default { suggestion: attr.span } } }; - cx.emit_span_lint(DEPRECATED, attr.span, BuiltinDeprecatedAttrLink { + cx.emit_lint(DEPRECATED, BuiltinDeprecatedAttrLink { + span: attr.span, name, reason, link, @@ -855,9 +850,9 @@ impl EarlyLintPass for DeprecatedAttr { } } if attr.has_name(sym::no_start) || attr.has_name(sym::crate_id) { - cx.emit_span_lint(DEPRECATED, attr.span, BuiltinDeprecatedAttrUsed { + cx.emit_lint(DEPRECATED, BuiltinDeprecatedAttrUsed { + span: attr.span, name: pprust::path_to_string(&attr.get_normal_item().path), - suggestion: attr.span, }); } } @@ -893,7 +888,8 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & BuiltinUnusedDocCommentSub::BlockHelp } }; - cx.emit_span_lint(UNUSED_DOC_COMMENTS, span, BuiltinUnusedDocComment { + cx.emit_lint(UNUSED_DOC_COMMENTS, BuiltinUnusedDocComment { + span, kind: node_kind, label: node_span, sub, @@ -1027,7 +1023,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { match param.kind { GenericParamKind::Lifetime { .. } => {} GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - cx.emit_span_lint(NO_MANGLE_GENERIC_ITEMS, span, BuiltinNoMangleGeneric { + cx.emit_lint(NO_MANGLE_GENERIC_ITEMS, BuiltinNoMangleGeneric { + span, suggestion: no_mangle_attr.span, }); break; @@ -1056,7 +1053,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to - cx.emit_span_lint(NO_MANGLE_CONST_ITEMS, it.span, BuiltinConstNoMangle { + cx.emit_lint(NO_MANGLE_CONST_ITEMS, BuiltinConstNoMangle { + span: it.span, suggestion, }); } @@ -1117,7 +1115,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind())) { if from_mutbl < to_mutbl { - cx.emit_span_lint(MUTABLE_TRANSMUTES, expr.span, BuiltinMutablesTransmutes); + cx.emit_lint(MUTABLE_TRANSMUTES, BuiltinMutablesTransmutes { span: expr.span }); } } @@ -1186,7 +1184,7 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { && let Some(items) = attr.meta_item_list() { for item in items { - cx.emit_span_lint(UNSTABLE_FEATURES, item.span(), BuiltinUnstableFeatures); + cx.emit_lint(UNSTABLE_FEATURES, BuiltinUnstableFeatures { span: item.span() }); } } } @@ -1239,11 +1237,11 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller { // Now, check if the function has the `#[track_caller]` attribute && let Some(attr) = cx.tcx.get_attr(def_id, sym::track_caller) { - cx.emit_span_lint( - UNGATED_ASYNC_FN_TRACK_CALLER, - attr.span, - BuiltinUngatedAsyncFnTrackCaller { label: span, session: &cx.tcx.sess }, - ); + cx.emit_lint(UNGATED_ASYNC_FN_TRACK_CALLER, BuiltinUngatedAsyncFnTrackCaller { + span: attr.span, + label: span, + session: &cx.tcx.sess, + }); } } } @@ -1306,7 +1304,8 @@ impl UnreachablePub { applicability = Applicability::MaybeIncorrect; } let def_span = cx.tcx.def_span(def_id); - cx.emit_span_lint(UNREACHABLE_PUB, def_span, BuiltinUnreachablePub { + cx.emit_lint(UNREACHABLE_PUB, BuiltinUnreachablePub { + span: def_span, what, suggestion: (vis_span, applicability), help: exportable, @@ -1453,20 +1452,20 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { let mut ty = Some(hir_ty); let enable_feat_help = cx.tcx.sess.is_nightly_build(); - if let [.., label_sp] = *where_spans { - cx.emit_span_lint(TYPE_ALIAS_BOUNDS, where_spans, BuiltinTypeAliasBounds { + if !where_spans.is_empty() { + cx.emit_lint(TYPE_ALIAS_BOUNDS, BuiltinTypeAliasBounds { + spans: where_spans, in_where_clause: true, - label: label_sp, enable_feat_help, suggestions: vec![(generics.where_clause_span, String::new())], preds: generics.predicates, ty: ty.take(), }); } - if let [.., label_sp] = *inline_spans { - cx.emit_span_lint(TYPE_ALIAS_BOUNDS, inline_spans, BuiltinTypeAliasBounds { + if !inline_spans.is_empty() { + cx.emit_lint(TYPE_ALIAS_BOUNDS, BuiltinTypeAliasBounds { + spans: inline_spans, in_where_clause: false, - label: label_sp, enable_feat_help, suggestions: inline_sugg, preds: generics.predicates, @@ -1557,7 +1556,8 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { | ClauseKind::ConstEvaluatable(..) => continue, }; if predicate.is_global() { - cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds { + cx.emit_lint(TRIVIAL_BOUNDS, BuiltinTrivialBounds { + span, predicate_kind_name, predicate, }); @@ -1674,11 +1674,10 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { replace, }); } else { - cx.emit_span_lint( + cx.emit_lint( ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, - pat.span, BuiltinEllipsisInclusiveRangePatternsLint::Parenthesise { - suggestion: pat.span, + span: pat.span, replace, }, ); @@ -1692,12 +1691,9 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { replace: replace.to_string(), }); } else { - cx.emit_span_lint( + cx.emit_lint( ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, - join, - BuiltinEllipsisInclusiveRangePatternsLint::NonParenthesise { - suggestion: join, - }, + BuiltinEllipsisInclusiveRangePatternsLint::NonParenthesise { span: join }, ); } }; @@ -1876,10 +1872,10 @@ impl KeywordIdents { return; } - cx.emit_span_lint(lint, ident.span, BuiltinKeywordIdents { + cx.emit_lint(lint, BuiltinKeywordIdents { + span: ident.span, kw: ident, next: edition, - suggestion: ident.span, prefix, }); } @@ -2213,17 +2209,14 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { lint_spans.sort_unstable(); lint_spans.dedup(); - cx.emit_span_lint( - EXPLICIT_OUTLIVES_REQUIREMENTS, - lint_spans.clone(), - BuiltinExplicitOutlives { - count: bound_count, - suggestion: BuiltinExplicitOutlivesSuggestion { - spans: lint_spans, - applicability, - }, + cx.emit_lint(EXPLICIT_OUTLIVES_REQUIREMENTS, BuiltinExplicitOutlives { + spans: lint_spans.clone(), + count: bound_count, + suggestion: BuiltinExplicitOutlivesSuggestion { + spans: lint_spans, + applicability, }, - ); + }); } } } @@ -2300,13 +2293,14 @@ impl EarlyLintPass for IncompleteInternalFeatures { let help = HAS_MIN_FEATURES.contains(&name).then_some(BuiltinIncompleteFeaturesHelp); - cx.emit_span_lint(INCOMPLETE_FEATURES, span, BuiltinIncompleteFeatures { + cx.emit_lint(INCOMPLETE_FEATURES, BuiltinIncompleteFeatures { + span, name, note, help, }); } else { - cx.emit_span_lint(INTERNAL_FEATURES, span, BuiltinInternalFeatures { name }); + cx.emit_lint(INTERNAL_FEATURES, BuiltinInternalFeatures { span, name }); } }); } @@ -2625,10 +2619,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit, }; let sub = BuiltinUnpermittedTypeInitSub { err }; - cx.emit_span_lint(INVALID_VALUE, expr.span, BuiltinUnpermittedTypeInit { + cx.emit_lint(INVALID_VALUE, BuiltinUnpermittedTypeInit { + span: expr.span, msg, ty: conjured_ty, - label: expr.span, sub, tcx: cx.tcx, }); @@ -2717,9 +2711,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr { { // `&raw *NULL` is ok. } else { - cx.emit_span_lint(DEREF_NULLPTR, expr.span, BuiltinDerefNullptr { - label: expr.span, - }); + cx.emit_lint(DEREF_NULLPTR, BuiltinDerefNullptr { span: expr.span }); } } } @@ -2936,12 +2928,14 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels { let span = span.unwrap_or(*template_span); match label_kind { AsmLabelKind::Named => { - cx.emit_span_lint(NAMED_ASM_LABELS, span, InvalidAsmLabel::Named { + cx.emit_lint(NAMED_ASM_LABELS, InvalidAsmLabel::Named { + span, missing_precise_span, }); } AsmLabelKind::FormatArg => { - cx.emit_span_lint(NAMED_ASM_LABELS, span, InvalidAsmLabel::FormatArg { + cx.emit_lint(NAMED_ASM_LABELS, InvalidAsmLabel::FormatArg { + span, missing_precise_span, }); } @@ -2953,9 +2947,9 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels { Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) | None ) => { - cx.emit_span_lint(BINARY_ASM_LABELS, span, InvalidAsmLabel::Binary { - missing_precise_span, + cx.emit_lint(BINARY_ASM_LABELS, InvalidAsmLabel::Binary { span, + missing_precise_span, }) } // No lint on anything other than x86 @@ -3027,16 +3021,13 @@ impl EarlyLintPass for SpecialModuleName { } match item.ident.name.as_str() { - "lib" => cx.emit_span_lint( - SPECIAL_MODULE_NAME, - item.span, - BuiltinSpecialModuleNameUsed::Lib, - ), - "main" => cx.emit_span_lint( - SPECIAL_MODULE_NAME, - item.span, - BuiltinSpecialModuleNameUsed::Main, - ), + "lib" => cx.emit_lint(SPECIAL_MODULE_NAME, BuiltinSpecialModuleNameUsed::Lib { + span: item.span, + }), + "main" => cx + .emit_lint(SPECIAL_MODULE_NAME, BuiltinSpecialModuleNameUsed::Main { + span: item.span, + }), _ => continue, } } diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 565c3c0425256..66e0149bee965 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -139,8 +139,15 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & suggestion, }); - stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } - .decorate_lint(diag); + stability::Deprecated { + span: None, + sub, + kind: "macro".to_owned(), + path, + note, + since_kind, + } + .decorate_lint(diag); } BuiltinLintDiag::UnusedDocComment(attr_span) => { lints::UnusedDocComment { span: attr_span }.decorate_lint(diag); diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 657642e093ccd..2a25459fb82a4 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -86,12 +86,12 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { .find_map(|i| (i.ident.name == sym::Target).then_some(i.span)) .map(|label| SupertraitAsDerefTargetLabel { label }); let span = tcx.def_span(item.owner_id.def_id); - cx.emit_span_lint(DEREF_INTO_DYN_SUPERTRAIT, span, SupertraitAsDerefTarget { + cx.emit_lint(DEREF_INTO_DYN_SUPERTRAIT, SupertraitAsDerefTarget { + span, self_ty, supertrait_principal: supertrait_principal .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)), target_principal, - label: span, label2, }); } diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 364c6fd488a8e..ceaac45ce104b 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -163,28 +163,32 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { }; match fn_name { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { - cx.emit_span_lint(DROPPING_REFERENCES, expr.span, DropRefDiag { + cx.emit_lint(DROPPING_REFERENCES, DropRefDiag { + span: expr.span, arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg(), }); } sym::mem_forget if arg_ty.is_ref() => { - cx.emit_span_lint(FORGETTING_REFERENCES, expr.span, ForgetRefDiag { + cx.emit_lint(FORGETTING_REFERENCES, ForgetRefDiag { + span: expr.span, arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg(), }); } sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { - cx.emit_span_lint(DROPPING_COPY_TYPES, expr.span, DropCopyDiag { + cx.emit_lint(DROPPING_COPY_TYPES, DropCopyDiag { + span: expr.span, arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg(), }); } sym::mem_forget if is_copy => { - cx.emit_span_lint(FORGETTING_COPY_TYPES, expr.span, ForgetCopyDiag { + cx.emit_lint(FORGETTING_COPY_TYPES, ForgetCopyDiag { + span: expr.span, arg_ty, label: arg.span, sugg: let_underscore_ignore_sugg(), @@ -194,18 +198,15 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { if let ty::Adt(adt, _) = arg_ty.kind() && adt.is_manually_drop() => { - cx.emit_span_lint( - UNDROPPED_MANUALLY_DROPS, - expr.span, - UndroppedManuallyDropsDiag { - arg_ty, - label: arg.span, - suggestion: UndroppedManuallyDropsSuggestion { - start_span: arg.span.shrink_to_lo(), - end_span: arg.span.shrink_to_hi(), - }, + cx.emit_lint(UNDROPPED_MANUALLY_DROPS, UndroppedManuallyDropsDiag { + span: expr.span, + arg_ty, + label: arg.span, + suggestion: UndroppedManuallyDropsSuggestion { + start_span: arg.span.shrink_to_lo(), + end_span: arg.span.shrink_to_hi(), }, - ); + }); } _ => return, }; diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs index 8e22a9bdc45a7..77e0bf1c4ca57 100644 --- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs +++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs @@ -55,7 +55,8 @@ fn enforce_mem_discriminant( ) { let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0); if is_non_enum(ty_param) { - cx.emit_span_lint(ENUM_INTRINSICS_NON_ENUMS, expr_span, EnumIntrinsicsMemDiscriminate { + cx.emit_lint(ENUM_INTRINSICS_NON_ENUMS, EnumIntrinsicsMemDiscriminate { + span: expr_span, ty_param, note: args_span, }); @@ -65,7 +66,7 @@ fn enforce_mem_discriminant( fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, span: Span) { let ty_param = cx.typeck_results().node_args(func_expr.hir_id).type_at(0); if is_non_enum(ty_param) { - cx.emit_span_lint(ENUM_INTRINSICS_NON_ENUMS, span, EnumIntrinsicsMemVariant { ty_param }); + cx.emit_lint(ENUM_INTRINSICS_NON_ENUMS, EnumIntrinsicsMemVariant { span, ty_param }); } } diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 289e2c9b72243..67e8046a95cfc 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -61,12 +61,11 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { { let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale }); let note = expectation.is_unfulfilled_lint_expectations; - tcx.emit_node_span_lint( - UNFULFILLED_LINT_EXPECTATIONS, - *hir_id, - expectation.emission_span, - Expectation { rationale, note }, - ); + tcx.emit_node_lint(UNFULFILLED_LINT_EXPECTATIONS, *hir_id, Expectation { + span: expectation.emission_span, + rationale, + note, + }); } } } diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index fcb7a6108c0e2..732309936d971 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -96,7 +96,8 @@ impl<'tcx> LateLintPass<'tcx> for ForLoopsOverFallibles { end_span: pat.span.between(arg.span), }; - cx.emit_span_lint(FOR_LOOPS_OVER_FALLIBLES, arg.span, ForLoopsOverFalliblesDiag { + cx.emit_lint(FOR_LOOPS_OVER_FALLIBLES, ForLoopsOverFalliblesDiag { + span: arg.span, article, ref_prefix, ty, diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 816882962bef6..57444c2b3c2a7 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -142,31 +142,17 @@ impl ClashingExternDeclarations { let this = tcx.item_name(this_fi.owner_id.to_def_id()); let orig = orig.get_name(); let previous_decl_label = get_relevant_span(tcx, existing_did); - let mismatch_label = get_relevant_span(tcx, this_fi.owner_id); + let span = get_relevant_span(tcx, this_fi.owner_id); let sub = BuiltinClashingExternSub { tcx, expected: existing_decl_ty, found: this_decl_ty }; - let decorator = if orig == this { - BuiltinClashingExtern::SameName { - this, - orig, - previous_decl_label, - mismatch_label, - sub, - } - } else { - BuiltinClashingExtern::DiffName { - this, - orig, - previous_decl_label, - mismatch_label, - sub, - } - }; - tcx.emit_node_span_lint( + tcx.emit_node_lint( CLASHING_EXTERN_DECLARATIONS, this_fi.hir_id(), - mismatch_label, - decorator, + if orig == this { + BuiltinClashingExtern::SameName { span, this, orig, previous_decl_label, sub } + } else { + BuiltinClashingExtern::DiffName { span, this, orig, previous_decl_label, sub } + }, ); } } diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs index 025fd45204064..9aacbba9649f6 100644 --- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs +++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs @@ -73,10 +73,10 @@ impl HiddenUnicodeCodepoints { HiddenUnicodeCodepointsDiagSub::NoEscape { spans } }; - cx.emit_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, HiddenUnicodeCodepointsDiag { + cx.emit_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, HiddenUnicodeCodepointsDiag { + span, label, count, - span_label: span, labels, sub, }); diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index bdfcc2c0a1006..8791a31a7cc9c 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -219,7 +219,8 @@ impl IfLetRescope { } } if let Some((span, hir_id)) = first_if_to_lint { - tcx.emit_node_span_lint(IF_LET_RESCOPE, hir_id, span, IfLetRescopeLint { + tcx.emit_node_lint(IF_LET_RESCOPE, hir_id, IfLetRescopeLint { + span, significant_droppers, lifetime_ends, rewrite: first_if_to_rewrite.then_some(IfLetRescopeRewrite { @@ -280,6 +281,8 @@ impl<'tcx> LateLintPass<'tcx> for IfLetRescope { #[derive(LintDiagnostic)] #[diag(lint_if_let_rescope)] struct IfLetRescopeLint { + #[primary_span] + span: Span, #[label] significant_droppers: Vec, #[help] diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index cc40b67ab271d..d25185d1722c4 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -366,11 +366,11 @@ where .map(|(def_id, _)| self.tcx.def_span(def_id)) .collect(); - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( IMPL_TRAIT_OVERCAPTURES, self.tcx.local_def_id_to_hir_id(opaque_def_id), - opaque_span, ImplTraitOvercapturesLint { + span: opaque_span, self_ty: t, num_captured: uncaptured_spans.len(), uncaptured_spans, @@ -423,11 +423,10 @@ where .iter() .all(|(def_id, _)| explicitly_captured.contains(def_id)) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( IMPL_TRAIT_REDUNDANT_CAPTURES, self.tcx.local_def_id_to_hir_id(opaque_def_id), - opaque_span, - ImplTraitRedundantCapturesLint { capturing_span }, + ImplTraitRedundantCapturesLint { span: opaque_span, capturing_span }, ); } } @@ -448,6 +447,7 @@ where } struct ImplTraitOvercapturesLint<'tcx> { + span: Span, uncaptured_spans: Vec, self_ty: Ty<'tcx>, num_captured: usize, @@ -470,11 +470,17 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { ); } } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(LintDiagnostic)] #[diag(lint_impl_trait_redundant_captures)] struct ImplTraitRedundantCapturesLint { + #[primary_span] + span: Span, #[suggestion(lint_suggestion, code = "", applicability = "machine-applicable")] capturing_span: Span, } diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 94cc58e495681..9ebd536e775cd 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -48,7 +48,8 @@ impl LateLintPass<'_> for DefaultHashTypes { Some(sym::HashSet) => "FxHashSet", _ => return, }; - cx.emit_span_lint(DEFAULT_HASH_TYPES, path.span, DefaultHashTypesDiag { + cx.emit_lint(DEFAULT_HASH_TYPES, DefaultHashTypesDiag { + span: path.span, preferred, used: cx.tcx.item_name(def_id), }); @@ -106,12 +107,14 @@ impl LateLintPass<'_> for QueryStability { if let Ok(Some(instance)) = ty::Instance::try_resolve(cx.tcx, cx.param_env, def_id, args) { let def_id = instance.def_id(); if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { - cx.emit_span_lint(POTENTIAL_QUERY_INSTABILITY, span, QueryInstability { + cx.emit_lint(POTENTIAL_QUERY_INSTABILITY, QueryInstability { + span, query: cx.tcx.item_name(def_id), }); } if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) { - cx.emit_span_lint(UNTRACKED_QUERY_INFORMATION, span, QueryUntracked { + cx.emit_lint(UNTRACKED_QUERY_INFORMATION, QueryUntracked { + span, method: cx.tcx.item_name(def_id), }); } @@ -154,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { { let span = path.span.with_hi(segment.args.map_or(segment.ident.span, |a| a.span_ext).hi()); - cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { suggestion: span }); + cx.emit_lint(USAGE_OF_TY_TYKIND, TykindKind { span: path.span, suggestion: span }); } } @@ -203,20 +206,18 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { match span { Some(span) => { - cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindKind { + cx.emit_lint(USAGE_OF_TY_TYKIND, TykindKind { + span: path.span, suggestion: span, }); } - None => cx.emit_span_lint(USAGE_OF_TY_TYKIND, path.span, TykindDiag), + None => cx.emit_lint(USAGE_OF_TY_TYKIND, TykindDiag { span: path.span }), } } else if !ty.span.from_expansion() && path.segments.len() > 1 && let Some(ty) = is_ty_or_ty_ctxt(cx, path) { - cx.emit_span_lint(USAGE_OF_QUALIFIED_TY, path.span, TyQualified { - ty, - suggestion: path.span, - }); + cx.emit_lint(USAGE_OF_QUALIFIED_TY, TyQualified { span: path.span, ty }); } } _ => {} @@ -309,15 +310,13 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr { if let Some(seg) = path.segments.iter().find(|seg| seg.res.opt_def_id().is_some_and(is_mod_inherent)) { - cx.emit_span_lint(USAGE_OF_TYPE_IR_INHERENT, seg.ident.span, TypeIrInherentUsage); + cx.emit_lint(USAGE_OF_TYPE_IR_INHERENT, TypeIrInherentUsage { span: seg.ident.span }); } // Final path resolutions, like `use rustc_type_ir::inherent` else if path.res.iter().any(|res| res.opt_def_id().is_some_and(is_mod_inherent)) { - cx.emit_span_lint( - USAGE_OF_TYPE_IR_INHERENT, - path.segments.last().unwrap().ident.span, - TypeIrInherentUsage, - ); + cx.emit_lint(USAGE_OF_TYPE_IR_INHERENT, TypeIrInherentUsage { + span: path.segments.last().unwrap().ident.span, + }); } let (lo, hi, snippet) = match path.segments { @@ -339,11 +338,11 @@ impl<'tcx> LateLintPass<'tcx> for TypeIr { } _ => return, }; - cx.emit_span_lint( - NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, - path.span, - NonGlobImportTypeIrInherent { suggestion: lo.eq_ctxt(hi).then(|| lo.to(hi)), snippet }, - ); + cx.emit_lint(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, NonGlobImportTypeIrInherent { + span: path.span, + suggestion: lo.eq_ctxt(hi).then(|| lo.to(hi)), + snippet, + }); } } @@ -368,11 +367,9 @@ impl EarlyLintPass for LintPassImpl { && call_site.ctxt().outer_expn_data().kind != ExpnKind::Macro(MacroKind::Bang, sym::declare_lint_pass) { - cx.emit_span_lint( - LINT_PASS_IMPL_WITHOUT_MACRO, - lint_pass.path.span, - LintPassByHand, - ); + cx.emit_lint(LINT_PASS_IMPL_WITHOUT_MACRO, LintPassByHand { + span: lint_pass.path.span, + }); } } } @@ -410,7 +407,8 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword { if is_doc_keyword(keyword) { return; } - cx.emit_span_lint(EXISTING_DOC_KEYWORD, attr.span, NonExistentDocKeyword { + cx.emit_lint(EXISTING_DOC_KEYWORD, NonExistentDocKeyword { + span: attr.span, keyword, }); } @@ -521,11 +519,9 @@ impl Diagnostics { let is_translatable = Self::is_diag_message(cx, arg_ty) || matches!(arg_ty.kind(), ty::Param(arg_param) if arg_param.name == sig_param.name); if !is_translatable { - cx.emit_span_lint( - UNTRANSLATABLE_DIAGNOSTIC, - arg_span, - UntranslatableDiag, - ); + cx.emit_lint(UNTRANSLATABLE_DIAGNOSTIC, UntranslatableDiag { + span: arg_span, + }); } } } @@ -580,7 +576,7 @@ impl Diagnostics { } debug!(?is_inside_appropriate_impl); if !is_inside_appropriate_impl { - cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl); + cx.emit_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, DiagOutOfImpl { span }); } } } @@ -615,7 +611,8 @@ impl LateLintPass<'_> for BadOptAccess { && let Some(lit) = item.lit() && let ast::LitKind::Str(val, _) = lit.kind { - cx.emit_span_lint(BAD_OPT_ACCESS, expr.span, BadOptAccessDiag { + cx.emit_lint(BAD_OPT_ACCESS, BadOptAccessDiag { + span: expr.span, msg: val.as_str(), }); } @@ -638,7 +635,7 @@ impl<'tcx> LateLintPass<'tcx> for SpanUseEqCtxt { expr.kind { if is_span_ctxt_call(cx, lhs) && is_span_ctxt_call(cx, rhs) { - cx.emit_span_lint(SPAN_USE_EQ_CTXT, expr.span, SpanUseEqCtxtDiag); + cx.emit_lint(SPAN_USE_EQ_CTXT, SpanUseEqCtxtDiag { span: expr.span }); } } } diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs index 0081374922e6c..5e36b1283a4b1 100644 --- a/compiler/rustc_lint/src/invalid_from_utf8.rs +++ b/compiler/rustc_lint/src/invalid_from_utf8.rs @@ -79,17 +79,21 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 { let valid_up_to = utf8_error.valid_up_to(); let is_unchecked_variant = diag_item.as_str().contains("unchecked"); - cx.emit_span_lint( + cx.emit_lint( if is_unchecked_variant { INVALID_FROM_UTF8_UNCHECKED } else { INVALID_FROM_UTF8 }, - expr.span, if is_unchecked_variant { - InvalidFromUtf8Diag::Unchecked { method, valid_up_to, label } + InvalidFromUtf8Diag::Unchecked { + span: expr.span, + method, + valid_up_to, + label, + } } else { - InvalidFromUtf8Diag::Checked { method, valid_up_to, label } + InvalidFromUtf8Diag::Checked { span: expr.span, method, valid_up_to, label } }, ) }; diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index abee9ee786993..4f8c0b3f61f51 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -1,4 +1,3 @@ -use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_middle::ty; use rustc_session::{declare_lint, declare_lint_pass}; @@ -155,14 +154,13 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { is_assign_desugar: matches!(local.source, rustc_hir::LocalSource::AssignDesugar(_)), }; if is_sync_lock { - let span = MultiSpan::from_span(pat.span); - cx.emit_span_lint(LET_UNDERSCORE_LOCK, span, NonBindingLet::SyncLock { + cx.emit_lint(LET_UNDERSCORE_LOCK, NonBindingLet::SyncLock { span: pat.span, sub }); + } else if can_use_init.is_some() { + // Only emit let_underscore_drop for top-level `_` patterns. + cx.emit_lint(LET_UNDERSCORE_DROP, NonBindingLet::DropType { + span: local.span, sub, - pat: pat.span, }); - // Only emit let_underscore_drop for top-level `_` patterns. - } else if can_use_init.is_some() { - cx.emit_span_lint(LET_UNDERSCORE_DROP, local.span, NonBindingLet::DropType { sub }); } }); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index ff2ae69e1db81..e962819d22f20 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -534,16 +534,12 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { sub, }); } else { - self.emit_span_lint( - FORBIDDEN_LINT_GROUPS, - src.span().into(), - OverruledAttributeLint { - overruled: src.span(), - lint_level: level.as_str(), - lint_source: src.name(), - sub, - }, - ); + self.emit_lint(FORBIDDEN_LINT_GROUPS, OverruledAttributeLint { + span: src.span(), + lint_level: level.as_str(), + lint_source: src.name(), + sub, + }); } // Retain the forbid lint level, unless we are @@ -712,14 +708,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { Symbol::intern(complete_name) } Some(new_lint_name) => { - self.emit_span_lint( + self.emit_lint( builtin::RENAMED_AND_REMOVED_LINTS, - sp.into(), - DeprecatedLintName { - name, - suggestion: sp, - replace: &new_lint_name, - }, + DeprecatedLintName { span: sp, name, replace: &new_lint_name }, ); Symbol::intern(&new_lint_name) } @@ -751,8 +742,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { RenamedLintSuggestion::WithSpan { suggestion: sp, replace }; let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); - let lint = RenamedLint { name: name.as_str(), suggestion }; - self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint); + let lint = RenamedLint { span: sp, name: name.as_str(), suggestion }; + self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint); } // If this lint was renamed, apply the new lint instead of ignoring the @@ -773,8 +764,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { if self.lint_added_lints { let name = tool_ident.map(|tool| format!("{tool}::{name}")).unwrap_or(name); - let lint = RemovedLint { name: name.as_str(), reason }; - self.emit_span_lint(RENAMED_AND_REMOVED_LINTS, sp.into(), lint); + let lint = RemovedLint { span: sp, name: name.as_str(), reason }; + self.emit_lint(RENAMED_AND_REMOVED_LINTS, lint); } continue; } @@ -790,8 +781,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { from_rustc, } }); - let lint = UnknownLint { name, suggestion }; - self.emit_span_lint(UNKNOWN_LINTS, sp.into(), lint); + let lint = UnknownLint { span: sp, name, suggestion }; + self.emit_lint(UNKNOWN_LINTS, lint); } continue; } @@ -841,11 +832,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { continue; }; - self.emit_span_lint( - UNUSED_ATTRIBUTES, - lint_attr_span.into(), - IgnoredUnlessCrateSpecified { level: level.as_str(), name: lint_attr_name }, - ); + self.emit_lint(UNUSED_ATTRIBUTES, IgnoredUnlessCrateSpecified { + span: lint_attr_span, + level: level.as_str(), + name: lint_attr_name, + }); // don't set a separate error for every lint in the group break; } @@ -911,23 +902,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { lint_level(self.sess, lint, level, src, span, decorate) } - #[track_caller] - pub fn emit_span_lint( - &self, - lint: &'static Lint, - span: MultiSpan, - decorate: impl for<'a> LintDiagnostic<'a, ()>, - ) { - let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, Some(span), |lint| { - decorate.decorate_lint(lint); - }); - } - #[track_caller] pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> LintDiagnostic<'a, ()>) { let (level, src) = self.lint_level(lint); - lint_level(self.sess, lint, level, src, None, |lint| { + lint_level(self.sess, lint, level, src, decorate.span(), |lint| { decorate.decorate_lint(lint); }); } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 16cfae17d4020..176a4700bc6e4 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] use std::num::NonZero; @@ -27,10 +28,11 @@ use crate::{LateContext, fluent_generated as fluent}; #[derive(LintDiagnostic)] #[diag(lint_shadowed_into_iter)] pub(crate) struct ShadowedIntoIterDiag { + #[primary_span] + #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")] + pub span: Span, pub target: &'static str, pub edition: &'static str, - #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")] - pub suggestion: Span, #[subdiagnostic] pub sub: Option, } @@ -58,79 +60,138 @@ pub(crate) enum ShadowedIntoIterDiagSub { #[derive(LintDiagnostic)] #[diag(lint_builtin_while_true)] pub(crate) struct BuiltinWhileTrue { + #[primary_span] #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] - pub suggestion: Span, + pub span: Span, pub replace: String, } #[derive(LintDiagnostic)] #[diag(lint_builtin_non_shorthand_field_patterns)] pub(crate) struct BuiltinNonShorthandFieldPatterns { - pub ident: Ident, + #[primary_span] #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")] - pub suggestion: Span, + pub span: Span, + pub ident: Ident, pub prefix: &'static str, } #[derive(LintDiagnostic)] pub(crate) enum BuiltinUnsafe { #[diag(lint_builtin_allow_internal_unsafe)] - AllowInternalUnsafe, + AllowInternalUnsafe { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_unsafe_block)] - UnsafeBlock, + UnsafeBlock { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_unsafe_extern_block)] - UnsafeExternBlock, + UnsafeExternBlock { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_unsafe_trait)] - UnsafeTrait, + UnsafeTrait { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_unsafe_impl)] - UnsafeImpl, + UnsafeImpl { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_no_mangle_fn)] #[note(lint_builtin_overridden_symbol_name)] - NoMangleFn, + NoMangleFn { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_export_name_fn)] #[note(lint_builtin_overridden_symbol_name)] - ExportNameFn, + ExportNameFn { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_link_section_fn)] #[note(lint_builtin_overridden_symbol_section)] - LinkSectionFn, + LinkSectionFn { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_no_mangle_static)] #[note(lint_builtin_overridden_symbol_name)] - NoMangleStatic, + NoMangleStatic { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_export_name_static)] #[note(lint_builtin_overridden_symbol_name)] - ExportNameStatic, + ExportNameStatic { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_link_section_static)] #[note(lint_builtin_overridden_symbol_section)] - LinkSectionStatic, + LinkSectionStatic { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_no_mangle_method)] #[note(lint_builtin_overridden_symbol_name)] - NoMangleMethod, + NoMangleMethod { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_export_name_method)] #[note(lint_builtin_overridden_symbol_name)] - ExportNameMethod, + ExportNameMethod { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_decl_unsafe_fn)] - DeclUnsafeFn, + DeclUnsafeFn { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_decl_unsafe_method)] - DeclUnsafeMethod, + DeclUnsafeMethod { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_impl_unsafe_method)] - ImplUnsafeMethod, + ImplUnsafeMethod { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_global_asm)] #[note(lint_builtin_global_macro_unsafety)] - GlobalAsm, + GlobalAsm { + #[primary_span] + span: Span, + }, } #[derive(LintDiagnostic)] #[diag(lint_builtin_missing_doc)] pub(crate) struct BuiltinMissingDoc<'a> { + #[primary_span] + pub span: Span, pub article: &'a str, pub desc: &'a str, } #[derive(LintDiagnostic)] #[diag(lint_builtin_missing_copy_impl)] -pub(crate) struct BuiltinMissingCopyImpl; +pub(crate) struct BuiltinMissingCopyImpl { + #[primary_span] + pub span: Span, +} pub(crate) struct BuiltinMissingDebugImpl<'a> { + pub span: Span, pub tcx: TyCtxt<'a>, pub def_id: DefId, } @@ -141,11 +202,17 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> { diag.primary_message(fluent::lint_builtin_missing_debug_impl); diag.arg("debug", self.tcx.def_path_str(self.def_id)); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(LintDiagnostic)] #[diag(lint_builtin_anonymous_params)] pub(crate) struct BuiltinAnonymousParams<'a> { + #[primary_span] + pub span: Span, #[suggestion(code = "_: {ty_snip}")] pub suggestion: (Span, Applicability), pub ty_snip: &'a str, @@ -155,6 +222,8 @@ pub(crate) struct BuiltinAnonymousParams<'a> { #[derive(LintDiagnostic)] #[diag(lint_builtin_deprecated_attr_link)] pub(crate) struct BuiltinDeprecatedAttrLink<'a> { + #[primary_span] + pub span: Span, pub name: Symbol, pub reason: &'a str, pub link: &'a str, @@ -180,19 +249,22 @@ pub(crate) enum BuiltinDeprecatedAttrLinkSuggestion<'a> { #[derive(LintDiagnostic)] #[diag(lint_builtin_deprecated_attr_used)] pub(crate) struct BuiltinDeprecatedAttrUsed { - pub name: String, + #[primary_span] #[suggestion( lint_builtin_deprecated_attr_default_suggestion, style = "short", code = "", applicability = "machine-applicable" )] - pub suggestion: Span, + pub span: Span, + pub name: String, } #[derive(LintDiagnostic)] #[diag(lint_builtin_unused_doc_comment)] pub(crate) struct BuiltinUnusedDocComment<'a> { + #[primary_span] + pub span: Span, pub kind: &'a str, #[label] pub label: Span, @@ -211,6 +283,8 @@ pub(crate) enum BuiltinUnusedDocCommentSub { #[derive(LintDiagnostic)] #[diag(lint_builtin_no_mangle_generic)] pub(crate) struct BuiltinNoMangleGeneric { + #[primary_span] + pub span: Span, // Use of `#[no_mangle]` suggests FFI intent; correct // fix may be to monomorphize source by hand #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")] @@ -220,20 +294,29 @@ pub(crate) struct BuiltinNoMangleGeneric { #[derive(LintDiagnostic)] #[diag(lint_builtin_const_no_mangle)] pub(crate) struct BuiltinConstNoMangle { + #[primary_span] + pub span: Span, #[suggestion(code = "pub static", applicability = "machine-applicable")] pub suggestion: Span, } #[derive(LintDiagnostic)] #[diag(lint_builtin_mutable_transmutes)] -pub(crate) struct BuiltinMutablesTransmutes; +pub(crate) struct BuiltinMutablesTransmutes { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_builtin_unstable_features)] -pub(crate) struct BuiltinUnstableFeatures; +pub(crate) struct BuiltinUnstableFeatures { + #[primary_span] + pub span: Span, +} // lint_ungated_async_fn_track_caller pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> { + pub span: Span, pub label: Span, pub session: &'a Session, } @@ -248,11 +331,17 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { sym::async_fn_track_caller, ); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(LintDiagnostic)] #[diag(lint_builtin_unreachable_pub)] pub(crate) struct BuiltinUnreachablePub<'a> { + #[primary_span] + pub span: Span, pub what: &'a str, #[suggestion(code = "pub(crate)")] pub suggestion: (Span, Applicability), @@ -263,13 +352,14 @@ pub(crate) struct BuiltinUnreachablePub<'a> { #[derive(LintDiagnostic)] #[diag(lint_macro_expr_fragment_specifier_2024_migration)] pub(crate) struct MacroExprFragment2024 { + #[primary_span] #[suggestion(code = "expr_2021", applicability = "machine-applicable")] - pub suggestion: Span, + pub span: Span, } pub(crate) struct BuiltinTypeAliasBounds<'hir> { + pub spans: Vec, pub in_where_clause: bool, - pub label: Span, pub enable_feat_help: bool, pub suggestions: Vec<(Span, String)>, pub preds: &'hir [hir::WherePredicate<'hir>], @@ -283,7 +373,9 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { } else { fluent::lint_builtin_type_alias_bounds_param_bounds }); - diag.span_label(self.label, fluent::lint_builtin_type_alias_bounds_label); + if let Some(&span) = self.spans.last() { + diag.span_label(span, fluent::lint_builtin_type_alias_bounds_label); + } diag.note(fluent::lint_builtin_type_alias_bounds_limitation_note); if self.enable_feat_help { diag.help(fluent::lint_builtin_type_alias_bounds_enable_feat_help); @@ -334,11 +426,17 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { ); } } + + fn span(&self) -> Option { + Some(self.spans.clone().into()) + } } #[derive(LintDiagnostic)] #[diag(lint_builtin_trivial_bounds)] pub(crate) struct BuiltinTrivialBounds<'a> { + #[primary_span] + pub span: Span, pub predicate_kind_name: &'a str, pub predicate: Clause<'a>, } @@ -347,30 +445,35 @@ pub(crate) struct BuiltinTrivialBounds<'a> { pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint { #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] Parenthesise { + #[primary_span] #[suggestion(code = "{replace}", applicability = "machine-applicable")] - suggestion: Span, + span: Span, replace: String, }, #[diag(lint_builtin_ellipsis_inclusive_range_patterns)] NonParenthesise { + #[primary_span] #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")] - suggestion: Span, + span: Span, }, } #[derive(LintDiagnostic)] #[diag(lint_builtin_keyword_idents)] pub(crate) struct BuiltinKeywordIdents { + #[primary_span] + #[suggestion(code = "{prefix}r#{kw}", applicability = "machine-applicable")] + pub span: Span, pub kw: Ident, pub next: Edition, - #[suggestion(code = "{prefix}r#{kw}", applicability = "machine-applicable")] - pub suggestion: Span, pub prefix: &'static str, } #[derive(LintDiagnostic)] #[diag(lint_builtin_explicit_outlives)] pub(crate) struct BuiltinExplicitOutlives { + #[primary_span] + pub spans: Vec, pub count: usize, #[subdiagnostic] pub suggestion: BuiltinExplicitOutlivesSuggestion, @@ -388,6 +491,8 @@ pub(crate) struct BuiltinExplicitOutlivesSuggestion { #[derive(LintDiagnostic)] #[diag(lint_builtin_incomplete_features)] pub(crate) struct BuiltinIncompleteFeatures { + #[primary_span] + pub span: Span, pub name: Symbol, #[subdiagnostic] pub note: Option, @@ -399,6 +504,8 @@ pub(crate) struct BuiltinIncompleteFeatures { #[diag(lint_builtin_internal_features)] #[note] pub(crate) struct BuiltinInternalFeatures { + #[primary_span] + pub span: Span, pub name: Symbol, } @@ -413,9 +520,9 @@ pub(crate) struct BuiltinFeatureIssueNote { } pub(crate) struct BuiltinUnpermittedTypeInit<'a> { + pub span: Span, pub msg: DiagMessage, pub ty: Ty<'a>, - pub label: Span, pub sub: BuiltinUnpermittedTypeInitSub, pub tcx: TyCtxt<'a>, } @@ -424,16 +531,17 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.primary_message(self.msg); diag.arg("ty", self.ty); - diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); + diag.span_label(self.span, fluent::lint_builtin_unpermitted_type_init_label); if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited. - diag.span_label( - self.label, - fluent::lint_builtin_unpermitted_type_init_label_suggestion, - ); + diag.span_label(self.span, fluent::lint_builtin_unpermitted_type_init_label_suggestion); } self.sub.add_to_diag(diag); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } // FIXME(davidtwco): make translatable @@ -467,23 +575,25 @@ impl Subdiagnostic for BuiltinUnpermittedTypeInitSub { pub(crate) enum BuiltinClashingExtern<'a> { #[diag(lint_builtin_clashing_extern_same_name)] SameName { + #[primary_span] + #[label(lint_mismatch_label)] + span: Span, this: Symbol, orig: Symbol, #[label(lint_previous_decl_label)] previous_decl_label: Span, - #[label(lint_mismatch_label)] - mismatch_label: Span, #[subdiagnostic] sub: BuiltinClashingExternSub<'a>, }, #[diag(lint_builtin_clashing_extern_diff_name)] DiffName { + #[primary_span] + #[label(lint_mismatch_label)] + span: Span, this: Symbol, orig: Symbol, #[label(lint_previous_decl_label)] previous_decl_label: Span, - #[label(lint_mismatch_label)] - mismatch_label: Span, #[subdiagnostic] sub: BuiltinClashingExternSub<'a>, }, @@ -513,8 +623,9 @@ impl Subdiagnostic for BuiltinClashingExternSub<'_> { #[derive(LintDiagnostic)] #[diag(lint_builtin_deref_nullptr)] pub(crate) struct BuiltinDerefNullptr { + #[primary_span] #[label] - pub label: Span, + pub span: Span, } // FIXME: migrate fluent::lint::builtin_asm_labels @@ -524,21 +635,28 @@ pub(crate) enum BuiltinSpecialModuleNameUsed { #[diag(lint_builtin_special_module_name_used_lib)] #[note] #[help] - Lib, + Lib { + #[primary_span] + span: Span, + }, #[diag(lint_builtin_special_module_name_used_main)] #[note] - Main, + Main { + #[primary_span] + span: Span, + }, } // deref_into_dyn_supertrait.rs #[derive(LintDiagnostic)] #[diag(lint_supertrait_as_deref_target)] pub(crate) struct SupertraitAsDerefTarget<'a> { + #[primary_span] + #[label] + pub span: Span, pub self_ty: Ty<'a>, pub supertrait_principal: PolyExistentialTraitRef<'a>, pub target_principal: PolyExistentialTraitRef<'a>, - #[label] - pub label: Span, #[subdiagnostic] pub label2: Option, } @@ -554,6 +672,8 @@ pub(crate) struct SupertraitAsDerefTargetLabel { #[derive(LintDiagnostic)] #[diag(lint_enum_intrinsics_mem_discriminant)] pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> { + #[primary_span] + pub span: Span, pub ty_param: Ty<'a>, #[note] pub note: Span, @@ -563,6 +683,8 @@ pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> { #[diag(lint_enum_intrinsics_mem_variant)] #[note] pub(crate) struct EnumIntrinsicsMemVariant<'a> { + #[primary_span] + pub span: Span, pub ty_param: Ty<'a>, } @@ -570,6 +692,8 @@ pub(crate) struct EnumIntrinsicsMemVariant<'a> { #[derive(LintDiagnostic)] #[diag(lint_expectation)] pub(crate) struct Expectation { + #[primary_span] + pub span: Span, #[subdiagnostic] pub rationale: Option, #[note] @@ -588,24 +712,34 @@ pub(crate) enum PtrNullChecksDiag<'a> { #[diag(lint_ptr_null_checks_fn_ptr)] #[help(lint_help)] FnPtr { + #[primary_span] + span: Span, orig_ty: Ty<'a>, #[label] label: Span, }, #[diag(lint_ptr_null_checks_ref)] Ref { + #[primary_span] + span: Span, orig_ty: Ty<'a>, #[label] label: Span, }, #[diag(lint_ptr_null_checks_fn_ret)] - FnRet { fn_name: Ident }, + FnRet { + #[primary_span] + span: Span, + fn_name: Ident, + }, } // for_loops_over_fallibles.rs #[derive(LintDiagnostic)] #[diag(lint_for_loops_over_fallibles)] pub(crate) struct ForLoopsOverFalliblesDiag<'a> { + #[primary_span] + pub span: Span, pub article: &'static str, pub ref_prefix: &'static str, pub ty: &'static str, @@ -673,6 +807,8 @@ pub(crate) enum UseLetUnderscoreIgnoreSuggestion { #[derive(LintDiagnostic)] #[diag(lint_dropping_references)] pub(crate) struct DropRefDiag<'a> { + #[primary_span] + pub span: Span, pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -683,6 +819,8 @@ pub(crate) struct DropRefDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_dropping_copy_types)] pub(crate) struct DropCopyDiag<'a> { + #[primary_span] + pub span: Span, pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -693,6 +831,8 @@ pub(crate) struct DropCopyDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_forgetting_references)] pub(crate) struct ForgetRefDiag<'a> { + #[primary_span] + pub span: Span, pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -703,6 +843,8 @@ pub(crate) struct ForgetRefDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_forgetting_copy_types)] pub(crate) struct ForgetCopyDiag<'a> { + #[primary_span] + pub span: Span, pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -713,6 +855,8 @@ pub(crate) struct ForgetCopyDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_undropped_manually_drops)] pub(crate) struct UndroppedManuallyDropsDiag<'a> { + #[primary_span] + pub span: Span, pub arg_ty: Ty<'a>, #[label] pub label: Span, @@ -734,6 +878,8 @@ pub(crate) struct UndroppedManuallyDropsSuggestion { pub(crate) enum InvalidFromUtf8Diag { #[diag(lint_invalid_from_utf8_unchecked)] Unchecked { + #[primary_span] + span: Span, method: String, valid_up_to: usize, #[label] @@ -741,6 +887,8 @@ pub(crate) enum InvalidFromUtf8Diag { }, #[diag(lint_invalid_from_utf8_checked)] Checked { + #[primary_span] + span: Span, method: String, valid_up_to: usize, #[label] @@ -754,6 +902,8 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { #[diag(lint_invalid_reference_casting_borrow_as_mut)] #[note(lint_invalid_reference_casting_note_book)] BorrowAsMut { + #[primary_span] + span: Span, #[label] orig_cast: Option, #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] @@ -762,6 +912,8 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { #[diag(lint_invalid_reference_casting_assign_to_ref)] #[note(lint_invalid_reference_casting_note_book)] AssignToRef { + #[primary_span] + span: Span, #[label] orig_cast: Option, #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)] @@ -770,6 +922,8 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { #[diag(lint_invalid_reference_casting_bigger_layout)] #[note(lint_layout)] BiggerLayout { + #[primary_span] + span: Span, #[label] orig_cast: Option, #[label(lint_alloc)] @@ -786,10 +940,11 @@ pub(crate) enum InvalidReferenceCastingDiag<'tcx> { #[diag(lint_hidden_unicode_codepoints)] #[note] pub(crate) struct HiddenUnicodeCodepointsDiag<'a> { + #[primary_span] + #[label] + pub span: Span, pub label: &'a str, pub count: usize, - #[label] - pub span_label: Span, #[subdiagnostic] pub labels: Option, #[subdiagnostic] @@ -868,6 +1023,8 @@ impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub { #[diag(lint_map_unit_fn)] #[note] pub(crate) struct MappingToUnit { + #[primary_span] + pub span: Span, #[label(lint_function_label)] pub function_label: Span, #[label(lint_argument_label)] @@ -884,6 +1041,8 @@ pub(crate) struct MappingToUnit { #[diag(lint_default_hash_types)] #[note] pub(crate) struct DefaultHashTypesDiag<'a> { + #[primary_span] + pub span: Span, pub preferred: &'a str, pub used: Symbol, } @@ -892,6 +1051,8 @@ pub(crate) struct DefaultHashTypesDiag<'a> { #[diag(lint_query_instability)] #[note] pub(crate) struct QueryInstability { + #[primary_span] + pub span: Span, pub query: Symbol, } @@ -899,16 +1060,23 @@ pub(crate) struct QueryInstability { #[diag(lint_query_untracked)] #[note] pub(crate) struct QueryUntracked { + #[primary_span] + pub span: Span, pub method: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_span_use_eq_ctxt)] -pub(crate) struct SpanUseEqCtxtDiag; +pub(crate) struct SpanUseEqCtxtDiag { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_tykind_kind)] pub(crate) struct TykindKind { + #[primary_span] + pub span: Span, #[suggestion(code = "ty", applicability = "maybe-incorrect")] pub suggestion: Span, } @@ -916,24 +1084,33 @@ pub(crate) struct TykindKind { #[derive(LintDiagnostic)] #[diag(lint_tykind)] #[help] -pub(crate) struct TykindDiag; +pub(crate) struct TykindDiag { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_ty_qualified)] pub(crate) struct TyQualified { - pub ty: String, + #[primary_span] #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] - pub suggestion: Span, + pub span: Span, + pub ty: String, } #[derive(LintDiagnostic)] #[diag(lint_type_ir_inherent_usage)] #[note] -pub(crate) struct TypeIrInherentUsage; +pub(crate) struct TypeIrInherentUsage { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_non_glob_import_type_ir_inherent)] pub(crate) struct NonGlobImportTypeIrInherent { + #[primary_span] + pub span: Span, #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")] pub suggestion: Option, pub snippet: &'static str, @@ -942,26 +1119,39 @@ pub(crate) struct NonGlobImportTypeIrInherent { #[derive(LintDiagnostic)] #[diag(lint_lintpass_by_hand)] #[help] -pub(crate) struct LintPassByHand; +pub(crate) struct LintPassByHand { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_non_existent_doc_keyword)] #[help] pub(crate) struct NonExistentDocKeyword { + #[primary_span] + pub span: Span, pub keyword: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_diag_out_of_impl)] -pub(crate) struct DiagOutOfImpl; +pub(crate) struct DiagOutOfImpl { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_untranslatable_diag)] -pub(crate) struct UntranslatableDiag; +pub(crate) struct UntranslatableDiag { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_bad_opt_access)] pub(crate) struct BadOptAccessDiag<'a> { + #[primary_span] + pub span: Span, pub msg: &'a str, } @@ -970,13 +1160,16 @@ pub(crate) struct BadOptAccessDiag<'a> { pub(crate) enum NonBindingLet { #[diag(lint_non_binding_let_on_sync_lock)] SyncLock { + #[primary_span] #[label] - pat: Span, + span: Span, #[subdiagnostic] sub: NonBindingLetSub, }, #[diag(lint_non_binding_let_on_drop_type)] DropType { + #[primary_span] + span: Span, #[subdiagnostic] sub: NonBindingLetSub, }, @@ -1026,8 +1219,9 @@ impl Subdiagnostic for NonBindingLetSub { #[derive(LintDiagnostic)] #[diag(lint_overruled_attribute)] pub(crate) struct OverruledAttributeLint<'a> { + #[primary_span] #[label] - pub overruled: Span, + pub span: Span, pub lint_level: &'a str, pub lint_source: Symbol, #[subdiagnostic] @@ -1037,9 +1231,10 @@ pub(crate) struct OverruledAttributeLint<'a> { #[derive(LintDiagnostic)] #[diag(lint_deprecated_lint_name)] pub(crate) struct DeprecatedLintName<'a> { - pub name: String, + #[primary_span] #[suggestion(code = "{replace}", applicability = "machine-applicable")] - pub suggestion: Span, + pub span: Span, + pub name: String, pub replace: &'a str, } @@ -1056,6 +1251,8 @@ pub(crate) struct DeprecatedLintNameFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_renamed_lint)] pub(crate) struct RenamedLint<'a> { + #[primary_span] + pub span: Span, pub name: &'a str, #[subdiagnostic] pub suggestion: RenamedLintSuggestion<'a>, @@ -1086,6 +1283,8 @@ pub(crate) struct RenamedLintFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_removed_lint)] pub(crate) struct RemovedLint<'a> { + #[primary_span] + pub span: Span, pub name: &'a str, pub reason: &'a str, } @@ -1102,6 +1301,8 @@ pub(crate) struct RemovedLintFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_unknown_lint)] pub(crate) struct UnknownLint { + #[primary_span] + pub span: Span, pub name: String, #[subdiagnostic] pub suggestion: Option, @@ -1133,6 +1334,8 @@ pub(crate) struct UnknownLintFromCommandLine<'a> { #[derive(LintDiagnostic)] #[diag(lint_ignored_unless_crate_specified)] pub(crate) struct IgnoredUnlessCrateSpecified<'a> { + #[primary_span] + pub span: Span, pub level: &'a str, pub name: Symbol, } @@ -1143,8 +1346,9 @@ pub(crate) struct IgnoredUnlessCrateSpecified<'a> { #[note] #[help] pub(crate) struct CStringPtr { + #[primary_span] #[label(lint_as_ptr_label)] - pub as_ptr: Span, + pub span: Span, #[label(lint_unwrap_label)] pub unwrap: Span, } @@ -1153,18 +1357,25 @@ pub(crate) struct CStringPtr { #[derive(LintDiagnostic)] #[diag(lint_multiple_supertrait_upcastable)] pub(crate) struct MultipleSupertraitUpcastable { + #[primary_span] + pub span: Span, pub ident: Ident, } // non_ascii_idents.rs #[derive(LintDiagnostic)] #[diag(lint_identifier_non_ascii_char)] -pub(crate) struct IdentifierNonAsciiChar; +pub(crate) struct IdentifierNonAsciiChar { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_identifier_uncommon_codepoints)] #[note] pub(crate) struct IdentifierUncommonCodepoints { + #[primary_span] + pub span: Span, pub codepoints: Vec, pub codepoints_len: usize, pub identifier_type: &'static str, @@ -1173,12 +1384,13 @@ pub(crate) struct IdentifierUncommonCodepoints { #[derive(LintDiagnostic)] #[diag(lint_confusable_identifier_pair)] pub(crate) struct ConfusableIdentifierPair { + #[primary_span] + #[label(lint_current_use)] + pub span: Span, pub existing_sym: Symbol, pub sym: Symbol, #[label(lint_other_use)] pub label: Span, - #[label(lint_current_use)] - pub main_label: Span, } #[derive(LintDiagnostic)] @@ -1186,12 +1398,15 @@ pub(crate) struct ConfusableIdentifierPair { #[note(lint_includes_note)] #[note] pub(crate) struct MixedScriptConfusables { + #[primary_span] + pub span: Span, pub set: String, pub includes: String, } // non_fmt_panic.rs pub(crate) struct NonFmtPanicUnused { + pub spans: Vec, pub count: usize, pub suggestion: Option, } @@ -1217,12 +1432,18 @@ impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused { ); } } + + fn span(&self) -> Option { + Some(self.spans.clone().into()) + } } #[derive(LintDiagnostic)] #[diag(lint_non_fmt_panic_braces)] #[note] pub(crate) struct NonFmtPanicBraces { + #[primary_span] + pub spans: Vec, pub count: usize, #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")] pub suggestion: Option, @@ -1232,6 +1453,8 @@ pub(crate) struct NonFmtPanicBraces { #[derive(LintDiagnostic)] #[diag(lint_non_camel_case_type)] pub(crate) struct NonCamelCaseType<'a> { + #[primary_span] + pub span: Span, pub sort: &'a str, pub name: &'a str, #[subdiagnostic] @@ -1256,6 +1479,8 @@ pub(crate) enum NonCamelCaseTypeSub { #[derive(LintDiagnostic)] #[diag(lint_non_snake_case)] pub(crate) struct NonSnakeCaseDiag<'a> { + #[primary_span] + pub span: Span, pub sort: &'a str, pub name: &'a str, pub sc: String, @@ -1316,6 +1541,8 @@ impl Subdiagnostic for NonSnakeCaseDiagSub { #[derive(LintDiagnostic)] #[diag(lint_non_upper_case_global)] pub(crate) struct NonUpperCaseGlobal<'a> { + #[primary_span] + pub span: Span, pub sort: &'a str, pub name: &'a str, #[subdiagnostic] @@ -1342,11 +1569,12 @@ pub(crate) enum NonUpperCaseGlobalSub { #[diag(lint_noop_method_call)] #[note] pub(crate) struct NoopMethodCallDiag<'a> { + #[primary_span] + #[suggestion(code = "", applicability = "machine-applicable")] + pub span: Span, pub method: Symbol, pub orig_ty: Ty<'a>, pub trait_: Symbol, - #[suggestion(code = "", applicability = "machine-applicable")] - pub label: Span, #[suggestion( lint_derive_suggestion, code = "#[derive(Clone)]\n", @@ -1358,18 +1586,23 @@ pub(crate) struct NoopMethodCallDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_suspicious_double_ref_deref)] pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> { + #[primary_span] + pub span: Span, pub ty: Ty<'a>, } #[derive(LintDiagnostic)] #[diag(lint_suspicious_double_ref_clone)] pub(crate) struct SuspiciousDoubleRefCloneDiag<'a> { + #[primary_span] + pub span: Span, pub ty: Ty<'a>, } // non_local_defs.rs pub(crate) enum NonLocalDefinitionsDiag { Impl { + span: MultiSpan, depth: u32, body_kind_descr: &'static str, body_name: String, @@ -1379,6 +1612,7 @@ pub(crate) enum NonLocalDefinitionsDiag { macro_to_change: Option<(String, &'static str)>, }, MacroRules { + span: Span, depth: u32, body_kind_descr: &'static str, body_name: String, @@ -1391,6 +1625,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { match self { NonLocalDefinitionsDiag::Impl { + span: _, depth, body_kind_descr, body_name, @@ -1432,6 +1667,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { } } NonLocalDefinitionsDiag::MacroRules { + span: _, depth, body_kind_descr, body_name, @@ -1457,6 +1693,13 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { } } } + + fn span(&self) -> Option { + match self { + Self::Impl { span, .. } => Some(span.clone().into()), + &Self::MacroRules { span, .. } => Some(span.into()), + } + } } #[derive(Subdiagnostic)] @@ -1472,6 +1715,8 @@ pub(crate) struct NonLocalDefinitionsCargoUpdateNote { #[diag(lint_ambiguous_negative_literals)] #[note(lint_example)] pub(crate) struct AmbiguousNegativeLiteralsDiag { + #[primary_span] + pub span: Span, #[subdiagnostic] pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion, #[subdiagnostic] @@ -1500,22 +1745,25 @@ pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { #[derive(LintDiagnostic)] #[diag(lint_pass_by_value)] pub(crate) struct PassByValueDiag { - pub ty: String, + #[primary_span] #[suggestion(code = "{ty}", applicability = "maybe-incorrect")] - pub suggestion: Span, + pub span: Span, + pub ty: String, } // redundant_semicolon.rs #[derive(LintDiagnostic)] #[diag(lint_redundant_semicolons)] pub(crate) struct RedundantSemicolonsDiag { - pub multiple: bool, + #[primary_span] #[suggestion(code = "", applicability = "maybe-incorrect")] - pub suggestion: Span, + pub span: Span, + pub multiple: bool, } // traits.rs pub(crate) struct DropTraitConstraintsDiag<'a> { + pub span: Span, pub predicate: Clause<'a>, pub tcx: TyCtxt<'a>, pub def_id: DefId, @@ -1528,9 +1776,14 @@ impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> { diag.arg("predicate", self.predicate); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } pub(crate) struct DropGlue<'a> { + pub span: Span, pub tcx: TyCtxt<'a>, pub def_id: DefId, } @@ -1541,12 +1794,18 @@ impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> { diag.primary_message(fluent::lint_drop_glue); diag.arg("needs_drop", self.tcx.def_path_str(self.def_id)); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } // types.rs #[derive(LintDiagnostic)] #[diag(lint_range_endpoint_out_of_range)] pub(crate) struct RangeEndpointOutOfRange<'a> { + #[primary_span] + pub span: Span, pub ty: &'a str, #[subdiagnostic] pub sub: UseInclusiveRange<'a>, @@ -1580,6 +1839,8 @@ pub(crate) enum UseInclusiveRange<'a> { #[derive(LintDiagnostic)] #[diag(lint_overflowing_bin_hex)] pub(crate) struct OverflowingBinHex<'a> { + #[primary_span] + pub span: Span, pub ty: &'a str, pub lit: String, pub dec: u128, @@ -1651,6 +1912,8 @@ pub(crate) struct OverflowingBinHexSignBitSub<'a> { #[diag(lint_overflowing_int)] #[note] pub(crate) struct OverflowingInt<'a> { + #[primary_span] + pub span: Span, pub ty: &'a str, pub lit: String, pub min: i128, @@ -1668,6 +1931,7 @@ pub(crate) struct OverflowingIntHelp<'a> { #[derive(LintDiagnostic)] #[diag(lint_only_cast_u8_to_char)] pub(crate) struct OnlyCastu8ToChar { + #[primary_span] #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")] pub span: Span, pub literal: u128, @@ -1677,6 +1941,8 @@ pub(crate) struct OnlyCastu8ToChar { #[diag(lint_overflowing_uint)] #[note] pub(crate) struct OverflowingUInt<'a> { + #[primary_span] + pub span: Span, pub ty: &'a str, pub lit: String, pub min: u128, @@ -1687,23 +1953,33 @@ pub(crate) struct OverflowingUInt<'a> { #[diag(lint_overflowing_literal)] #[note] pub(crate) struct OverflowingLiteral<'a> { + #[primary_span] + pub span: Span, pub ty: &'a str, pub lit: String, } #[derive(LintDiagnostic)] #[diag(lint_unused_comparisons)] -pub(crate) struct UnusedComparisons; +pub(crate) struct UnusedComparisons { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] pub(crate) enum InvalidNanComparisons { #[diag(lint_invalid_nan_comparisons_eq_ne)] EqNe { + #[primary_span] + span: Span, #[subdiagnostic] suggestion: InvalidNanComparisonsSuggestion, }, #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)] - LtLeGtGe, + LtLeGtGe { + #[primary_span] + span: Span, + }, } #[derive(Subdiagnostic)] @@ -1729,6 +2005,8 @@ pub(crate) enum InvalidNanComparisonsSuggestion { pub(crate) enum AmbiguousWidePointerComparisons<'a> { #[diag(lint_ambiguous_wide_pointer_comparisons)] Spanful { + #[primary_span] + span: Span, #[subdiagnostic] addr_suggestion: AmbiguousWidePointerComparisonsAddrSuggestion<'a>, #[subdiagnostic] @@ -1737,7 +2015,10 @@ pub(crate) enum AmbiguousWidePointerComparisons<'a> { #[diag(lint_ambiguous_wide_pointer_comparisons)] #[help(lint_addr_metadata_suggestion)] #[help(lint_addr_suggestion)] - Spanless, + Spanless { + #[primary_span] + span: Span, + }, } #[derive(Subdiagnostic)] @@ -1807,9 +2088,9 @@ pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> { } pub(crate) struct ImproperCTypes<'a> { + pub span: Span, pub ty: Ty<'a>, pub desc: &'a str, - pub label: Span, pub help: Option, pub note: DiagMessage, pub span_note: Option, @@ -1821,7 +2102,7 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { diag.primary_message(fluent::lint_improper_ctypes); diag.arg("ty", self.ty); diag.arg("desc", self.desc); - diag.span_label(self.label, fluent::lint_label); + diag.span_label(self.span, fluent::lint_label); if let Some(help) = self.help { diag.help(help); } @@ -1830,45 +2111,62 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> { diag.span_note(note, fluent::lint_note); } } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(LintDiagnostic)] #[diag(lint_variant_size_differences)] pub(crate) struct VariantSizeDifferencesDiag { + #[primary_span] + pub span: Span, pub largest: u64, } #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_load)] #[help] -pub(crate) struct AtomicOrderingLoad; +pub(crate) struct AtomicOrderingLoad { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_store)] #[help] -pub(crate) struct AtomicOrderingStore; +pub(crate) struct AtomicOrderingStore { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_fence)] #[help] -pub(crate) struct AtomicOrderingFence; +pub(crate) struct AtomicOrderingFence { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_atomic_ordering_invalid)] #[help] pub(crate) struct InvalidAtomicOrderingDiag { - pub method: Symbol, + #[primary_span] #[label] - pub fail_order_arg_span: Span, + pub span: Span, + pub method: Symbol, } // unused.rs #[derive(LintDiagnostic)] #[diag(lint_unused_op)] pub(crate) struct UnusedOp<'a> { - pub op: &'a str, + #[primary_span] #[label] - pub label: Span, + pub span: Span, + pub op: &'a str, #[subdiagnostic] pub suggestion: UnusedOpSuggestion, } @@ -1897,6 +2195,8 @@ pub(crate) enum UnusedOpSuggestion { #[derive(LintDiagnostic)] #[diag(lint_unused_result)] pub(crate) struct UnusedResult<'a> { + #[primary_span] + pub span: Span, pub ty: Ty<'a>, } @@ -1906,6 +2206,8 @@ pub(crate) struct UnusedResult<'a> { #[diag(lint_unused_closure)] #[note] pub(crate) struct UnusedClosure<'a> { + #[primary_span] + pub span: Span, pub count: usize, pub pre: &'a str, pub post: &'a str, @@ -1917,6 +2219,8 @@ pub(crate) struct UnusedClosure<'a> { #[diag(lint_unused_coroutine)] #[note] pub(crate) struct UnusedCoroutine<'a> { + #[primary_span] + pub span: Span, pub count: usize, pub pre: &'a str, pub post: &'a str, @@ -1925,6 +2229,7 @@ pub(crate) struct UnusedCoroutine<'a> { // FIXME(davidtwco): this isn't properly translatable because of the pre/post // strings pub(crate) struct UnusedDef<'a, 'b> { + pub span: Span, pub pre: &'a str, pub post: &'a str, pub cx: &'a LateContext<'b>, @@ -1934,7 +2239,6 @@ pub(crate) struct UnusedDef<'a, 'b> { } #[derive(Subdiagnostic)] - pub(crate) enum UnusedDefSuggestion { #[suggestion( lint_suggestion, @@ -1970,11 +2274,17 @@ impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> { diag.subdiagnostic(sugg); } } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(LintDiagnostic)] #[diag(lint_path_statement_drop)] pub(crate) struct PathStatementDrop { + #[primary_span] + pub span: Span, #[subdiagnostic] pub sub: PathStatementDropSub, } @@ -1996,11 +2306,16 @@ pub(crate) enum PathStatementDropSub { #[derive(LintDiagnostic)] #[diag(lint_path_statement_no_effect)] -pub(crate) struct PathStatementNoEffect; +pub(crate) struct PathStatementNoEffect { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_unused_delim)] pub(crate) struct UnusedDelim<'a> { + #[primary_span] + pub span: MultiSpan, pub delim: &'static str, pub item: &'a str, #[subdiagnostic] @@ -2021,18 +2336,27 @@ pub(crate) struct UnusedDelimSuggestion { #[derive(LintDiagnostic)] #[diag(lint_unused_import_braces)] pub(crate) struct UnusedImportBracesDiag { + #[primary_span] + pub span: Span, pub node: Symbol, } #[derive(LintDiagnostic)] #[diag(lint_unused_allocation)] -pub(crate) struct UnusedAllocationDiag; +pub(crate) struct UnusedAllocationDiag { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_unused_allocation_mut)] -pub(crate) struct UnusedAllocationMutDiag; +pub(crate) struct UnusedAllocationMutDiag { + #[primary_span] + pub span: Span, +} pub(crate) struct AsyncFnInTraitDiag { + pub span: Span, pub sugg: Option>, } @@ -2044,11 +2368,17 @@ impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag { diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect); } } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(LintDiagnostic)] #[diag(lint_unit_bindings)] pub(crate) struct UnitBindingsDiag { + #[primary_span] + pub span: Span, #[label] pub label: Span, } @@ -2059,6 +2389,8 @@ pub(crate) enum InvalidAsmLabel { #[help] #[note] Named { + #[primary_span] + span: Span, #[note(lint_invalid_asm_label_no_span)] missing_precise_span: bool, }, @@ -2067,6 +2399,8 @@ pub(crate) enum InvalidAsmLabel { #[note(lint_note1)] #[note(lint_note2)] FormatArg { + #[primary_span] + span: Span, #[note(lint_invalid_asm_label_no_span)] missing_precise_span: bool, }, @@ -2075,11 +2409,11 @@ pub(crate) enum InvalidAsmLabel { #[note(lint_note1)] #[note(lint_note2)] Binary { - #[note(lint_invalid_asm_label_no_span)] - missing_precise_span: bool, - // hack to get a label on the whole span, must match the emitted span + #[primary_span] #[label] span: Span, + #[note(lint_invalid_asm_label_no_span)] + missing_precise_span: bool, }, } @@ -2412,6 +2746,11 @@ impl<'a> LintDiagnostic<'a, ()> for UnstableFeature { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.primary_message(self.msg); } + + fn span(&self) -> Option { + // The primary span is to be provided by `BufferedEarlyLint`. + None + } } #[derive(LintDiagnostic)] @@ -2628,6 +2967,11 @@ impl LintDiagnostic<'_, G> for ElidedNamedLifetime { ), }; } + + fn span(&self) -> Option { + // The primary span is to be provided by `BufferedEarlyLint`. + None + } } #[derive(LintDiagnostic)] @@ -2914,7 +3258,6 @@ pub(crate) struct UnusedExternCrate { pub(crate) struct ExternCrateNotIdiomatic { #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")] pub span: Span, - pub code: &'static str, } @@ -2928,6 +3271,11 @@ impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports { diag.primary_message(self.ambiguity.msg.clone()); rustc_errors::report_ambiguity_error(diag, self.ambiguity); } + + fn span(&self) -> Option { + // The primary span is to be provided by `BufferedEarlyLint`. + None + } } #[derive(LintDiagnostic)] @@ -3018,6 +3366,7 @@ pub(crate) struct OutOfScopeMacroCalls { #[derive(LintDiagnostic)] #[diag(lint_static_mut_refs_lint)] pub(crate) struct RefOfMutStatic<'a> { + #[primary_span] #[label] pub span: Span, #[subdiagnostic] @@ -3049,7 +3398,10 @@ pub(crate) enum MutRefSugg { #[derive(LintDiagnostic)] #[diag(lint_unqualified_local_imports)] -pub(crate) struct UnqualifiedLocalImportsDiag {} +pub(crate) struct UnqualifiedLocalImportsDiag { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(lint_reserved_string)] diff --git a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs index 23f4f7289067d..42e728c0308ab 100644 --- a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs +++ b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs @@ -136,11 +136,9 @@ impl Expr2024 { } debug!("emitting lint"); - cx.builder.emit_span_lint( - &EDITION_2024_EXPR_FRAGMENT_SPECIFIER, - token.span.into(), - MacroExprFragment2024 { suggestion: token.span }, - ); + cx.builder.emit_lint(EDITION_2024_EXPR_FRAGMENT_SPECIFIER, MacroExprFragment2024 { + span: token.span, + }); } } diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs index 776d51a672718..2ca9f18419a30 100644 --- a/compiler/rustc_lint/src/map_unit_fn.rs +++ b/compiler/rustc_lint/src/map_unit_fn.rs @@ -60,7 +60,8 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn { let fn_ty = cx.tcx.fn_sig(id).skip_binder(); let ret_ty = fn_ty.output().skip_binder(); if is_unit_type(ret_ty) { - cx.emit_span_lint(MAP_UNIT_FN, span, MappingToUnit { + cx.emit_lint(MAP_UNIT_FN, MappingToUnit { + span, function_label: cx.tcx.span_of_impl(*id).unwrap_or(default_span), argument_label: args[0].span, map_label: arg_ty.default_span(cx.tcx), @@ -72,7 +73,8 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn { let cl_ty = subs.as_closure().sig(); let ret_ty = cl_ty.output().skip_binder(); if is_unit_type(ret_ty) { - cx.emit_span_lint(MAP_UNIT_FN, span, MappingToUnit { + cx.emit_lint(MAP_UNIT_FN, MappingToUnit { + span, function_label: cx.tcx.span_of_impl(*id).unwrap_or(default_span), argument_label: args[0].span, map_label: arg_ty.default_span(cx.tcx), diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs index df22bf0972d71..6179f659066bf 100644 --- a/compiler/rustc_lint/src/methods.rs +++ b/compiler/rustc_lint/src/methods.rs @@ -58,8 +58,8 @@ fn lint_cstring_as_ptr( if cx.tcx.is_diagnostic_item(sym::Result, def.did()) { if let ty::Adt(adt, _) = args.type_at(0).kind() { if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) { - cx.emit_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, CStringPtr { - as_ptr: as_ptr_span, + cx.emit_lint(TEMPORARY_CSTRING_AS_PTR, CStringPtr { + span: as_ptr_span, unwrap: unwrap.span, }); } diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index 9fde35f82d823..ecfb78b04c89d 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -48,10 +48,12 @@ impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { .iter_identity_copied() .filter_map(|(pred, _)| pred.as_trait_clause()); if direct_super_traits_iter.count() > 1 { - cx.emit_span_lint( + cx.emit_lint( MULTIPLE_SUPERTRAIT_UPCASTABLE, - cx.tcx.def_span(def_id), - crate::lints::MultipleSupertraitUpcastable { ident: item.ident }, + crate::lints::MultipleSupertraitUpcastable { + span: cx.tcx.def_span(def_id), + ident: item.ident, + }, ); } } diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 9b495c19990c1..b18293eb08f7c 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -189,7 +189,7 @@ impl EarlyLintPass for NonAsciiIdents { continue; } has_non_ascii_idents = true; - cx.emit_span_lint(NON_ASCII_IDENTS, sp, IdentifierNonAsciiChar); + cx.emit_lint(NON_ASCII_IDENTS, IdentifierNonAsciiChar { span: sp }); if check_uncommon_codepoints && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed) { @@ -209,7 +209,8 @@ impl EarlyLintPass for NonAsciiIdents { if codepoints.is_empty() { continue; } - cx.emit_span_lint(UNCOMMON_CODEPOINTS, sp, IdentifierUncommonCodepoints { + cx.emit_lint(UNCOMMON_CODEPOINTS, IdentifierUncommonCodepoints { + span: sp, codepoints_len: codepoints.len(), codepoints: codepoints.into_iter().map(|(c, _)| c).collect(), identifier_type: id_ty_descr, @@ -220,7 +221,8 @@ impl EarlyLintPass for NonAsciiIdents { .extract_if(|(c, _)| !GeneralSecurityProfile::identifier_allowed(*c)) .collect::>(); if !remaining.is_empty() { - cx.emit_span_lint(UNCOMMON_CODEPOINTS, sp, IdentifierUncommonCodepoints { + cx.emit_lint(UNCOMMON_CODEPOINTS, IdentifierUncommonCodepoints { + span: sp, codepoints_len: remaining.len(), codepoints: remaining.into_iter().map(|(c, _)| c).collect(), identifier_type: "Restricted", @@ -253,11 +255,11 @@ impl EarlyLintPass for NonAsciiIdents { .entry(skeleton_sym) .and_modify(|(existing_symbol, existing_span, existing_is_ascii)| { if !*existing_is_ascii || !is_ascii { - cx.emit_span_lint(CONFUSABLE_IDENTS, sp, ConfusableIdentifierPair { + cx.emit_lint(CONFUSABLE_IDENTS, ConfusableIdentifierPair { + span: sp, existing_sym: *existing_symbol, sym: symbol, label: *existing_span, - main_label: sp, }); } if *existing_is_ascii && !is_ascii { @@ -370,7 +372,8 @@ impl EarlyLintPass for NonAsciiIdents { let char_info = format!("'{}' (U+{:04X})", ch, ch as u32); includes += &char_info; } - cx.emit_span_lint(MIXED_SCRIPT_CONFUSABLES, sp, MixedScriptConfusables { + cx.emit_lint(MIXED_SCRIPT_CONFUSABLES, MixedScriptConfusables { + span: sp, set: script_set.to_string(), includes, }); diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 51877e8a03495..e9d88b4272436 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -255,7 +255,8 @@ fn check_panic_str<'tcx>( .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end))) .collect(), }; - cx.emit_span_lint(NON_FMT_PANICS, arg_spans, NonFmtPanicUnused { + cx.emit_lint(NON_FMT_PANICS, NonFmtPanicUnused { + spans: arg_spans, count: n_arguments, suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span), }); @@ -268,14 +269,11 @@ fn check_panic_str<'tcx>( .collect() }); let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2); - cx.emit_span_lint( - NON_FMT_PANICS, - brace_spans.unwrap_or_else(|| vec![span]), - NonFmtPanicBraces { - count, - suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span.shrink_to_lo()), - }, - ); + cx.emit_lint(NON_FMT_PANICS, NonFmtPanicBraces { + spans: brace_spans.unwrap_or_else(|| vec![span]), + count, + suggestion: is_arg_inside_call(arg.span, span).then_some(arg.span.shrink_to_lo()), + }); } } diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 3c31b879bd6aa..7267a80287599 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -217,7 +217,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { None }; - cx.emit_span_lint(NON_LOCAL_DEFINITIONS, ms, NonLocalDefinitionsDiag::Impl { + cx.emit_lint(NON_LOCAL_DEFINITIONS, NonLocalDefinitionsDiag::Impl { + span: ms, depth: self.body_depth, body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent), body_name: parent_opt_item_name @@ -232,19 +233,16 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { ItemKind::Macro(_macro, MacroKind::Bang) if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) => { - cx.emit_span_lint( - NON_LOCAL_DEFINITIONS, - item.span, - NonLocalDefinitionsDiag::MacroRules { - depth: self.body_depth, - body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent), - body_name: parent_opt_item_name - .map(|s| s.to_ident_string()) - .unwrap_or_else(|| "".to_string()), - cargo_update: cargo_update(), - doctest: is_at_toplevel_doctest(), - }, - ) + cx.emit_lint(NON_LOCAL_DEFINITIONS, NonLocalDefinitionsDiag::MacroRules { + span: item.span, + depth: self.body_depth, + body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent), + body_name: parent_opt_item_name + .map(|s| s.to_ident_string()) + .unwrap_or_else(|| "".to_string()), + cargo_update: cargo_update(), + doctest: is_at_toplevel_doctest(), + }) } _ => {} } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 83a8ca4307e03..866c71d927896 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -151,7 +151,8 @@ impl NonCamelCaseTypes { } else { NonCamelCaseTypeSub::Label { span: ident.span } }; - cx.emit_span_lint(NON_CAMEL_CASE_TYPES, ident.span, NonCamelCaseType { + cx.emit_lint(NON_CAMEL_CASE_TYPES, NonCamelCaseType { + span: ident.span, sort, name, sub, @@ -321,7 +322,7 @@ impl NonSnakeCase { } else { NonSnakeCaseDiagSub::Label { span } }; - cx.emit_span_lint(NON_SNAKE_CASE, span, NonSnakeCaseDiag { sort, name, sc, sub }); + cx.emit_lint(NON_SNAKE_CASE, NonSnakeCaseDiag { span, sort, name, sc, sub }); } } } @@ -489,7 +490,8 @@ impl NonUpperCaseGlobals { } else { NonUpperCaseGlobalSub::Label { span: ident.span } }; - cx.emit_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, NonUpperCaseGlobal { + cx.emit_lint(NON_UPPER_CASE_GLOBALS, NonUpperCaseGlobal { + span: ident.span, sort, name, sub, diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 4890a93fa76a9..f2f6a9315d5bc 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -128,11 +128,11 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { ty::Adt(def, _) => Some(cx.tcx.def_span(def.did()).shrink_to_lo()), _ => None, }; - cx.emit_span_lint(NOOP_METHOD_CALL, span, NoopMethodCallDiag { + cx.emit_lint(NOOP_METHOD_CALL, NoopMethodCallDiag { + span, method: call.ident.name, orig_ty, trait_, - label: span, suggest_derive, }); } else { @@ -140,16 +140,18 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { // If `type_of(x) == T` and `x.borrow()` is used to get `&T`, // then that should be allowed sym::noop_method_borrow => return, - sym::noop_method_clone => cx.emit_span_lint( - SUSPICIOUS_DOUBLE_REF_OP, - span, - SuspiciousDoubleRefCloneDiag { ty: expr_ty }, - ), - sym::noop_method_deref => cx.emit_span_lint( - SUSPICIOUS_DOUBLE_REF_OP, - span, - SuspiciousDoubleRefDerefDiag { ty: expr_ty }, - ), + sym::noop_method_clone => { + cx.emit_lint(SUSPICIOUS_DOUBLE_REF_OP, SuspiciousDoubleRefCloneDiag { + span, + ty: expr_ty, + }) + } + sym::noop_method_deref => { + cx.emit_lint(SUSPICIOUS_DOUBLE_REF_OP, SuspiciousDoubleRefDerefDiag { + span, + ty: expr_ty, + }) + } _ => return, } } diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index ffbcf7f808ebe..05f8bcb99ba2e 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -178,20 +178,17 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { _ => None, }; - cx.emit_span_lint( - OPAQUE_HIDDEN_INFERRED_BOUND, - pred_span, - OpaqueHiddenInferredBoundLint { - ty: Ty::new_opaque( - cx.tcx, - def_id, - ty::GenericArgs::identity_for_item(cx.tcx, def_id), - ), - proj_ty: proj_term, - assoc_pred_span, - add_bound, - }, - ); + cx.emit_lint(OPAQUE_HIDDEN_INFERRED_BOUND, OpaqueHiddenInferredBoundLint { + span: pred_span, + ty: Ty::new_opaque( + cx.tcx, + def_id, + ty::GenericArgs::identity_for_item(cx.tcx, def_id), + ), + proj_ty: proj_term, + assoc_pred_span, + add_bound, + }); } } }); @@ -202,6 +199,8 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { #[derive(LintDiagnostic)] #[diag(lint_opaque_hidden_inferred_bound)] struct OpaqueHiddenInferredBoundLint<'tcx> { + #[primary_span] + span: Span, ty: Ty<'tcx>, proj_ty: Ty<'tcx>, #[label(lint_specifically)] diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index ec306f5f83472..530702176c371 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -31,10 +31,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue { } } if let Some(t) = path_for_pass_by_value(cx, inner_ty) { - cx.emit_span_lint(PASS_BY_VALUE, ty.span, PassByValueDiag { - ty: t, - suggestion: ty.span, - }); + cx.emit_lint(PASS_BY_VALUE, PassByValueDiag { span: ty.span, ty: t }); } } _ => {} diff --git a/compiler/rustc_lint/src/precedence.rs b/compiler/rustc_lint/src/precedence.rs index 52321e25c7d43..acb540f7311ff 100644 --- a/compiler/rustc_lint/src/precedence.rs +++ b/compiler/rustc_lint/src/precedence.rs @@ -52,20 +52,17 @@ impl EarlyLintPass for Precedence { && let ExprKind::Lit(lit) = &arg.kind && let LitKind::Integer | LitKind::Float = &lit.kind { - cx.emit_span_lint( - AMBIGUOUS_NEGATIVE_LITERALS, - expr.span, - AmbiguousNegativeLiteralsDiag { - negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion { - start_span: expr.span.shrink_to_lo(), - end_span: arg.span.shrink_to_hi(), - }, - current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { - start_span: operand.span.shrink_to_lo(), - end_span: operand.span.shrink_to_hi(), - }, + cx.emit_lint(AMBIGUOUS_NEGATIVE_LITERALS, AmbiguousNegativeLiteralsDiag { + span: expr.span, + negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion { + start_span: expr.span.shrink_to_lo(), + end_span: arg.span.shrink_to_hi(), }, - ); + current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion { + start_span: operand.span.shrink_to_lo(), + end_span: operand.span.shrink_to_hi(), + }, + }); } } } diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 1489f9de81991..f09a17372be9f 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -1,7 +1,7 @@ use rustc_ast::LitKind; use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind}; use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::sym; +use rustc_span::{Span, sym}; use crate::lints::PtrNullChecksDiag; use crate::{LateContext, LateLintPass, LintContext}; @@ -41,6 +41,7 @@ declare_lint_pass!(PtrNullChecks => [USELESS_PTR_NULL_CHECKS]); fn incorrect_check<'a, 'tcx: 'a>( cx: &'a LateContext<'tcx>, mut e: &'a Expr<'a>, + span: Span, ) -> Option> { let mut had_at_least_one_cast = false; loop { @@ -50,14 +51,14 @@ fn incorrect_check<'a, 'tcx: 'a>( && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr) && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) { - return Some(PtrNullChecksDiag::FnRet { fn_name }); + return Some(PtrNullChecksDiag::FnRet { span, fn_name }); } else if let ExprKind::Call(path, _args) = e.kind && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() && cx.tcx.has_attr(def_id, sym::rustc_never_returns_null_ptr) && let Some(fn_name) = cx.tcx.opt_item_ident(def_id) { - return Some(PtrNullChecksDiag::FnRet { fn_name }); + return Some(PtrNullChecksDiag::FnRet { span, fn_name }); } e = if let ExprKind::Cast(expr, t) = e.kind && let TyKind::Ptr(_) = t.kind @@ -73,9 +74,9 @@ fn incorrect_check<'a, 'tcx: 'a>( } else if had_at_least_one_cast { let orig_ty = cx.typeck_results().expr_ty(e); return if orig_ty.is_fn() { - Some(PtrNullChecksDiag::FnPtr { orig_ty, label: e.span }) + Some(PtrNullChecksDiag::FnPtr { span, orig_ty, label: e.span }) } else if orig_ty.is_ref() { - Some(PtrNullChecksDiag::Ref { orig_ty, label: e.span }) + Some(PtrNullChecksDiag::Ref { span, orig_ty, label: e.span }) } else { None }; @@ -97,9 +98,9 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks { cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_const_is_null | sym::ptr_is_null) ) - && let Some(diag) = incorrect_check(cx, arg) => + && let Some(diag) = incorrect_check(cx, arg, expr.span) => { - cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag) + cx.emit_lint(USELESS_PTR_NULL_CHECKS, diag) } // Catching: @@ -110,18 +111,18 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks { cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_const_is_null | sym::ptr_is_null) ) - && let Some(diag) = incorrect_check(cx, receiver) => + && let Some(diag) = incorrect_check(cx, receiver, expr.span) => { - cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag) + cx.emit_lint(USELESS_PTR_NULL_CHECKS, diag) } ExprKind::Binary(op, left, right) if matches!(op.node, BinOpKind::Eq) => { let to_check: &Expr<'_>; let diag: PtrNullChecksDiag<'_>; - if let Some(ddiag) = incorrect_check(cx, left) { + if let Some(ddiag) = incorrect_check(cx, left, expr.span) { to_check = right; diag = ddiag; - } else if let Some(ddiag) = incorrect_check(cx, right) { + } else if let Some(ddiag) = incorrect_check(cx, right, expr.span) { to_check = left; diag = ddiag; } else { @@ -136,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks { && let LitKind::Int(v, _) = spanned.node && v == 0 => { - cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag) + cx.emit_lint(USELESS_PTR_NULL_CHECKS, diag) } // Catching: @@ -147,7 +148,7 @@ impl<'tcx> LateLintPass<'tcx> for PtrNullChecks { && let Some(diag_item) = cx.tcx.get_diagnostic_name(def_id) && (diag_item == sym::ptr_null || diag_item == sym::ptr_null_mut) => { - cx.emit_span_lint(USELESS_PTR_NULL_CHECKS, expr.span, diag) + cx.emit_lint(USELESS_PTR_NULL_CHECKS, diag) } _ => {} diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index 036bfd06856f6..b2962dace5150 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -50,9 +50,6 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo return; } - cx.emit_span_lint(REDUNDANT_SEMICOLONS, span, RedundantSemicolonsDiag { - multiple, - suggestion: span, - }); + cx.emit_lint(REDUNDANT_SEMICOLONS, RedundantSemicolonsDiag { span, multiple }); } } diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 45d97403d6068..c420edbc2d265 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -54,16 +54,17 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { && let Some(ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr(cx, init, &mut peel_casts) { - cx.emit_span_lint( + cx.emit_lint( INVALID_REFERENCE_CASTING, - expr.span, if pat == PatternKind::Assign { InvalidReferenceCastingDiag::AssignToRef { + span: expr.span, orig_cast, ty_has_interior_mutability, } } else { InvalidReferenceCastingDiag::BorrowAsMut { + span: expr.span, orig_cast, ty_has_interior_mutability, } @@ -74,10 +75,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { if let Some((from_ty_layout, to_ty_layout, e_alloc)) = is_cast_to_bigger_memory_layout(cx, init, &mut peel_casts) { - cx.emit_span_lint( + cx.emit_lint( INVALID_REFERENCE_CASTING, - expr.span, InvalidReferenceCastingDiag::BiggerLayout { + span: expr.span, orig_cast, alloc: e_alloc.span, from_ty: from_ty_layout.ty, diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index a73904cd7769b..c688fb6ffd5da 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -146,11 +146,6 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter { None }; - cx.emit_span_lint(lint, call.ident.span, ShadowedIntoIterDiag { - target, - edition, - suggestion: call.ident.span, - sub, - }); + cx.emit_lint(lint, ShadowedIntoIterDiag { span: call.ident.span, target, edition, sub }); } } diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 5d78b41944fef..0717c6de428a0 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -146,7 +146,7 @@ fn emit_static_mut_refs( } }; - cx.emit_span_lint(STATIC_MUT_REFS, span, RefOfMutStatic { + cx.emit_lint(STATIC_MUT_REFS, RefOfMutStatic { span, sugg, shared_label, diff --git a/compiler/rustc_lint/src/tail_expr_drop_order.rs b/compiler/rustc_lint/src/tail_expr_drop_order.rs index 04f769bf5517f..3e6e5a5e079fa 100644 --- a/compiler/rustc_lint/src/tail_expr_drop_order.rs +++ b/compiler/rustc_lint/src/tail_expr_drop_order.rs @@ -244,12 +244,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LintTailExpr<'a, 'tcx> { if self.is_root_tail_expr { self.is_root_tail_expr = false; } else if self.expr_generates_nonlocal_droppy_value(expr) { - self.cx.tcx.emit_node_span_lint( - TAIL_EXPR_DROP_ORDER, - expr.hir_id, - expr.span, - TailExprDropOrderLint { spans: self.locals.to_vec() }, - ); + self.cx.tcx.emit_node_lint(TAIL_EXPR_DROP_ORDER, expr.hir_id, TailExprDropOrderLint { + span: expr.span, + locals: self.locals.to_vec(), + }); return; } match expr.kind { @@ -301,6 +299,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LintTailExpr<'a, 'tcx> { #[derive(LintDiagnostic)] #[diag(lint_tail_expr_drop_order)] struct TailExprDropOrderLint { + #[primary_span] + pub span: Span, #[label] - pub spans: Vec, + pub locals: Vec, } diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index b793ec6a4939e..751886dfa821e 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -101,7 +101,8 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { continue; } let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return }; - cx.emit_span_lint(DROP_BOUNDS, span, DropTraitConstraintsDiag { + cx.emit_lint(DROP_BOUNDS, DropTraitConstraintsDiag { + span, predicate, tcx: cx.tcx, def_id, @@ -116,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { let def_id = bound.trait_ref.trait_def_id(); if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop)) { let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return }; - cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id }); + cx.emit_lint(DYN_DROP, DropGlue { span: bound.span, tcx: cx.tcx, def_id }); } } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 60ff925b40e0d..c9b03f84c3094 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -224,7 +224,7 @@ fn lint_nan<'tcx>( InvalidNanComparisonsSuggestion::Spanless }; - InvalidNanComparisons::EqNe { suggestion } + InvalidNanComparisons::EqNe { span: e.span, suggestion } } let lint = match binop.node { @@ -245,12 +245,12 @@ fn lint_nan<'tcx>( hir::BinOpKind::Lt | hir::BinOpKind::Le | hir::BinOpKind::Gt | hir::BinOpKind::Ge if is_nan(cx, l) || is_nan(cx, r) => { - InvalidNanComparisons::LtLeGtGe + InvalidNanComparisons::LtLeGtGe { span: e.span } } _ => return, }; - cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint); + cx.emit_lint(INVALID_NAN_COMPARISONS, lint); } #[derive(Debug, PartialEq)] @@ -315,10 +315,9 @@ fn lint_wide_pointer<'tcx>( let (Some(l_span), Some(r_span)) = (l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span)) else { - return cx.emit_span_lint( + return cx.emit_lint( AMBIGUOUS_WIDE_POINTER_COMPARISONS, - e.span, - AmbiguousWidePointerComparisons::Spanless, + AmbiguousWidePointerComparisons::Spanless { span: e.span }, ); }; @@ -336,49 +335,46 @@ fn lint_wide_pointer<'tcx>( let l_modifiers = &*l_modifiers; let r_modifiers = &*r_modifiers; - cx.emit_span_lint( - AMBIGUOUS_WIDE_POINTER_COMPARISONS, - e.span, - AmbiguousWidePointerComparisons::Spanful { - addr_metadata_suggestion: (is_eq_ne && !is_dyn_comparison).then(|| { - AmbiguousWidePointerComparisonsAddrMetadataSuggestion { - ne, - deref_left, - deref_right, - l_modifiers, - r_modifiers, - left, - middle, - right, - } - }), - addr_suggestion: if is_eq_ne { - AmbiguousWidePointerComparisonsAddrSuggestion::AddrEq { - ne, - deref_left, - deref_right, - l_modifiers, - r_modifiers, - left, - middle, - right, - } - } else { - AmbiguousWidePointerComparisonsAddrSuggestion::Cast { - deref_left, - deref_right, - l_modifiers, - r_modifiers, - paren_left: if l_ty_refs != 0 { ")" } else { "" }, - paren_right: if r_ty_refs != 0 { ")" } else { "" }, - left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()), - left_after: l_span.shrink_to_hi(), - right_before: (r_ty_refs != 0).then_some(r_span.shrink_to_lo()), - right_after: r_span.shrink_to_hi(), - } - }, + cx.emit_lint(AMBIGUOUS_WIDE_POINTER_COMPARISONS, AmbiguousWidePointerComparisons::Spanful { + span: e.span, + addr_metadata_suggestion: (is_eq_ne && !is_dyn_comparison).then(|| { + AmbiguousWidePointerComparisonsAddrMetadataSuggestion { + ne, + deref_left, + deref_right, + l_modifiers, + r_modifiers, + left, + middle, + right, + } + }), + addr_suggestion: if is_eq_ne { + AmbiguousWidePointerComparisonsAddrSuggestion::AddrEq { + ne, + deref_left, + deref_right, + l_modifiers, + r_modifiers, + left, + middle, + right, + } + } else { + AmbiguousWidePointerComparisonsAddrSuggestion::Cast { + deref_left, + deref_right, + l_modifiers, + r_modifiers, + paren_left: if l_ty_refs != 0 { ")" } else { "" }, + paren_right: if r_ty_refs != 0 { ")" } else { "" }, + left_before: (l_ty_refs != 0).then_some(l_span.shrink_to_lo()), + left_after: l_span.shrink_to_hi(), + right_before: (r_ty_refs != 0).then_some(r_span.shrink_to_lo()), + right_after: r_span.shrink_to_hi(), + } }, - ); + }); } impl<'tcx> LateLintPass<'tcx> for TypeLimits { @@ -394,7 +390,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { hir::ExprKind::Binary(binop, ref l, ref r) => { if is_comparison(binop) { if !check_limits(cx, binop, l, r) { - cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons); + cx.emit_lint(UNUSED_COMPARISONS, UnusedComparisons { span: e.span }); } else { lint_nan(cx, e, binop, l, r); lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r); @@ -1163,14 +1159,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } else { None }; - self.cx.emit_span_lint(lint, sp, ImproperCTypes { - ty, - desc, - label: sp, - help, - note, - span_note, - }); + self.cx.emit_lint(lint, ImproperCTypes { span: sp, ty, desc, help, note, span_note }); } fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { @@ -1497,11 +1486,10 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { // We only warn if the largest variant is at least thrice as large as // the second-largest. if largest > slargest * 3 && slargest > 0 { - cx.emit_span_lint( - VARIANT_SIZE_DIFFERENCES, - enum_definition.variants[largest_index].span, - VariantSizeDifferencesDiag { largest }, - ); + cx.emit_lint(VARIANT_SIZE_DIFFERENCES, VariantSizeDifferencesDiag { + span: enum_definition.variants[largest_index].span, + largest, + }); } } } @@ -1618,9 +1606,13 @@ impl InvalidAtomicOrdering { && (ordering == invalid_ordering || ordering == sym::AcqRel) { if method == sym::load { - cx.emit_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, AtomicOrderingLoad); + cx.emit_lint(INVALID_ATOMIC_ORDERING, AtomicOrderingLoad { + span: ordering_arg.span, + }); } else { - cx.emit_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, AtomicOrderingStore); + cx.emit_lint(INVALID_ATOMIC_ORDERING, AtomicOrderingStore { + span: ordering_arg.span, + }); }; } } @@ -1632,7 +1624,7 @@ impl InvalidAtomicOrdering { && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::fence | sym::compiler_fence)) && Self::match_ordering(cx, &args[0]) == Some(sym::Relaxed) { - cx.emit_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, AtomicOrderingFence); + cx.emit_lint(INVALID_ATOMIC_ORDERING, AtomicOrderingFence { span: args[0].span }); } } @@ -1654,11 +1646,10 @@ impl InvalidAtomicOrdering { let Some(fail_ordering) = Self::match_ordering(cx, fail_order_arg) else { return }; if matches!(fail_ordering, sym::Release | sym::AcqRel) { - cx.emit_span_lint( - INVALID_ATOMIC_ORDERING, - fail_order_arg.span, - InvalidAtomicOrderingDiag { method, fail_order_arg_span: fail_order_arg.span }, - ); + cx.emit_lint(INVALID_ATOMIC_ORDERING, InvalidAtomicOrderingDiag { + span: fail_order_arg.span, + method, + }); } } } diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs index d1e850990dc3e..3dea04bdb0cbc 100644 --- a/compiler/rustc_lint/src/types/literal.rs +++ b/compiler/rustc_lint/src/types/literal.rs @@ -74,7 +74,8 @@ fn lint_overflowing_range_endpoint<'tcx>( } }; - cx.emit_span_lint(OVERFLOWING_LITERALS, struct_expr.span, RangeEndpointOutOfRange { + cx.emit_lint(OVERFLOWING_LITERALS, RangeEndpointOutOfRange { + span: struct_expr.span, ty, sub: sub_sugg, }); @@ -186,7 +187,8 @@ fn report_bin_hex_error( }) .flatten(); - cx.emit_span_lint(OVERFLOWING_LITERALS, expr.span, OverflowingBinHex { + cx.emit_lint(OVERFLOWING_LITERALS, OverflowingBinHex { + span: expr.span, ty: t, lit: repr_str.clone(), dec: val, @@ -261,7 +263,8 @@ fn lint_int_literal<'tcx>( let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative) .map(|suggestion_ty| OverflowingIntHelp { suggestion_ty }); - cx.emit_span_lint(OVERFLOWING_LITERALS, span, OverflowingInt { + cx.emit_lint(OVERFLOWING_LITERALS, OverflowingInt { + span, ty: t.name_str(), lit, min, @@ -291,7 +294,7 @@ fn lint_uint_literal<'tcx>( match par_e.kind { hir::ExprKind::Cast(..) => { if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() { - cx.emit_span_lint(OVERFLOWING_LITERALS, par_e.span, OnlyCastu8ToChar { + cx.emit_lint(OVERFLOWING_LITERALS, OnlyCastu8ToChar { span: par_e.span, literal: lit_val, }); @@ -317,7 +320,8 @@ fn lint_uint_literal<'tcx>( ); return; } - cx.emit_span_lint(OVERFLOWING_LITERALS, e.span, OverflowingUInt { + cx.emit_lint(OVERFLOWING_LITERALS, OverflowingUInt { + span: e.span, ty: t.name_str(), lit: cx .sess() @@ -359,7 +363,8 @@ pub(crate) fn lint_literal<'tcx>( _ => bug!(), }; if is_infinite == Ok(true) { - cx.emit_span_lint(OVERFLOWING_LITERALS, e.span, OverflowingLiteral { + cx.emit_lint(OVERFLOWING_LITERALS, OverflowingLiteral { + span: e.span, ty: t.name_str(), lit: cx .sess() diff --git a/compiler/rustc_lint/src/unit_bindings.rs b/compiler/rustc_lint/src/unit_bindings.rs index 3c2c5f8fae095..3235b35543fea 100644 --- a/compiler/rustc_lint/src/unit_bindings.rs +++ b/compiler/rustc_lint/src/unit_bindings.rs @@ -63,7 +63,8 @@ impl<'tcx> LateLintPass<'tcx> for UnitBindings { && !matches!(init.kind, hir::ExprKind::Tup([])) && !matches!(local.pat.kind, hir::PatKind::Tuple([], ..)) { - cx.emit_span_lint(UNIT_BINDINGS, local.span, UnitBindingsDiag { + cx.emit_lint(UNIT_BINDINGS, UnitBindingsDiag { + span: local.span, label: local.pat.span, }); } diff --git a/compiler/rustc_lint/src/unqualified_local_imports.rs b/compiler/rustc_lint/src/unqualified_local_imports.rs index bea01a33bd6ce..f5b8b9ae18725 100644 --- a/compiler/rustc_lint/src/unqualified_local_imports.rs +++ b/compiler/rustc_lint/src/unqualified_local_imports.rs @@ -76,10 +76,8 @@ impl<'tcx> LateLintPass<'tcx> for UnqualifiedLocalImports { } // This `use` qualifies for our lint! - cx.emit_span_lint( - UNQUALIFIED_LOCAL_IMPORTS, - first_seg.ident.span, - lints::UnqualifiedLocalImportsDiag {}, - ); + cx.emit_lint(UNQUALIFIED_LOCAL_IMPORTS, lints::UnqualifiedLocalImportsDiag { + span: first_seg.ident.span, + }); } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index ddc18c755a89b..4e645296319a4 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -185,9 +185,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { let mut op_warned = false; if let Some(must_use_op) = must_use_op { - cx.emit_span_lint(UNUSED_MUST_USE, expr.span, UnusedOp { + cx.emit_lint(UNUSED_MUST_USE, UnusedOp { + span: expr.span, op: must_use_op, - label: expr.span, suggestion: if expr_is_from_block { UnusedOpSuggestion::BlockTailExpr { before_span: expr.span.shrink_to_lo(), @@ -201,7 +201,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } if !(type_lint_emitted_or_suppressed || fn_warned || op_warned) { - cx.emit_span_lint(UNUSED_RESULTS, s.span, UnusedResult { ty }); + cx.emit_lint(UNUSED_RESULTS, UnusedResult { span: s.span, ty }); } fn check_fn_must_use( @@ -492,27 +492,30 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { expr_is_from_block, ); } - MustUsePath::Closure(span) => { - cx.emit_span_lint(UNUSED_MUST_USE, *span, UnusedClosure { + &MustUsePath::Closure(span) => { + cx.emit_lint(UNUSED_MUST_USE, UnusedClosure { + span, count: plural_len, pre: descr_pre, post: descr_post, }); } - MustUsePath::Coroutine(span) => { - cx.emit_span_lint(UNUSED_MUST_USE, *span, UnusedCoroutine { + &MustUsePath::Coroutine(span) => { + cx.emit_lint(UNUSED_MUST_USE, UnusedCoroutine { + span, count: plural_len, pre: descr_pre, post: descr_post, }); } - MustUsePath::Def(span, def_id, reason) => { - cx.emit_span_lint(UNUSED_MUST_USE, *span, UnusedDef { + &MustUsePath::Def(span, def_id, reason) => { + cx.emit_lint(UNUSED_MUST_USE, UnusedDef { + span, pre: descr_pre, post: descr_post, cx, - def_id: *def_id, - note: *reason, + def_id, + note: reason, suggestion: (!is_inner).then_some(if expr_is_from_block { UnusedDefSuggestion::BlockTailExpr { before_span: span.shrink_to_lo(), @@ -563,9 +566,9 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements { } else { PathStatementDropSub::Help { span: s.span } }; - cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementDrop { sub }) + cx.emit_lint(PATH_STATEMENTS, PathStatementDrop { span: s.span, sub }) } else { - cx.emit_span_lint(PATH_STATEMENTS, s.span, PathStatementNoEffect); + cx.emit_lint(PATH_STATEMENTS, PathStatementNoEffect { span: s.span }); } } } @@ -869,7 +872,8 @@ trait UnusedDelimLint { end_replace: hi_replace, } }); - cx.emit_span_lint(self.lint(), primary_span, UnusedDelim { + cx.emit_lint(self.lint(), UnusedDelim { + span: primary_span, delim: Self::DELIM_STR, item: msg, suggestion, @@ -1558,7 +1562,8 @@ impl UnusedImportBraces { ast::UseTreeKind::Nested { .. } => return, }; - cx.emit_span_lint(UNUSED_IMPORT_BRACES, item.span, UnusedImportBracesDiag { + cx.emit_lint(UNUSED_IMPORT_BRACES, UnusedImportBracesDiag { + span: item.span, node: node_name, }); } @@ -1613,10 +1618,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind { match m { adjustment::AutoBorrowMutability::Not => { - cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag); + cx.emit_lint(UNUSED_ALLOCATION, UnusedAllocationDiag { span: e.span }); } adjustment::AutoBorrowMutability::Mut { .. } => { - cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationMutDiag); + cx.emit_lint(UNUSED_ALLOCATION, UnusedAllocationMutDiag { span: e.span }); } }; } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index b5862565e8e87..3c6cd9641043c 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -253,13 +253,11 @@ pub fn explain_lint_level_source( /// The innermost function for emitting lints. /// -/// If you are looking to implement a lint, look for higher level functions, -/// for example: -/// - [`TyCtxt::emit_node_span_lint`] -/// - [`TyCtxt::node_span_lint`] +/// If you are looking to implement a lint, look for higher level functions, for example: +/// /// - [`TyCtxt::emit_node_lint`] /// - [`TyCtxt::node_lint`] -/// - `LintContext::opt_span_lint` +/// - `rustc_lint::LintContext::opt_span_lint` /// /// ## `decorate` /// diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index c0688aff18327..d354bc264c1b2 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -147,6 +147,7 @@ pub struct DeprecationSuggestion { } pub struct Deprecated { + pub span: Option, pub sub: Option, // FIXME: make this translatable @@ -180,6 +181,12 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate diag.subdiagnostic(sub); } } + + fn span(&self) -> Option { + // If this lint diagnostic comes from an early (buffered) lint, `self.span` is `None` + // since in that case the primary span is to be provided by `BufferedEarlyLint`. + self.span.map(Into::into) + } } fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind { @@ -242,6 +249,7 @@ fn late_report_deprecation( let suggestion = if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { depr.suggestion } else { None }; let diag = Deprecated { + span: Some(method_span), sub: suggestion.map(|suggestion| DeprecationSuggestion { span: method_span, kind: def_kind.to_owned(), @@ -252,7 +260,7 @@ fn late_report_deprecation( note: depr.note, since_kind: deprecated_since_kind(is_in_effect, depr.since), }; - tcx.emit_node_span_lint(deprecation_lint(is_in_effect), hir_id, method_span, diag); + tcx.emit_node_lint(deprecation_lint(is_in_effect), hir_id, diag); } /// Result of `TyCtxt::eval_stability`. diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index f3e6301d9d165..0ce47883d2bb2 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -122,10 +122,9 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { }) .unwrap_or_default(); - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( DEPRECATED_SAFE_2024, self.hir_context, - span, CallToDeprecatedSafeFnRequiresUnsafe { span, function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), @@ -692,101 +691,90 @@ impl UnsafeOpKind { // FIXME: ideally we would want to trim the def paths, but this is not // feasible with the current lint emission API (see issue #106126). match self { - CallToUnsafeFunction(Some(did)) => tcx.emit_node_span_lint( + CallToUnsafeFunction(Some(did)) => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { span, function: with_no_trimmed_paths!(tcx.def_path_str(*did)), unsafe_not_inherited_note, }, ), - CallToUnsafeFunction(None) => tcx.emit_node_span_lint( + CallToUnsafeFunction(None) => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { span, unsafe_not_inherited_note, }, ), - UseOfInlineAssembly => tcx.emit_node_span_lint( + UseOfInlineAssembly => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - InitializingTypeWith => tcx.emit_node_span_lint( + InitializingTypeWith => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - UseOfMutableStatic => tcx.emit_node_span_lint( + UseOfMutableStatic => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - UseOfExternStatic => tcx.emit_node_span_lint( + UseOfExternStatic => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - DerefOfRawPointer => tcx.emit_node_span_lint( + DerefOfRawPointer => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - AccessToUnionField => tcx.emit_node_span_lint( + AccessToUnionField => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - MutationOfLayoutConstrainedField => tcx.emit_node_span_lint( + MutationOfLayoutConstrainedField => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - BorrowOfLayoutConstrainedField => tcx.emit_node_span_lint( + BorrowOfLayoutConstrainedField => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span, unsafe_not_inherited_note, }, ), - CallToFunctionWith { function, missing, build_enabled } => tcx.emit_node_span_lint( + CallToFunctionWith { function, missing, build_enabled } => tcx.emit_node_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, - span, UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { span, function: with_no_trimmed_paths!(tcx.def_path_str(*function)), @@ -1045,7 +1033,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { warnings.sort_by_key(|w| w.block_span); for UnusedUnsafeWarning { hir_id, block_span, enclosing_unsafe } in warnings { let block_span = tcx.sess.source_map().guess_head_span(block_span); - tcx.emit_node_span_lint(UNUSED_UNSAFE, hir_id, block_span, UnusedUnsafe { + tcx.emit_node_lint(UNUSED_UNSAFE, hir_id, UnusedUnsafe { span: block_span, enclosing: enclosing_unsafe, }); diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 00f65e0c7d093..e9d10fbefe05f 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -16,6 +16,7 @@ use crate::fluent_generated as fluent; #[diag(mir_build_unconditional_recursion)] #[help] pub(crate) struct UnconditionalRecursion { + #[primary_span] #[label] pub(crate) span: Span, #[label(mir_build_unconditional_recursion_call_site_label)] @@ -25,6 +26,7 @@ pub(crate) struct UnconditionalRecursion { #[derive(LintDiagnostic)] #[diag(mir_build_call_to_deprecated_safe_fn_requires_unsafe)] pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, pub(crate) function: String, @@ -49,6 +51,7 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, pub(crate) function: String, @@ -60,6 +63,7 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -70,6 +74,7 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { #[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -80,6 +85,7 @@ pub(crate) struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { #[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -90,6 +96,7 @@ pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -100,6 +107,7 @@ pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { #[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -110,6 +118,7 @@ pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -120,6 +129,7 @@ pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { #[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe, code = E0133)] #[note] pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -133,6 +143,7 @@ pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { )] #[note] pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -145,6 +156,7 @@ pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsa code = E0133, )] pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -155,6 +167,7 @@ pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)] #[help] pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { + #[primary_span] #[label] pub(crate) span: Span, pub(crate) function: String, @@ -470,6 +483,7 @@ impl Subdiagnostic for UnsafeNotInheritedLintNote { #[derive(LintDiagnostic)] #[diag(mir_build_unused_unsafe)] pub(crate) struct UnusedUnsafe { + #[primary_span] #[label] pub(crate) span: Span, #[subdiagnostic] @@ -584,8 +598,10 @@ pub(crate) struct NonConstPath { #[derive(LintDiagnostic)] #[diag(mir_build_unreachable_pattern)] pub(crate) struct UnreachablePattern<'tcx> { + #[primary_span] + pub(crate) span: Span, #[label] - pub(crate) span: Option, + pub(crate) label: Option, #[label(mir_build_unreachable_matches_no_values)] pub(crate) matches_no_values: Option, pub(crate) matches_no_values_ty: Ty<'tcx>, @@ -649,6 +665,8 @@ pub(crate) struct LowerRangeBoundMustBeLessThanUpper { #[note] #[help] pub(crate) struct LeadingIrrefutableLetPatterns { + #[primary_span] + pub(crate) span: Span, pub(crate) count: usize, } @@ -657,12 +675,16 @@ pub(crate) struct LeadingIrrefutableLetPatterns { #[note] #[help] pub(crate) struct TrailingIrrefutableLetPatterns { + #[primary_span] + pub(crate) span: Span, pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_bindings_with_variant_name, code = E0170)] pub(crate) struct BindingsWithVariantName { + #[primary_span] + pub(crate) span: Span, #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")] pub(crate) suggestion: Option, pub(crate) ty_path: String, @@ -674,6 +696,8 @@ pub(crate) struct BindingsWithVariantName { #[note] #[help] pub(crate) struct IrrefutableLetPatternsIfLet { + #[primary_span] + pub(crate) span: Span, pub(crate) count: usize, } @@ -682,6 +706,8 @@ pub(crate) struct IrrefutableLetPatternsIfLet { #[note] #[help] pub(crate) struct IrrefutableLetPatternsIfLetGuard { + #[primary_span] + pub(crate) span: Span, pub(crate) count: usize, } @@ -690,6 +716,8 @@ pub(crate) struct IrrefutableLetPatternsIfLetGuard { #[note] #[help] pub(crate) struct IrrefutableLetPatternsLetElse { + #[primary_span] + pub(crate) span: Span, pub(crate) count: usize, } @@ -698,6 +726,8 @@ pub(crate) struct IrrefutableLetPatternsLetElse { #[note] #[help] pub(crate) struct IrrefutableLetPatternsWhileLet { + #[primary_span] + pub(crate) span: Span, pub(crate) count: usize, } @@ -977,6 +1007,8 @@ pub(crate) enum RustcBoxAttrReason { #[derive(LintDiagnostic)] #[diag(mir_build_rust_2024_incompatible_pat)] pub(crate) struct Rust2024IncompatiblePat { + #[primary_span] + pub(crate) span: Span, #[subdiagnostic] pub(crate) sugg: Rust2024IncompatiblePatSugg, } diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index cb9a4e2604e25..603bc5b629703 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -54,7 +54,7 @@ fn check_recursion<'tcx>( let sp = tcx.def_span(def_id); let hir_id = tcx.local_def_id_to_hir_id(def_id); - tcx.emit_node_span_lint(UNCONDITIONAL_RECURSION, hir_id, sp, UnconditionalRecursion { + tcx.emit_node_lint(UNCONDITIONAL_RECURSION, hir_id, UnconditionalRecursion { span: sp, call_sites: vis.reachable_recursive_calls, }); diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 8498df59ce653..c6d46d86fa2b4 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -582,11 +582,10 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let span_end = prefix.last().unwrap().unwrap().0; let span = span_start.to(span_end); let count = prefix.len(); - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( IRREFUTABLE_LET_PATTERNS, self.lint_level, - span, - LeadingIrrefutableLetPatterns { count }, + LeadingIrrefutableLetPatterns { span, count }, ); } } @@ -601,11 +600,10 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { let span_end = suffix.last().unwrap().unwrap().0; let span = span_start.to(span_end); let count = suffix.len(); - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( IRREFUTABLE_LET_PATTERNS, self.lint_level, - span, - TrailingIrrefutableLetPatterns { count }, + TrailingIrrefutableLetPatterns { span, count }, ); } } @@ -859,23 +857,15 @@ fn check_for_bindings_named_same_as_variants( { let variant_count = edef.variants().len(); let ty_path = with_no_trimmed_paths!(cx.tcx.def_path_str(edef.did())); - cx.tcx.emit_node_span_lint( - BINDINGS_WITH_VARIANT_NAME, - cx.lint_level, - pat.span, - BindingsWithVariantName { - // If this is an irrefutable pattern, and there's > 1 variant, - // then we can't actually match on this. Applying the below - // suggestion would produce code that breaks on `check_binding_is_irrefutable`. - suggestion: if rf == Refutable || variant_count == 1 { - Some(pat.span) - } else { - None - }, - ty_path, - name, - }, - ) + cx.tcx.emit_node_lint(BINDINGS_WITH_VARIANT_NAME, cx.lint_level, BindingsWithVariantName { + span: pat.span, + // If this is an irrefutable pattern, and there's > 1 variant, + // then we can't actually match on this. Applying the below + // suggestion would produce code that breaks on `check_binding_is_irrefutable`. + suggestion: (rf == Refutable || variant_count == 1).then_some(pat.span), + ty_path, + name, + }) } } @@ -901,7 +891,7 @@ fn report_irrefutable_let_patterns( ) { macro_rules! emit_diag { ($lint:tt) => {{ - tcx.emit_node_span_lint(IRREFUTABLE_LET_PATTERNS, id, span, $lint { count }); + tcx.emit_node_lint(IRREFUTABLE_LET_PATTERNS, id, $lint { span, count }); }}; } @@ -925,7 +915,8 @@ fn report_unreachable_pattern<'p, 'tcx>( static CAP_COVERED_BY_MANY: usize = 4; let pat_span = pat.data().span; let mut lint = UnreachablePattern { - span: Some(pat_span), + span: pat_span, + label: Some(pat_span), matches_no_values: None, matches_no_values_ty: **pat.ty(), uninhabited_note: None, @@ -938,7 +929,7 @@ fn report_unreachable_pattern<'p, 'tcx>( match explanation.covered_by.as_slice() { [] => { // Empty pattern; we report the uninhabited type that caused the emptiness. - lint.span = None; // Don't label the pattern itself + lint.label = None; // Don't label the pattern itself lint.uninhabited_note = Some(()); // Give a link about empty types lint.matches_no_values = Some(pat_span); lint.suggest_remove = whole_arm_span; // Suggest to remove the match arm @@ -985,7 +976,7 @@ fn report_unreachable_pattern<'p, 'tcx>( lint.covered_by_many = Some(multispan); } } - cx.tcx.emit_node_span_lint(UNREACHABLE_PATTERNS, hir_id, pat_span, lint); + cx.tcx.emit_node_lint(UNREACHABLE_PATTERNS, hir_id, lint); } /// Report unreachable arms, if any. diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 56e5156a91fc0..2f4a50367937b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -64,11 +64,10 @@ pub(super) fn pat_from_hir<'a, 'tcx>( err.subdiagnostic(sugg); err.emit(); } else { - tcx.emit_node_span_lint( + tcx.emit_node_lint( lint::builtin::RUST_2024_INCOMPATIBLE_PAT, pat.hir_id, - pat.span, - Rust2024IncompatiblePat { sugg }, + Rust2024IncompatiblePat { span: pat.span, sugg }, ); } } diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 7968b666dff2f..c344741b07b53 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -100,11 +100,10 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { && let Some((lint_root, span, item)) = self.should_lint_const_item_usage(lhs, def_id, loc) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( CONST_ITEM_MUTATION, lint_root, - span, - errors::ConstMutate::Modify { konst: item }, + errors::ConstMutate::Modify { span, konst: item }, ); } @@ -146,11 +145,10 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { if let Some((lint_root, span, item)) = self.should_lint_const_item_usage(place, def_id, lint_loc) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( CONST_ITEM_MUTATION, lint_root, - span, - errors::ConstMutate::MutBorrow { method_call, konst: item }, + errors::ConstMutate::MutBorrow { span, method_call, konst: item }, ); } } diff --git a/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs b/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs index 8ba14a1158ef9..c5cce2b11c88c 100644 --- a/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs +++ b/compiler/rustc_mir_transform/src/check_undefined_transmutes.rs @@ -66,11 +66,10 @@ impl<'tcx> Visitor<'tcx> for UndefinedTransmutesChecker<'_, 'tcx> { { let hir_id = self.tcx.local_def_id_to_hir_id(call_id); let span = self.body.source_info(location).span; - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS, hir_id, - span, - errors::UndefinedTransmute, + errors::UndefinedTransmute { span }, ); } } diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index cd29105897778..49f968f010ada 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1986,15 +1986,14 @@ fn check_must_not_suspend_def( span: data.source_span, reason: s.as_str().to_string(), }); - tcx.emit_node_span_lint( + tcx.emit_node_lint( rustc_session::lint::builtin::MUST_NOT_SUSPEND, hir_id, - data.source_span, errors::MustNotSupend { tcx, + span: data.source_span, yield_sp: data.yield_span, reason, - src_sp: data.source_span, pre: data.descr_pre, def_id, post: data.descr_post, diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 8b309147c64cd..f8390eba6370a 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -1,5 +1,5 @@ use rustc_errors::codes::*; -use rustc_errors::{Diag, LintDiagnostic}; +use rustc_errors::{Diag, LintDiagnostic, MultiSpan}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::mir::AssertKind; use rustc_middle::ty::TyCtxt; @@ -14,6 +14,8 @@ pub(crate) enum ConstMutate { #[diag(mir_transform_const_modify)] #[note] Modify { + #[primary_span] + span: Span, #[note(mir_transform_const_defined_here)] konst: Span, }, @@ -21,6 +23,8 @@ pub(crate) enum ConstMutate { #[note] #[note(mir_transform_note2)] MutBorrow { + #[primary_span] + span: Span, #[note(mir_transform_note3)] method_call: Option, #[note(mir_transform_const_defined_here)] @@ -61,6 +65,10 @@ impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint

{ }); diag.span_label(self.span, label); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } impl AssertLintKind { @@ -75,6 +83,7 @@ impl AssertLintKind { #[derive(LintDiagnostic)] #[diag(mir_transform_ffi_unwind_call)] pub(crate) struct FfiUnwindCall { + #[primary_span] #[label(mir_transform_ffi_unwind_call)] pub span: Span, pub foreign: bool, @@ -83,6 +92,7 @@ pub(crate) struct FfiUnwindCall { #[derive(LintDiagnostic)] #[diag(mir_transform_fn_item_ref)] pub(crate) struct FnItemRef { + #[primary_span] #[suggestion(code = "{sugg}", applicability = "unspecified")] pub span: Span, pub sugg: String, @@ -99,9 +109,9 @@ pub(crate) struct MCDCExceedsTestVectorLimit { pub(crate) struct MustNotSupend<'a, 'tcx> { pub tcx: TyCtxt<'tcx>, + pub span: Span, pub yield_sp: Span, pub reason: Option, - pub src_sp: Span, pub pre: &'a str, pub def_id: DefId, pub post: &'a str, @@ -115,11 +125,15 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> { if let Some(reason) = self.reason { diag.subdiagnostic(reason); } - diag.span_help(self.src_sp, fluent::_subdiag::help); + diag.span_help(self.span, fluent::_subdiag::help); diag.arg("pre", self.pre); diag.arg("def_path", self.tcx.def_path_str(self.def_id)); diag.arg("post", self.post); } + + fn span(&self) -> Option { + Some(self.span.into()) + } } #[derive(Subdiagnostic)] @@ -135,4 +149,7 @@ pub(crate) struct MustNotSuspendReason { #[note] #[note(mir_transform_note2)] #[help] -pub(crate) struct UndefinedTransmute; +pub(crate) struct UndefinedTransmute { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 99892a1296be4..0e4cd2f0a7b8e 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -86,7 +86,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { let span = terminator.source_info.span; let foreign = fn_def_id.is_some(); - tcx.emit_node_span_lint(FFI_UNWIND_CALLS, lint_root, span, errors::FfiUnwindCall { + tcx.emit_node_lint(FFI_UNWIND_CALLS, lint_root, errors::FfiUnwindCall { span, foreign, }); diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index e55aeeac6e069..5d710ef315b99 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -186,11 +186,10 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { ret, ); - self.tcx.emit_node_span_lint( - FUNCTION_ITEM_REFERENCES, - lint_root, + self.tcx.emit_node_lint(FUNCTION_ITEM_REFERENCES, lint_root, errors::FnItemRef { span, - errors::FnItemRef { span, sugg, ident }, - ); + sugg, + ident, + }); } } diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 08923748eb275..f76f76dddda0b 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -295,7 +295,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let source_info = self.body.source_info(location); if let Some(lint_root) = self.lint_root(*source_info) { let span = source_info.span; - self.tcx.emit_node_span_lint(lint_kind.lint(), lint_root, span, AssertLint { + self.tcx.emit_node_lint(lint_kind.lint(), lint_root, AssertLint { span, assert_kind, lint_kind, diff --git a/compiler/rustc_monomorphize/src/collector/move_check.rs b/compiler/rustc_monomorphize/src/collector/move_check.rs index b86ef1e737328..617f47ffe1fd4 100644 --- a/compiler/rustc_monomorphize/src/collector/move_check.rs +++ b/compiler/rustc_monomorphize/src/collector/move_check.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> { // but correct span? This would make the lint at least accept crate-level lint attributes. return; }; - self.tcx.emit_node_span_lint(LARGE_ASSIGNMENTS, lint_root, span, LargeAssignmentsLint { + self.tcx.emit_node_lint(LARGE_ASSIGNMENTS, lint_root, LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64, diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index d5fae6e23cb45..9cc4cc2d82a9a 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -54,6 +54,7 @@ impl Diagnostic<'_, G> for UnusedGenericParamsHint { #[diag(monomorphize_large_assignments)] #[note] pub(crate) struct LargeAssignmentsLint { + #[primary_span] #[label] pub span: Span, pub size: u64, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 61e196bdebe66..d5816db05fdb4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -44,7 +44,10 @@ use crate::{errors, fluent_generated as fluent}; #[derive(LintDiagnostic)] #[diag(passes_diagnostic_diagnostic_on_unimplemented_only_for_traits)] -struct DiagnosticOnUnimplementedOnlyForTraits; +struct DiagnosticOnUnimplementedOnlyForTraits { + #[primary_span] + pub span: Span, +} fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { match impl_item.kind { @@ -310,17 +313,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) { match attr.style { - ast::AttrStyle::Outer => self.tcx.emit_node_span_lint( + ast::AttrStyle::Outer => self.tcx.emit_node_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span, - errors::OuterCrateLevelAttr, + errors::OuterCrateLevelAttr { span: attr.span }, ), - ast::AttrStyle::Inner => self.tcx.emit_node_span_lint( + ast::AttrStyle::Inner => self.tcx.emit_node_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span, - errors::InnerCrateLevelAttr, + errors::InnerCrateLevelAttr { span: attr.span }, ), } } @@ -338,27 +339,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::IgnoredAttrWithMacro { sym }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::IgnoredAttrWithMacro { + span: attr.span, + sym, + }); } fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { - self.tcx - .emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::IgnoredAttr { sym }); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::IgnoredAttr { + span: attr.span, + sym, + }); } /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl. fn check_do_not_recommend(&self, attr_span: Span, hir_id: HirId, target: Target) { if !matches!(target, Target::Impl) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, hir_id, - attr_span, - errors::IncorrectDoNotRecommendLocation, + errors::IncorrectDoNotRecommendLocation { span: attr_span }, ); } } @@ -366,11 +366,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) { if !matches!(target, Target::Trait) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, hir_id, - attr_span, - DiagnosticOnUnimplementedOnlyForTraits, + DiagnosticOnUnimplementedOnlyForTraits { span: attr_span }, ); } } @@ -382,22 +381,20 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | Target::Closure | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {} Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span, - errors::IgnoredInlineAttrFnProto, - ) + errors::IgnoredInlineAttrFnProto { span: attr.span }, + ); } // FIXME(#65833): We permit associated consts to have an `#[inline]` attribute with // just a lint, because we previously erroneously allowed it and some crates used it // accidentally, to be compatible with crates depending on them, we can't throw an // error here. - Target::AssocConst => self.tcx.emit_node_span_lint( + Target::AssocConst => self.tcx.emit_node_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span, - errors::IgnoredInlineAttrConstants, + errors::IgnoredInlineAttrConstants { span: attr.span }, ), // FIXME(#80564): Same for fields, arms, and macro defs Target::Field | Target::Arm | Target::MacroDef => { @@ -457,15 +454,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { allowed_target: Target, ) { if target != allowed_target { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::OnlyHasEffectOn { - attr_name: attr.name_or_empty(), - target_name: allowed_target.name().replace(' ', "_"), - }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::OnlyHasEffectOn { + span: attr.span, + attr_name: attr.name_or_empty(), + target_name: allowed_target.name().replace(' ', "_"), + }); } } @@ -704,11 +697,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // FIXME: #[target_feature] was previously erroneously allowed on statements and some // crates used this, so only emit a warning. Target::Statement => { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span, - errors::TargetFeatureOnStatement, + errors::TargetFeatureOnStatement { span: attr.span }, ); } // FIXME(#80564): We permit struct fields, match arms and macro defs to have an @@ -838,12 +830,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; } if let Err(entry) = aliases.try_insert(doc_alias_str.to_owned(), span) { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::DocAliasDuplicated { span, - errors::DocAliasDuplicated { first_defn: *entry.entry.get() }, - ); + first_defn: *entry.entry.get(), + }); } } @@ -979,16 +969,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } _ => { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocInlineOnlyUse { - attr_span: meta.span(), - item_span: (attr.style == AttrStyle::Outer) - .then(|| self.tcx.hir().span(hir_id)), - }, - ); + self.tcx.emit_node_lint(INVALID_DOC_ATTRIBUTES, hir_id, errors::DocInlineOnlyUse { + span: meta.span(), + item_span: (attr.style == AttrStyle::Outer) + .then(|| self.tcx.hir().span(hir_id)), + }); } } } @@ -1001,12 +986,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { target: Target, ) { if target != Target::ExternCrate { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - meta.span(), errors::DocMaskedOnlyExternCrate { - attr_span: meta.span(), + span: meta.span(), item_span: (attr.style == AttrStyle::Outer) .then(|| self.tcx.hir().span(hir_id)), }, @@ -1015,12 +999,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } if self.tcx.extern_mod_stmt_cnum(hir_id.owner).is_none() { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - meta.span(), errors::DocMaskedNotExternCrateSelf { - attr_span: meta.span(), + span: meta.span(), item_span: (attr.style == AttrStyle::Outer) .then(|| self.tcx.hir().span(hir_id)), }, @@ -1057,12 +1040,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .then_some(errors::AttrCrateLevelOnlySugg { attr: attr.span.with_lo(bang_span).with_hi(bang_span), }); - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::AttrCrateLevelOnly { sugg }, - ); + self.tcx.emit_node_lint(INVALID_DOC_ATTRIBUTES, hir_id, errors::AttrCrateLevelOnly { + span: meta.span(), + sugg, + }); return false; } true @@ -1076,45 +1057,37 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match (i_meta.name_or_empty(), i_meta.meta_item()) { (sym::attr | sym::no_crate_inject, _) => {} (_, Some(m)) => { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span(), errors::DocTestUnknown { + span: i_meta.span(), path: rustc_ast_pretty::pprust::path_to_string(&m.path), }, ); } (_, None) => { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span(), - errors::DocTestLiteral, + errors::DocTestLiteral { span: i_meta.span() }, ); } } } } else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocTestTakesList, - ); + self.tcx.emit_node_lint(INVALID_DOC_ATTRIBUTES, hir_id, errors::DocTestTakesList { + span: meta.span(), + }); } } /// Check that the `#![doc(cfg_hide(...))]` attribute only contains a list of attributes. - /// fn check_doc_cfg_hide(&self, meta: &MetaItemInner, hir_id: HirId) { if meta.meta_item_list().is_none() { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocCfgHideTakesList, - ); + self.tcx.emit_node_lint(INVALID_DOC_ATTRIBUTES, hir_id, errors::DocCfgHideTakesList { + span: meta.span(), + }); } } @@ -1202,11 +1175,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { _ => { let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); if i_meta.has_name(sym::spotlight) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span, - errors::DocTestUnknownSpotlight { path, span: i_meta.span }, + errors::DocTestUnknownSpotlight { span: i_meta.span, path }, ); } else if i_meta.has_name(sym::include) && let Some(value) = i_meta.value_str() @@ -1218,11 +1190,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }; // If there are multiple attributes, the suggestion would suggest // deleting all of them, which is incorrect. - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span, errors::DocTestUnknownInclude { + span: i_meta.span, path, value: value.to_string(), inner: match attr.style { @@ -1235,36 +1207,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } else if i_meta.has_name(sym::passes) || i_meta.has_name(sym::no_default_passes) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span, - errors::DocTestUnknownPasses { path, span: i_meta.span }, + errors::DocTestUnknownPasses { span: i_meta.span, path }, ); } else if i_meta.has_name(sym::plugins) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span, - errors::DocTestUnknownPlugins { path, span: i_meta.span }, + errors::DocTestUnknownPlugins { span: i_meta.span, path }, ); } else { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INVALID_DOC_ATTRIBUTES, hir_id, - i_meta.span, - errors::DocTestUnknownAny { path }, + errors::DocTestUnknownAny { span: i_meta.span, path }, ); } } } } else { - self.tcx.emit_node_span_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - meta.span(), - errors::DocInvalid, - ); + self.tcx.emit_node_lint(INVALID_DOC_ATTRIBUTES, hir_id, errors::DocInvalid { + span: meta.span(), + }); } } } @@ -1343,12 +1309,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { _ => "a", }; - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseNoEffect { article, target }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::MustUseNoEffect { + span: attr.span, + article, + target, + }); } } @@ -1397,8 +1362,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { _ => { // FIXME: #[cold] was previously allowed on non-functions and some crates used // this, so only emit a warning. - self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::Cold { - span, + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::Cold { + span: attr.span, + label: span, on_crate: hir_id == CRATE_HIR_ID, }); } @@ -1415,8 +1381,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; } - self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::Link { - span: (target != Target::ForeignMod).then_some(span), + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::Link { + span: attr.span, + label: (target != Target::ForeignMod).then_some(span), }); } @@ -1434,21 +1401,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> { _ => { // FIXME: #[cold] was previously allowed on non-functions/statics and some crates // used this, so only emit a warning. - let attr_span = matches!(target, Target::ForeignMod).then_some(attr.span); + let help_sp = matches!(target, Target::ForeignMod).then_some(attr.span); if let Some(s) = attr.value_str() { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::LinkName { span, attr_span, value: s.as_str() }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::LinkName { + span: attr.span, + label: span, + help: help_sp, + value: s.as_str(), + }); } else { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::LinkName { span, attr_span, value: "..." }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::LinkName { + span: attr.span, + label: span, + help: help_sp, + value: "...", + }); }; } } @@ -1663,12 +1630,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { _ => { // FIXME: #[link_section] was previously allowed on non-functions/statics and some // crates used this, so only emit a warning. - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::LinkSection { span }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::LinkSection { + span: attr.span, + label: span, + }); } } } @@ -1694,22 +1659,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Target::ForeignStatic => "static", _ => unreachable!(), }; - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::NoMangleForeign { span, attr_span: attr.span, foreign_item_kind }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::NoMangleForeign { + span: attr.span, + label: span, + foreign_item_kind, + }); } _ => { // FIXME: #[no_mangle] was previously allowed on non-functions/statics and some // crates used this, so only emit a warning. - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::NoMangle { span }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::NoMangle { + span: attr.span, + label: span, + }); } } } @@ -1888,12 +1850,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let ItemLike::Item(item) = item { is_c_like_enum(item) } else { false } })) { - self.tcx.emit_node_span_lint( - CONFLICTING_REPR_HINTS, - hir_id, - hint_spans.collect::>(), - errors::ReprConflictingLint, - ); + self.tcx.emit_node_lint(CONFLICTING_REPR_HINTS, hir_id, errors::ReprConflictingLint { + spans: hint_spans.collect(), + }); } } @@ -2105,12 +2064,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_deprecated(&self, hir_id: HirId, attr: &Attribute, _span: Span, target: Target) { match target { Target::Closure | Target::Expression | Target::Statement | Target::Arm => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::Deprecated, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::Deprecated { + span: attr.span, + }); } _ => {} } @@ -2121,40 +2077,36 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match target { Target::ExternCrate | Target::Mod => {} _ => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MacroUse { name }, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::MacroUse { + span: attr.span, + name, + }); } } } fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) { if target != Target::MacroDef { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MacroExport::Normal, - ); + self.tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::MacroExport::Normal { + span: attr.span, + }); } else if let Some(meta_item_list) = attr.meta_item_list() - && !meta_item_list.is_empty() + && let [first_item, other_items @ ..] = meta_item_list.as_slice() { - if meta_item_list.len() > 1 { - self.tcx.emit_node_span_lint( + if !other_items.is_empty() { + self.tcx.emit_node_lint( INVALID_MACRO_EXPORT_ARGUMENTS, hir_id, - attr.span, - errors::MacroExport::TooManyItems, + errors::MacroExport::TooManyItems { span: attr.span }, ); - } else if meta_item_list[0].name_or_empty() != sym::local_inner_macros { - self.tcx.emit_node_span_lint( + } else if first_item.name_or_empty() != sym::local_inner_macros { + self.tcx.emit_node_lint( INVALID_MACRO_EXPORT_ARGUMENTS, hir_id, - meta_item_list[0].span(), - errors::MacroExport::UnknownItem { name: meta_item_list[0].name_or_empty() }, + errors::MacroExport::UnknownItem { + span: first_item.span(), + name: first_item.name_or_empty(), + }, ); } } else { @@ -2163,11 +2115,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let is_decl_macro = !macro_definition.macro_rules; if is_decl_macro { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span, - errors::MacroExport::OnDeclMacro, + errors::MacroExport::OnDeclMacro { span: attr.span }, ); } } @@ -2205,10 +2156,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; }; - self.tcx.emit_node_span_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::Unused { - attr_span: attr.span, - note, - }); + self.tcx + .emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::Unused { span: attr.span, note }); } /// A best effort attempt to create an error for a mismatching proc macro signature. @@ -2591,19 +2540,11 @@ fn check_duplicates( } else { (attr.span, *entry.get()) }; - tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - this, - errors::UnusedDuplicate { - this, - other, - warning: matches!( - duplicates, - FutureWarnFollowing | FutureWarnPreceding - ), - }, - ); + tcx.emit_node_lint(UNUSED_ATTRIBUTES, hir_id, errors::UnusedDuplicate { + span: this, + other, + warning: matches!(duplicates, FutureWarnFollowing | FutureWarnPreceding), + }); } Entry::Vacant(entry) => { entry.insert(attr.span); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index af17fbf7e4df3..5449cb91f3c0f 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -8,7 +8,6 @@ use std::mem; use hir::ItemKind; use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::MultiSpan; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; @@ -213,12 +212,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { && !assign.span.from_expansion() { let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..)); - self.tcx.emit_node_span_lint( - lint::builtin::DEAD_CODE, - assign.hir_id, - assign.span, - UselessAssignment { is_field_assign, ty: self.typeck_results().expr_ty(lhs) }, - ) + self.tcx.emit_node_lint(lint::builtin::DEAD_CODE, assign.hir_id, UselessAssignment { + span: assign.span, + is_field_assign, + ty: self.typeck_results().expr_ty(lhs), + }) } } @@ -1083,6 +1081,7 @@ impl<'tcx> DeadVisitor<'tcx> { }; MultipleDeadCodes::UnusedTupleStructFields { + spans, multiple, num, descr, @@ -1094,6 +1093,7 @@ impl<'tcx> DeadVisitor<'tcx> { } } ReportOn::NamedField => MultipleDeadCodes::DeadCodes { + spans, multiple, num, descr, @@ -1105,7 +1105,7 @@ impl<'tcx> DeadVisitor<'tcx> { }; let hir_id = tcx.local_def_id_to_hir_id(first_item.def_id); - self.tcx.emit_node_span_lint(DEAD_CODE, hir_id, MultiSpan::from_spans(spans), diag); + self.tcx.emit_node_lint(DEAD_CODE, hir_id, diag); } fn warn_multiple( diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 042e50d890e9e..2734af4672d53 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -18,7 +18,10 @@ use crate::lang_items::Duplicate; #[derive(LintDiagnostic)] #[diag(passes_incorrect_do_not_recommend_location)] -pub(crate) struct IncorrectDoNotRecommendLocation; +pub(crate) struct IncorrectDoNotRecommendLocation { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(passes_autodiff_attr)] @@ -30,33 +33,49 @@ pub(crate) struct AutoDiffAttr { #[derive(LintDiagnostic)] #[diag(passes_outer_crate_level_attr)] -pub(crate) struct OuterCrateLevelAttr; +pub(crate) struct OuterCrateLevelAttr { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_inner_crate_level_attr)] -pub(crate) struct InnerCrateLevelAttr; +pub(crate) struct InnerCrateLevelAttr { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_ignored_attr_with_macro)] pub(crate) struct IgnoredAttrWithMacro<'a> { + #[primary_span] + pub span: Span, pub sym: &'a str, } #[derive(LintDiagnostic)] #[diag(passes_ignored_attr)] pub(crate) struct IgnoredAttr<'a> { + #[primary_span] + pub span: Span, pub sym: &'a str, } #[derive(LintDiagnostic)] #[diag(passes_inline_ignored_function_prototype)] -pub(crate) struct IgnoredInlineAttrFnProto; +pub(crate) struct IgnoredInlineAttrFnProto { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_inline_ignored_constants)] #[warning] #[note] -pub(crate) struct IgnoredInlineAttrConstants; +pub(crate) struct IgnoredInlineAttrConstants { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(passes_inline_not_fn_or_closure, code = E0518)] @@ -126,7 +145,10 @@ pub(crate) struct AttrShouldBeAppliedToTrait { #[derive(LintDiagnostic)] #[diag(passes_target_feature_on_statement)] -pub(crate) struct TargetFeatureOnStatement; +pub(crate) struct TargetFeatureOnStatement { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_static)] @@ -190,6 +212,8 @@ pub(crate) struct DocAliasNotAnAlias<'a> { #[derive(LintDiagnostic)] #[diag(passes_doc_alias_duplicated)] pub(crate) struct DocAliasDuplicated { + #[primary_span] + pub span: Span, #[label] pub first_defn: Span, } @@ -256,8 +280,9 @@ pub(crate) struct DocKeywordConflict { #[diag(passes_doc_inline_only_use)] #[note] pub(crate) struct DocInlineOnlyUse { + #[primary_span] #[label] - pub attr_span: Span, + pub span: Span, #[label(passes_not_a_use_item_label)] pub item_span: Option, } @@ -266,8 +291,9 @@ pub(crate) struct DocInlineOnlyUse { #[diag(passes_doc_masked_only_extern_crate)] #[note] pub(crate) struct DocMaskedOnlyExternCrate { + #[primary_span] #[label] - pub attr_span: Span, + pub span: Span, #[label(passes_not_an_extern_crate_label)] pub item_span: Option, } @@ -275,8 +301,9 @@ pub(crate) struct DocMaskedOnlyExternCrate { #[derive(LintDiagnostic)] #[diag(passes_doc_masked_not_extern_crate_self)] pub(crate) struct DocMaskedNotExternCrateSelf { + #[primary_span] #[label] - pub attr_span: Span, + pub span: Span, #[label(passes_extern_crate_self_label)] pub item_span: Option, } @@ -292,24 +319,37 @@ pub(crate) struct DocAttrNotCrateLevel<'a> { #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown)] pub(crate) struct DocTestUnknown { + #[primary_span] + pub span: Span, pub path: String, } #[derive(LintDiagnostic)] #[diag(passes_doc_test_literal)] -pub(crate) struct DocTestLiteral; +pub(crate) struct DocTestLiteral { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_doc_test_takes_list)] -pub(crate) struct DocTestTakesList; +pub(crate) struct DocTestTakesList { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_doc_cfg_hide_takes_list)] -pub(crate) struct DocCfgHideTakesList; +pub(crate) struct DocCfgHideTakesList { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_any)] pub(crate) struct DocTestUnknownAny { + #[primary_span] + pub span: Span, pub path: String, } @@ -318,9 +358,10 @@ pub(crate) struct DocTestUnknownAny { #[note] #[note(passes_no_op_note)] pub(crate) struct DocTestUnknownSpotlight { - pub path: String, + #[primary_span] #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] pub span: Span, + pub path: String, } #[derive(LintDiagnostic)] @@ -329,9 +370,10 @@ pub(crate) struct DocTestUnknownSpotlight { #[help] #[note(passes_no_op_note)] pub(crate) struct DocTestUnknownPasses { - pub path: String, + #[primary_span] #[label] pub span: Span, + pub path: String, } #[derive(LintDiagnostic)] @@ -339,14 +381,17 @@ pub(crate) struct DocTestUnknownPasses { #[note] #[note(passes_no_op_note)] pub(crate) struct DocTestUnknownPlugins { - pub path: String, + #[primary_span] #[label] pub span: Span, + pub path: String, } #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_include)] pub(crate) struct DocTestUnknownInclude { + #[primary_span] + pub span: Span, pub path: String, pub value: String, pub inner: &'static str, @@ -356,7 +401,10 @@ pub(crate) struct DocTestUnknownInclude { #[derive(LintDiagnostic)] #[diag(passes_doc_invalid)] -pub(crate) struct DocInvalid; +pub(crate) struct DocInvalid { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(passes_pass_by_value)] @@ -409,6 +457,8 @@ pub(crate) struct FfiConstInvalidTarget { #[derive(LintDiagnostic)] #[diag(passes_must_use_no_effect)] pub(crate) struct MustUseNoEffect { + #[primary_span] + pub span: Span, pub article: &'static str, pub target: rustc_hir::Target, } @@ -426,8 +476,10 @@ pub(crate) struct MustNotSuspend { #[diag(passes_cold)] #[warning] pub(crate) struct Cold { - #[label] + #[primary_span] pub span: Span, + #[label] + pub label: Span, pub on_crate: bool, } @@ -435,18 +487,22 @@ pub(crate) struct Cold { #[diag(passes_link)] #[warning] pub(crate) struct Link { + #[primary_span] + pub span: Span, #[label] - pub span: Option, + pub label: Option, } #[derive(LintDiagnostic)] #[diag(passes_link_name)] #[warning] pub(crate) struct LinkName<'a> { + #[primary_span] + pub span: Span, #[help] - pub attr_span: Option, + pub help: Option, #[label] - pub span: Span, + pub label: Span, pub value: &'a str, } @@ -529,8 +585,10 @@ pub(crate) struct RustcDirtyClean { #[diag(passes_link_section)] #[warning] pub(crate) struct LinkSection { - #[label] + #[primary_span] pub span: Span, + #[label] + pub label: Span, } #[derive(LintDiagnostic)] @@ -538,10 +596,11 @@ pub(crate) struct LinkSection { #[warning] #[note] pub(crate) struct NoMangleForeign { - #[label] - pub span: Span, + #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] - pub attr_span: Span, + pub span: Span, + #[label] + pub label: Span, pub foreign_item_kind: &'static str, } @@ -549,8 +608,10 @@ pub(crate) struct NoMangleForeign { #[diag(passes_no_mangle)] #[warning] pub(crate) struct NoMangle { - #[label] + #[primary_span] pub span: Span, + #[label] + pub label: Span, } #[derive(Diagnostic)] @@ -569,7 +630,10 @@ pub(crate) struct ReprConflicting { #[derive(LintDiagnostic)] #[diag(passes_repr_conflicting, code = E0566)] -pub(crate) struct ReprConflictingLint; +pub(crate) struct ReprConflictingLint { + #[primary_span] + pub spans: Vec, +} #[derive(Diagnostic)] #[diag(passes_used_static)] @@ -723,28 +787,46 @@ pub(crate) struct StabilityPromotable { #[derive(LintDiagnostic)] #[diag(passes_deprecated)] -pub(crate) struct Deprecated; +pub(crate) struct Deprecated { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_macro_use)] pub(crate) struct MacroUse { + #[primary_span] + pub span: Span, pub name: Symbol, } #[derive(LintDiagnostic)] pub(crate) enum MacroExport { #[diag(passes_macro_export)] - Normal, + Normal { + #[primary_span] + span: Span, + }, #[diag(passes_macro_export_on_decl_macro)] #[note] - OnDeclMacro, + OnDeclMacro { + #[primary_span] + span: Span, + }, #[diag(passes_invalid_macro_export_arguments)] - UnknownItem { name: Symbol }, + UnknownItem { + #[primary_span] + span: Span, + name: Symbol, + }, #[diag(passes_invalid_macro_export_arguments_too_many_items)] - TooManyItems, + TooManyItems { + #[primary_span] + span: Span, + }, } #[derive(Subdiagnostic)] @@ -760,8 +842,9 @@ pub(crate) enum UnusedNote { #[derive(LintDiagnostic)] #[diag(passes_unused)] pub(crate) struct Unused { + #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] - pub attr_span: Span, + pub span: Span, #[subdiagnostic] pub note: UnusedNote, } @@ -784,8 +867,9 @@ pub(crate) struct InvalidMayDangle { #[derive(LintDiagnostic)] #[diag(passes_unused_duplicate)] pub(crate) struct UnusedDuplicate { + #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] - pub this: Span, + pub span: Span, #[note] pub other: Span, #[warning] @@ -833,6 +917,7 @@ pub(crate) struct CollapseDebuginfo { #[derive(LintDiagnostic)] #[diag(passes_deprecated_annotation_has_no_effect)] pub(crate) struct DeprecatedAnnotationHasNoEffect { + #[primary_span] #[suggestion(applicability = "machine-applicable", code = "")] pub span: Span, } @@ -1182,7 +1267,10 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> { #[derive(LintDiagnostic)] #[diag(passes_undefined_naked_function_abi)] -pub(crate) struct UndefinedNakedFunctionAbi; +pub(crate) struct UndefinedNakedFunctionAbi { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(passes_no_patterns)] @@ -1414,6 +1502,8 @@ pub(crate) struct IncorrectTarget<'a> { #[derive(LintDiagnostic)] #[diag(passes_useless_assignment)] pub(crate) struct UselessAssignment<'a> { + #[primary_span] + pub span: Span, pub is_field_assign: bool, pub ty: Ty<'a>, } @@ -1421,6 +1511,8 @@ pub(crate) struct UselessAssignment<'a> { #[derive(LintDiagnostic)] #[diag(passes_only_has_effect_on)] pub(crate) struct OnlyHasEffectOn { + #[primary_span] + pub span: Span, pub attr_name: Symbol, pub target_name: String, } @@ -1588,6 +1680,8 @@ pub(crate) struct MissingConstErr { pub(crate) enum MultipleDeadCodes<'tcx> { #[diag(passes_dead_codes)] DeadCodes { + #[primary_span] + spans: Vec, multiple: bool, num: usize, descr: &'tcx str, @@ -1600,6 +1694,8 @@ pub(crate) enum MultipleDeadCodes<'tcx> { }, #[diag(passes_dead_codes)] UnusedTupleStructFields { + #[primary_span] + spans: Vec, multiple: bool, num: usize, descr: &'tcx str, @@ -1665,12 +1761,13 @@ pub(crate) struct SkippingConstChecks { #[derive(LintDiagnostic)] #[diag(passes_unreachable_due_to_uninhabited)] pub(crate) struct UnreachableDueToUninhabited<'desc, 'tcx> { - pub descr: &'desc str, + #[primary_span] #[label] - pub expr: Span, + pub span: Span, #[label(passes_label_orig)] #[note] pub orig: Span, + pub descr: &'desc str, pub ty: Ty<'tcx>, } @@ -1678,6 +1775,8 @@ pub(crate) struct UnreachableDueToUninhabited<'desc, 'tcx> { #[diag(passes_unused_var_maybe_capture_ref)] #[help] pub(crate) struct UnusedVarMaybeCaptureRef { + #[primary_span] + pub span: Span, pub name: String, } @@ -1685,12 +1784,16 @@ pub(crate) struct UnusedVarMaybeCaptureRef { #[diag(passes_unused_capture_maybe_capture_ref)] #[help] pub(crate) struct UnusedCaptureMaybeCaptureRef { + #[primary_span] + pub span: Span, pub name: String, } #[derive(LintDiagnostic)] #[diag(passes_unused_var_remove_field)] pub(crate) struct UnusedVarRemoveField { + #[primary_span] + pub spans: Vec, pub name: String, #[subdiagnostic] pub sugg: UnusedVarRemoveFieldSugg, @@ -1710,12 +1813,16 @@ pub(crate) struct UnusedVarRemoveFieldSugg { #[diag(passes_unused_var_assigned_only)] #[note] pub(crate) struct UnusedVarAssignedOnly { + #[primary_span] + pub spans: Vec, pub name: String, } #[derive(LintDiagnostic)] #[diag(passes_unnecessary_stable_feature)] pub(crate) struct UnnecessaryStableFeature { + #[primary_span] + pub span: Span, pub feature: Symbol, pub since: Symbol, } @@ -1723,6 +1830,7 @@ pub(crate) struct UnnecessaryStableFeature { #[derive(LintDiagnostic)] #[diag(passes_unnecessary_partial_stable_feature)] pub(crate) struct UnnecessaryPartialStableFeature { + #[primary_span] #[suggestion(code = "{implies}", applicability = "maybe-incorrect")] pub span: Span, #[suggestion(passes_suggestion_remove, code = "", applicability = "maybe-incorrect")] @@ -1735,12 +1843,17 @@ pub(crate) struct UnnecessaryPartialStableFeature { #[derive(LintDiagnostic)] #[diag(passes_ineffective_unstable_impl)] #[note] -pub(crate) struct IneffectiveUnstableImpl; +pub(crate) struct IneffectiveUnstableImpl { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(passes_unused_assign)] #[help] pub(crate) struct UnusedAssign { + #[primary_span] + pub spans: Vec, pub name: String, } @@ -1748,12 +1861,16 @@ pub(crate) struct UnusedAssign { #[diag(passes_unused_assign_passed)] #[help] pub(crate) struct UnusedAssignPassed { + #[primary_span] + pub spans: Vec, pub name: String, } #[derive(LintDiagnostic)] #[diag(passes_unused_variable_try_prefix)] pub(crate) struct UnusedVariableTryPrefix { + #[primary_span] + pub spans: Vec, #[label] pub label: Option, #[subdiagnostic] @@ -1803,6 +1920,8 @@ impl Subdiagnostic for UnusedVariableStringInterp { #[derive(LintDiagnostic)] #[diag(passes_unused_variable_try_ignore)] pub(crate) struct UnusedVarTryIgnore { + #[primary_span] + pub spans: Vec, #[subdiagnostic] pub sugg: UnusedVarTryIgnoreSugg, } @@ -1821,6 +1940,8 @@ pub(crate) struct UnusedVarTryIgnoreSugg { #[diag(passes_attr_crate_level)] #[note] pub(crate) struct AttrCrateLevelOnly { + #[primary_span] + pub span: Span, #[subdiagnostic] pub sugg: Option, } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 366f7dd293c44..601c1b18d885c 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1331,12 +1331,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // that we do not emit the same warning twice if the uninhabited type // is indeed `!`. - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNREACHABLE_CODE, expr_id, - expr_span, errors::UnreachableDueToUninhabited { - expr: expr_span, + span: expr_span, orig: orig_span, descr, ty: orig_ty, @@ -1492,20 +1491,18 @@ impl<'tcx> Liveness<'_, 'tcx> { if self.used_on_entry(entry_ln, var) { if !self.live_on_entry(entry_ln, var) { if let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_ASSIGNMENTS, var_hir_id, - vec![span], - errors::UnusedCaptureMaybeCaptureRef { name }, + errors::UnusedCaptureMaybeCaptureRef { span, name }, ); } } } else if let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_VARIABLES, var_hir_id, - vec![span], - errors::UnusedVarMaybeCaptureRef { name }, + errors::UnusedVarMaybeCaptureRef { span, name }, ); } } @@ -1522,11 +1519,10 @@ impl<'tcx> Liveness<'_, 'tcx> { if !self.live_on_entry(ln, var) && let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_ASSIGNMENTS, hir_id, - spans, - errors::UnusedAssignPassed { name }, + errors::UnusedAssignPassed { spans, name }, ); } }, @@ -1596,17 +1592,16 @@ impl<'tcx> Liveness<'_, 'tcx> { if ln == self.exit_ln { false } else { self.assigned_on_exit(ln, var) }; if is_assigned { - self.ir.tcx.emit_node_span_lint( + let spans = + hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect(); + + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans - .into_iter() - .map(|(_, _, ident_span)| ident_span) - .collect::>(), - errors::UnusedVarAssignedOnly { name }, + errors::UnusedVarAssignedOnly { spans, name }, ) } else if can_remove { - let spans = hir_ids_and_spans + let sugg_spans = hir_ids_and_spans .iter() .map(|(_, pat_span, _)| { let span = self @@ -1618,13 +1613,13 @@ impl<'tcx> Liveness<'_, 'tcx> { span.with_hi(BytePos(span.hi().0 + 1)) }) .collect(); - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::>(), errors::UnusedVarRemoveField { + spans: hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect(), name, - sugg: errors::UnusedVarRemoveFieldSugg { spans }, + sugg: errors::UnusedVarRemoveFieldSugg { spans: sugg_spans }, }, ); } else { @@ -1643,14 +1638,14 @@ impl<'tcx> Liveness<'_, 'tcx> { let non_shorthands = non_shorthands.into_iter().map(|(_, pat_span, _)| pat_span).collect(); - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans - .iter() - .map(|(_, pat_span, _)| *pat_span) - .collect::>(), errors::UnusedVarTryIgnore { + spans: hir_ids_and_spans + .iter() + .map(|(_, pat_span, _)| *pat_span) + .collect(), sugg: errors::UnusedVarTryIgnoreSugg { shorthands, non_shorthands, @@ -1682,14 +1677,14 @@ impl<'tcx> Liveness<'_, 'tcx> { } }; - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans - .iter() - .map(|(_, _, ident_span)| *ident_span) - .collect::>(), errors::UnusedVariableTryPrefix { + spans: hir_ids_and_spans + .iter() + .map(|(_, _, ident_span)| *ident_span) + .collect(), label: if !suggestions.is_empty() { Some(pat.span) } else { None }, name, sugg, @@ -1734,11 +1729,10 @@ impl<'tcx> Liveness<'_, 'tcx> { if !self.live_on_exit(ln, var) && let Some(name) = self.should_warn(var) { - self.ir.tcx.emit_node_span_lint( + self.ir.tcx.emit_node_lint( lint::builtin::UNUSED_ASSIGNMENTS, hir_id, - spans, - errors::UnusedAssign { name }, + errors::UnusedAssign { spans, name }, ); } } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index b2f8d7dadff37..9356e330e77b9 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -63,12 +63,9 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) { if abi == Abi::Rust { let hir_id = tcx.local_def_id_to_hir_id(def_id); let span = tcx.def_span(def_id); - tcx.emit_node_span_lint( - UNDEFINED_NAKED_FUNCTION_ABI, - hir_id, + tcx.emit_node_lint(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, UndefinedNakedFunctionAbi { span, - UndefinedNakedFunctionAbi, - ); + }); } } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index a176b2bb1ad41..4eac5d0ace86e 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -120,21 +120,20 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { let depr = attr::find_deprecation(self.tcx.sess, self.tcx.features(), attrs); let mut is_deprecated = false; - if let Some((depr, span)) = &depr { + if let Some((depr, span)) = depr { is_deprecated = true; if matches!(kind, AnnotationKind::Prohibited | AnnotationKind::DeprecationProhibited) { let hir_id = self.tcx.local_def_id_to_hir_id(def_id); - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( USELESS_DEPRECATED, hir_id, - *span, - errors::DeprecatedAnnotationHasNoEffect { span: *span }, + errors::DeprecatedAnnotationHasNoEffect { span }, ); } // `Deprecation` is just two pointers, no need to intern it - let depr_entry = DeprecationEntry::local(*depr, def_id); + let depr_entry = DeprecationEntry::local(depr, def_id); self.index.depr_map.insert(def_id, depr_entry); } else if let Some(parent_depr) = self.parent_depr { if inherit_deprecation.yes() { @@ -751,11 +750,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // do not lint when the trait isn't resolved, since resolution error should // be fixed first if t.path.res != Res::Err && c.fully_stable { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), - span, - errors::IneffectiveUnstableImpl, + errors::IneffectiveUnstableImpl { span }, ); } } @@ -1081,10 +1079,9 @@ fn unnecessary_partially_stable_feature_lint( implies: Symbol, since: Symbol, ) { - tcx.emit_node_span_lint( + tcx.emit_node_lint( lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, - span, errors::UnnecessaryPartialStableFeature { span, line: tcx.sess.source_map().span_extend_to_line(span), @@ -1104,10 +1101,9 @@ fn unnecessary_stable_feature_lint( if since.as_str() == VERSION_PLACEHOLDER { since = sym::env_CFG_RELEASE; } - tcx.emit_node_span_lint( + tcx.emit_node_lint( lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, - span, - errors::UnnecessaryStableFeature { feature, since }, + errors::UnnecessaryStableFeature { span, feature, since }, ); } diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs index 1f7852e5190d2..644c82711e652 100644 --- a/compiler/rustc_pattern_analysis/src/errors.rs +++ b/compiler/rustc_pattern_analysis/src/errors.rs @@ -43,10 +43,11 @@ impl Uncovered { #[diag(pattern_analysis_overlapping_range_endpoints)] #[note] pub struct OverlappingRangeEndpoints { + #[primary_span] #[label] - pub range: Span, + pub span: Span, #[subdiagnostic] - pub overlap: Vec, + pub overlaps: Vec, } pub struct Overlap { @@ -72,10 +73,11 @@ impl Subdiagnostic for Overlap { #[derive(LintDiagnostic)] #[diag(pattern_analysis_excluside_range_missing_max)] pub struct ExclusiveRangeMissingMax { + #[primary_span] #[label] #[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")] /// This is an exclusive range that looks like `lo..max` (i.e. doesn't match `max`). - pub first_range: Span, + pub span: Span, /// Suggest `lo..=max` instead. pub suggestion: String, pub max: String, // a printed pattern @@ -84,10 +86,11 @@ pub struct ExclusiveRangeMissingMax { #[derive(LintDiagnostic)] #[diag(pattern_analysis_excluside_range_missing_gap)] pub struct ExclusiveRangeMissingGap { + #[primary_span] #[label] #[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")] /// This is an exclusive range that looks like `lo..gap` (i.e. doesn't match `gap`). - pub first_range: Span, + pub span: Span, pub gap: String, // a printed pattern /// Suggest `lo..=gap` instead. pub suggestion: String, @@ -125,6 +128,8 @@ impl Subdiagnostic for GappedRange { #[help] #[note] pub(crate) struct NonExhaustiveOmittedPattern<'tcx> { + #[primary_span] + pub span: Span, pub scrut_ty: Ty<'tcx>, #[subdiagnostic] pub uncovered: Uncovered, @@ -134,6 +139,8 @@ pub(crate) struct NonExhaustiveOmittedPattern<'tcx> { #[diag(pattern_analysis_non_exhaustive_omitted_pattern_lint_on_arm)] #[help] pub(crate) struct NonExhaustiveOmittedPatternLintOnArm { + #[primary_span] + pub span: Span, #[label] pub lint_span: Span, #[suggestion(code = "#[{lint_level}({lint_name})]\n", applicability = "maybe-incorrect")] diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs index 585cda1d24b7f..8d4c3550cf898 100644 --- a/compiler/rustc_pattern_analysis/src/lints.rs +++ b/compiler/rustc_pattern_analysis/src/lints.rs @@ -73,11 +73,11 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>( // is not exhaustive enough. // // NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`. - rcx.tcx.emit_node_span_lint( + rcx.tcx.emit_node_lint( NON_EXHAUSTIVE_OMITTED_PATTERNS, rcx.match_lint_level, - rcx.scrut_span, NonExhaustiveOmittedPattern { + span: rcx.scrut_span, scrut_ty: scrut_ty.inner(), uncovered: Uncovered::new(rcx.scrut_span, rcx, witnesses), }, @@ -91,7 +91,8 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>( let (lint_level, lint_level_source) = rcx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.arm_data); if !matches!(lint_level, rustc_session::lint::Level::Allow) { - let decorator = NonExhaustiveOmittedPatternLintOnArm { + let lint = NonExhaustiveOmittedPatternLintOnArm { + span: arm.pat.data().span, lint_span: lint_level_source.span(), suggest_lint_on_match: rcx.whole_match_span.map(|span| span.shrink_to_lo()), lint_level: lint_level.as_str(), @@ -99,9 +100,9 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>( }; use rustc_errors::LintDiagnostic; - let mut err = rcx.tcx.dcx().struct_span_warn(arm.pat.data().span, ""); - decorator.decorate_lint(&mut err); - err.emit(); + let mut diag = rcx.tcx.dcx().struct_span_warn(lint.span, ""); + lint.decorate_lint(&mut diag); + diag.emit(); } } } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 0e132b27fb4cd..d47adc04ae1c3 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -977,17 +977,15 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { overlaps_with: &[&crate::pat::DeconstructedPat], ) { let overlap_as_pat = self.print_pat_range(&overlaps_on, *pat.ty()); - let overlaps: Vec<_> = overlaps_with + let overlaps = overlaps_with .iter() .map(|pat| pat.data().span) .map(|span| errors::Overlap { range: overlap_as_pat.to_string(), span }) .collect(); - let pat_span = pat.data().span; - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, self.match_lint_level, - pat_span, - errors::OverlappingRangeEndpoints { overlap: overlaps, range: pat_span }, + errors::OverlappingRangeEndpoints { span: pat.data().span, overlaps }, ); } @@ -1019,13 +1017,12 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { let gap_as_pat = self.print_pat_range(&gap, *pat.ty()); if gapped_with.is_empty() { // If `gapped_with` is empty, `gap == T::MAX`. - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint::builtin::NON_CONTIGUOUS_RANGE_ENDPOINTS, self.match_lint_level, - thir_pat.span, errors::ExclusiveRangeMissingMax { // Point at this range. - first_range: thir_pat.span, + span: thir_pat.span, // That's the gap that isn't covered. max: gap_as_pat, // Suggest `lo..=max` instead. @@ -1033,13 +1030,12 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { }, ); } else { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint::builtin::NON_CONTIGUOUS_RANGE_ENDPOINTS, self.match_lint_level, - thir_pat.span, errors::ExclusiveRangeMissingGap { // Point at this range. - first_range: thir_pat.span, + span: thir_pat.span, // That's the gap that isn't covered. gap: gap_as_pat.to_string(), // Suggest `lo..=gap` instead. diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index f5e641eb64243..33186904057f3 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -72,6 +72,8 @@ pub(crate) struct ReportEffectiveVisibility { #[derive(LintDiagnostic)] #[diag(privacy_from_private_dep_in_public_interface)] pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { + #[primary_span] + pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, pub krate: Symbol, @@ -80,6 +82,7 @@ pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { #[derive(LintDiagnostic)] #[diag(privacy_unnameable_types_lint)] pub(crate) struct UnnameableTypesLint<'a> { + #[primary_span] #[label] pub span: Span, pub kind: &'a str, @@ -94,8 +97,9 @@ pub(crate) struct UnnameableTypesLint<'a> { #[derive(LintDiagnostic)] #[diag(privacy_private_interface_or_bounds_lint)] pub(crate) struct PrivateInterfacesOrBoundsLint<'a> { + #[primary_span] #[label(privacy_item_label)] - pub item_span: Span, + pub span: Span, pub item_kind: &'a str, pub item_descr: DiagArgFromDisplay<'a>, pub item_vis_descr: &'a str, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 7827975d3cafb..a1217c41a613d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1296,11 +1296,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display) -> bool { if self.leaks_private_dep(def_id) { - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint::builtin::EXPORTED_PRIVATE_DEPENDENCIES, self.tcx.local_def_id_to_hir_id(self.item_def_id), - self.tcx.def_span(self.item_def_id.to_def_id()), FromPrivateDependencyInPublicInterface { + span: self.tcx.def_span(self.item_def_id), kind, descr: descr.into(), krate: self.tcx.crate_name(def_id.krate), @@ -1353,12 +1353,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } else { lint::builtin::PRIVATE_BOUNDS }; - self.tcx.emit_node_span_lint( + self.tcx.emit_node_lint( lint, self.tcx.local_def_id_to_hir_id(self.item_def_id), - span, PrivateInterfacesOrBoundsLint { - item_span: span, + span, item_kind: self.tcx.def_descr(self.item_def_id.to_def_id()), item_descr: (&LazyDefPathStr { def_id: self.item_def_id.to_def_id(), @@ -1441,18 +1440,13 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> { if reachable_at_vis.is_public() && reexported_at_vis != reachable_at_vis { let hir_id = self.tcx.local_def_id_to_hir_id(def_id); let span = self.tcx.def_span(def_id.to_def_id()); - self.tcx.emit_node_span_lint( - lint::builtin::UNNAMEABLE_TYPES, - hir_id, + self.tcx.emit_node_lint(lint::builtin::UNNAMEABLE_TYPES, hir_id, UnnameableTypesLint { span, - UnnameableTypesLint { - span, - kind: self.tcx.def_descr(def_id.to_def_id()), - descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(), - reachable_vis: &reachable_at_vis.to_string(def_id, self.tcx), - reexported_vis: &reexported_at_vis.to_string(def_id, self.tcx), - }, - ); + kind: self.tcx.def_descr(def_id.to_def_id()), + descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(), + reachable_vis: &reachable_at_vis.to_string(def_id, self.tcx), + reexported_vis: &reexported_at_vis.to_string(def_id, self.tcx), + }); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 7f42c932fcf57..820b9e8ffd788 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -318,29 +318,28 @@ pub enum AppendConstMessage { #[diag(trait_selection_malformed_on_unimplemented_attr)] #[help] pub struct MalformedOnUnimplementedAttrLint { + #[primary_span] #[label] pub span: Span, } -impl MalformedOnUnimplementedAttrLint { - fn new(span: Span) -> Self { - Self { span } - } -} - #[derive(LintDiagnostic)] #[diag(trait_selection_missing_options_for_on_unimplemented_attr)] #[help] -pub struct MissingOptionsForOnUnimplementedAttr; +pub struct MissingOptionsForOnUnimplementedAttr { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(trait_selection_ignored_diagnostic_option)] pub struct IgnoredDiagnosticOption { - pub option_name: &'static str, + #[primary_span] #[label] pub span: Span, #[label(trait_selection_other_label)] pub prev_span: Span, + pub option_name: &'static str, } impl IgnoredDiagnosticOption { @@ -353,10 +352,9 @@ impl IgnoredDiagnosticOption { ) { if let (Some(new_item), Some(old_item)) = (new, old) { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - new_item, IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name }, ); } @@ -368,6 +366,8 @@ impl IgnoredDiagnosticOption { #[diag(trait_selection_unknown_format_parameter_for_on_unimplemented_attr)] #[help] pub struct UnknownFormatParameterForOnUnimplementedAttr { + #[primary_span] + span: Span, argument_name: Symbol, trait_name: Symbol, } @@ -375,16 +375,24 @@ pub struct UnknownFormatParameterForOnUnimplementedAttr { #[derive(LintDiagnostic)] #[diag(trait_selection_disallowed_positional_argument)] #[help] -pub struct DisallowedPositionalArgument; +pub struct DisallowedPositionalArgument { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(trait_selection_invalid_format_specifier)] #[help] -pub struct InvalidFormatSpecifier; +pub struct InvalidFormatSpecifier { + #[primary_span] + pub span: Span, +} #[derive(LintDiagnostic)] #[diag(trait_selection_wrapped_parser_error)] pub struct WrappedParserError { + #[primary_span] + span: Span, description: String, label: String, } @@ -504,11 +512,10 @@ impl<'tcx> OnUnimplementedDirective { if is_diagnostic_namespace_variant { if let Some(def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(def_id), - vec![item.span()], - MalformedOnUnimplementedAttrLint::new(item.span()), + MalformedOnUnimplementedAttrLint { span: item.span() }, ); } } else { @@ -644,11 +651,10 @@ impl<'tcx> OnUnimplementedDirective { }; if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - report_span, - MalformedOnUnimplementedAttrLint::new(report_span), + MalformedOnUnimplementedAttrLint { span: report_span }, ); } Ok(None) @@ -657,21 +663,19 @@ impl<'tcx> OnUnimplementedDirective { match &attr.kind { AttrKind::Normal(p) if !matches!(p.item.args, AttrArgs::Empty) => { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - attr.span, - MalformedOnUnimplementedAttrLint::new(attr.span), + MalformedOnUnimplementedAttrLint { span: attr.span }, ); } } _ => { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - attr.span, - MissingOptionsForOnUnimplementedAttr, + MissingOptionsForOnUnimplementedAttr { span: attr.span }, ) } } @@ -804,11 +808,10 @@ impl<'tcx> OnUnimplementedFormatString { || format_spec.fill_span.is_some()) { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - self.span, - InvalidFormatSpecifier, + InvalidFormatSpecifier { span: self.span }, ); } } @@ -827,11 +830,11 @@ impl<'tcx> OnUnimplementedFormatString { s => { if self.is_diagnostic_namespace_variant { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - self.span, UnknownFormatParameterForOnUnimplementedAttr { + span: self.span, argument_name: s, trait_name, }, @@ -859,11 +862,10 @@ impl<'tcx> OnUnimplementedFormatString { Position::ArgumentIs(..) | Position::ArgumentImplicitlyIs(_) => { if self.is_diagnostic_namespace_variant { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - self.span, - DisallowedPositionalArgument, + DisallowedPositionalArgument { span: self.span }, ); } } else { @@ -889,11 +891,14 @@ impl<'tcx> OnUnimplementedFormatString { for e in parser.errors { if self.is_diagnostic_namespace_variant { if let Some(item_def_id) = item_def_id.as_local() { - tcx.emit_node_span_lint( + tcx.emit_node_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, tcx.local_def_id_to_hir_id(item_def_id), - self.span, - WrappedParserError { description: e.description, label: e.label }, + WrappedParserError { + span: self.span, + description: e.description, + label: e.label, + }, ); } } else { From 7072c99018fa58564f3c661d148be0ea59ee1be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 17 May 2024 17:31:02 +0200 Subject: [PATCH 3/4] Update fulldeps UI tests to the new lint diagnostic API --- .../ui-fulldeps/internal-lints/diagnostics.rs | 10 ++- .../internal-lints/diagnostics.stderr | 14 +-- .../session-diagnostic/diagnostic-derive.rs | 1 - .../diagnostic-derive.stderr | 86 +++++++++---------- 4 files changed, 55 insertions(+), 56 deletions(-) diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 442f9d72c3f19..8aba70340ea85 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -14,7 +14,7 @@ extern crate rustc_session; extern crate rustc_span; use rustc_errors::{ - Diag, DiagCtxtHandle, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level, + Diag, DiagCtxtHandle, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan, LintDiagnostic, SubdiagMessage, SubdiagMessageOp, Subdiagnostic, }; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -85,6 +85,10 @@ impl<'a> LintDiagnostic<'a, ()> for UntranslatableInLintDiagnostic { diag.note("untranslatable diagnostic"); //~^ ERROR diagnostics should be created using translatable messages } + + fn span(&self) -> Option { + None + } } pub struct TranslatableInLintDiagnostic; @@ -93,6 +97,10 @@ impl<'a> LintDiagnostic<'a, ()> for TranslatableInLintDiagnostic { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { diag.note(crate::fluent_generated::no_crate_note); } + + fn span(&self) -> Option { + None + } } pub fn make_diagnostics<'a>(dcx: DiagCtxtHandle<'a>) { diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index 36dd3cf4be798..625e1973bcd6a 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -23,7 +23,7 @@ LL | diag.note("untranslatable diagnostic"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:99:21 + --> $DIR/diagnostics.rs:107:21 | LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); | ^^^^^^^^^^ @@ -35,37 +35,37 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:102:21 + --> $DIR/diagnostics.rs:110:21 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:102:32 + --> $DIR/diagnostics.rs:110:32 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:120:7 + --> $DIR/diagnostics.rs:128:7 | LL | f("untranslatable diagnostic", crate::fluent_generated::no_crate_example); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:122:50 + --> $DIR/diagnostics.rs:130:50 | LL | f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:124:7 + --> $DIR/diagnostics.rs:132:7 | LL | f("untranslatable diagnostic", "untranslatable diagnostic"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:124:36 + --> $DIR/diagnostics.rs:132:36 | LL | f("untranslatable diagnostic", "untranslatable diagnostic"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 1577b68e748f5..8d672150dfcd0 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -561,7 +561,6 @@ struct LintsGood {} #[diag(no_crate_example)] struct PrimarySpanOnLint { #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute span: Span, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index ff7af38851489..c5228f54ce6e4 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -322,22 +322,14 @@ error: only `no_span` is a valid nested attribute LL | #[label(no_crate_label, foo("..."))] | ^^^ -error: `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:563:5 - | -LL | #[primary_span] - | ^ - | - = help: the `primary_span` field attribute is not valid for lint diagnostics - error: `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:583:1 + --> $DIR/diagnostic-derive.rs:582:1 | LL | #[error(no_crate_example, code = E0123)] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:583:1 + --> $DIR/diagnostic-derive.rs:582:1 | LL | #[error(no_crate_example, code = E0123)] | ^ @@ -345,13 +337,13 @@ LL | #[error(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:590:1 + --> $DIR/diagnostic-derive.rs:589:1 | LL | #[warn_(no_crate_example, code = E0123)] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:590:1 + --> $DIR/diagnostic-derive.rs:589:1 | LL | #[warn_(no_crate_example, code = E0123)] | ^ @@ -359,13 +351,13 @@ LL | #[warn_(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:597:1 + --> $DIR/diagnostic-derive.rs:596:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:597:1 + --> $DIR/diagnostic-derive.rs:596:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ @@ -373,13 +365,13 @@ LL | #[lint(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:604:1 + --> $DIR/diagnostic-derive.rs:603:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:604:1 + --> $DIR/diagnostic-derive.rs:603:1 | LL | #[lint(no_crate_example, code = E0123)] | ^ @@ -387,19 +379,19 @@ LL | #[lint(no_crate_example, code = E0123)] = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:613:53 + --> $DIR/diagnostic-derive.rs:612:53 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:613:39 + --> $DIR/diagnostic-derive.rs:612:39 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:622:24 + --> $DIR/diagnostic-derive.rs:621:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -407,7 +399,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:630:17 + --> $DIR/diagnostic-derive.rs:629:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -415,13 +407,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:637:5 + --> $DIR/diagnostic-derive.rs:636:5 | LL | #[suggestion(no_crate_suggestion)] | ^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:644:1 + --> $DIR/diagnostic-derive.rs:643:1 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -429,7 +421,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:647:1 + --> $DIR/diagnostic-derive.rs:646:1 | LL | #[multipart_suggestion()] | ^ @@ -437,7 +429,7 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:651:5 + --> $DIR/diagnostic-derive.rs:650:5 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^ @@ -445,7 +437,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:659:1 + --> $DIR/diagnostic-derive.rs:658:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] | ^ @@ -453,7 +445,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:668:1 + --> $DIR/diagnostic-derive.rs:667:1 | LL | #[label] | ^ @@ -461,61 +453,61 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:702:5 + --> $DIR/diagnostic-derive.rs:701:5 | LL | #[subdiagnostic(bad)] | ^ error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:710:5 + --> $DIR/diagnostic-derive.rs:709:5 | LL | #[subdiagnostic = "bad"] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:718:5 + --> $DIR/diagnostic-derive.rs:717:5 | LL | #[subdiagnostic(bad, bad)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:726:5 + --> $DIR/diagnostic-derive.rs:725:5 | LL | #[subdiagnostic("bad")] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:734:5 + --> $DIR/diagnostic-derive.rs:733:5 | LL | #[subdiagnostic(eager)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:742:5 + --> $DIR/diagnostic-derive.rs:741:5 | LL | #[subdiagnostic(eager)] | ^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:763:5 + --> $DIR/diagnostic-derive.rs:762:5 | LL | #[subdiagnostic(eager)] | ^ error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:794:23 + --> $DIR/diagnostic-derive.rs:793:23 | LL | #[suggestion(code())] | ^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:802:23 + --> $DIR/diagnostic-derive.rs:801:23 | LL | #[suggestion(code(foo))] | ^^^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:826:5 + --> $DIR/diagnostic-derive.rs:825:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^ @@ -531,13 +523,13 @@ LL | #[diag = "E0123"] | ^ you might be missing crate `core` error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:802:23 + --> $DIR/diagnostic-derive.rs:801:23 | LL | #[suggestion(code(foo))] | ^^^ you might be missing crate `core` error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:811:25 + --> $DIR/diagnostic-derive.rs:810:25 | LL | #[suggestion(code = 3)] | ^ you might be missing crate `core` @@ -555,43 +547,43 @@ LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:583:3 + --> $DIR/diagnostic-derive.rs:582:3 | LL | #[error(no_crate_example, code = E0123)] | ^^^^^ error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:590:3 + --> $DIR/diagnostic-derive.rs:589:3 | LL | #[warn_(no_crate_example, code = E0123)] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:597:3 + --> $DIR/diagnostic-derive.rs:596:3 | LL | #[lint(no_crate_example, code = E0123)] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:604:3 + --> $DIR/diagnostic-derive.rs:603:3 | LL | #[lint(no_crate_example, code = E0123)] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:644:3 + --> $DIR/diagnostic-derive.rs:643:3 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:647:3 + --> $DIR/diagnostic-derive.rs:646:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:651:7 + --> $DIR/diagnostic-derive.rs:650:7 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ @@ -603,7 +595,7 @@ LL | #[diag(nonsense, code = E0123)] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:808:10 + --> $DIR/diagnostic-derive.rs:807:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -624,7 +616,7 @@ note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 85 previous errors +error: aborting due to 84 previous errors Some errors have detailed explanations: E0277, E0425, E0433. For more information about an error, try `rustc --explain E0277`. From 775527e808e915d4f6d8adfd6365becd7e656302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 17 May 2024 12:46:15 +0200 Subject: [PATCH 4/4] Derive both Diagnostic and LintDiagnostic on some tys --- .../src/coherence/orphan.rs | 4 +-- compiler/rustc_hir_analysis/src/errors.rs | 31 ++----------------- compiler/rustc_hir_typeck/src/errors.rs | 13 +------- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 5 ++- compiler/rustc_passes/src/errors.rs | 9 +----- tests/ui/self/self-ctor-nongeneric.stderr | 5 +-- 7 files changed, 12 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 18f60d80b35ff..50e2b7927c221 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -497,10 +497,10 @@ fn lint_uncovered_ty_params<'tcx>( Some(local_type) => tcx.emit_node_lint( UNCOVERED_PARAM_IN_PROJECTION, hir_id, - errors::TyParamFirstLocalLint { span, note: (), param: name, local_type }, + errors::TyParamFirstLocal { span, note: (), param: name, local_type }, ), None => { - tcx.emit_node_lint(UNCOVERED_PARAM_IN_PROJECTION, hir_id, errors::TyParamSomeLint { + tcx.emit_node_lint(UNCOVERED_PARAM_IN_PROJECTION, hir_id, errors::TyParamSome { span, note: (), param: name, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 25362203cb25b..71b357a276346 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1382,9 +1382,7 @@ pub(crate) struct CrossCrateTraitsDefined { pub traits: String, } -// FIXME(fmease): Deduplicate: - -#[derive(Diagnostic)] +#[derive(Diagnostic, LintDiagnostic)] #[diag(hir_analysis_ty_param_first_local, code = E0210)] #[note] pub(crate) struct TyParamFirstLocal<'tcx> { @@ -1397,20 +1395,7 @@ pub(crate) struct TyParamFirstLocal<'tcx> { pub local_type: Ty<'tcx>, } -#[derive(LintDiagnostic)] -#[diag(hir_analysis_ty_param_first_local, code = E0210)] -#[note] -pub(crate) struct TyParamFirstLocalLint<'tcx> { - #[primary_span] - #[label] - pub span: Span, - #[note(hir_analysis_case_note)] - pub note: (), - pub param: Symbol, - pub local_type: Ty<'tcx>, -} - -#[derive(Diagnostic)] +#[derive(Diagnostic, LintDiagnostic)] #[diag(hir_analysis_ty_param_some, code = E0210)] #[note] pub(crate) struct TyParamSome { @@ -1422,18 +1407,6 @@ pub(crate) struct TyParamSome { pub param: Symbol, } -#[derive(LintDiagnostic)] -#[diag(hir_analysis_ty_param_some, code = E0210)] -#[note] -pub(crate) struct TyParamSomeLint { - #[primary_span] - #[label] - pub span: Span, - #[note(hir_analysis_only_note)] - pub note: (), - pub param: Symbol, -} - #[derive(Diagnostic)] pub(crate) enum OnlyCurrentTraits { #[diag(hir_analysis_only_current_traits_outside, code = E0117)] diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 94a1c5f100952..c5940a9f77dc4 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -697,7 +697,7 @@ pub(crate) enum SuggestBoxingForReturnImplTrait { }, } -#[derive(Diagnostic)] +#[derive(Diagnostic, LintDiagnostic)] #[diag(hir_typeck_self_ctor_from_outer_item, code = E0401)] pub(crate) struct SelfCtorFromOuterItem { #[primary_span] @@ -708,17 +708,6 @@ pub(crate) struct SelfCtorFromOuterItem { pub sugg: Option, } -#[derive(LintDiagnostic)] -#[diag(hir_typeck_self_ctor_from_outer_item)] -pub(crate) struct SelfCtorFromOuterItemLint { - #[primary_span] - pub span: Span, - #[label] - pub impl_span: Span, - #[subdiagnostic] - pub sugg: Option, -} - #[derive(Subdiagnostic)] #[suggestion(hir_typeck_suggestion, code = "{name}", applicability = "machine-applicable")] pub(crate) struct ReplaceWithName { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ef9af9347f71b..426a91ea6a07c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1151,7 +1151,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.emit_node_lint( SELF_CONSTRUCTOR_FROM_OUTER_ITEM, hir_id, - errors::SelfCtorFromOuterItemLint { + errors::SelfCtorFromOuterItem { span: path_span, impl_span: tcx.def_span(impl_def_id), sugg, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d5816db05fdb4..b1a7ad4df9cf9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1838,8 +1838,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }); } if is_explicit_rust && (int_reprs > 0 || is_c || is_simd) { - let hint_spans = hint_spans.clone().collect(); - self.dcx().emit_err(errors::ReprConflicting { hint_spans }); + self.dcx().emit_err(errors::ReprConflicting { spans: hint_spans.clone().collect() }); } // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) if (int_reprs > 1) @@ -1850,7 +1849,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let ItemLike::Item(item) = item { is_c_like_enum(item) } else { false } })) { - self.tcx.emit_node_lint(CONFLICTING_REPR_HINTS, hir_id, errors::ReprConflictingLint { + self.tcx.emit_node_lint(CONFLICTING_REPR_HINTS, hir_id, errors::ReprConflicting { spans: hint_spans.collect(), }); } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 2734af4672d53..0555cf7fa4032 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -621,16 +621,9 @@ pub(crate) struct ReprIdent { pub span: Span, } -#[derive(Diagnostic)] +#[derive(Diagnostic, LintDiagnostic)] #[diag(passes_repr_conflicting, code = E0566)] pub(crate) struct ReprConflicting { - #[primary_span] - pub hint_spans: Vec, -} - -#[derive(LintDiagnostic)] -#[diag(passes_repr_conflicting, code = E0566)] -pub(crate) struct ReprConflictingLint { #[primary_span] pub spans: Vec, } diff --git a/tests/ui/self/self-ctor-nongeneric.stderr b/tests/ui/self/self-ctor-nongeneric.stderr index 6c03c6f3e38a4..308cf6bad8d72 100644 --- a/tests/ui/self/self-ctor-nongeneric.stderr +++ b/tests/ui/self/self-ctor-nongeneric.stderr @@ -1,4 +1,4 @@ -warning: can't reference `Self` constructor from outer item +warning[E0401]: can't reference `Self` constructor from outer item --> $DIR/self-ctor-nongeneric.rs:8:23 | LL | impl S0 { @@ -11,7 +11,7 @@ LL | const C: S0 = Self(0); = note: for more information, see issue #124186 = note: `#[warn(self_constructor_from_outer_item)]` on by default -warning: can't reference `Self` constructor from outer item +warning[E0401]: can't reference `Self` constructor from outer item --> $DIR/self-ctor-nongeneric.rs:12:13 | LL | impl S0 { @@ -25,3 +25,4 @@ LL | Self(0) warning: 2 warnings emitted +For more information about this error, try `rustc --explain E0401`.