diff options
| author | Michael Goulet <michael@errs.io> | 2025-01-25 17:14:33 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-02-13 05:45:53 +0000 |
| commit | 72b4df3772a6c2cae8d9cf7ae618c010c10131b2 (patch) | |
| tree | 7c2d611b8fce4d6776b7579df0a65d8078399290 /compiler/rustc_hir_analysis/src | |
| parent | 2189908170f86809b7de5275dcde0cf828c16b37 (diff) | |
| download | rust-72b4df3772a6c2cae8d9cf7ae618c010c10131b2.tar.gz rust-72b4df3772a6c2cae8d9cf7ae618c010c10131b2.zip | |
Implement lint for definition site item shadowing too
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/wfcheck.rs | 45 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 28 |
2 files changed, 72 insertions, 1 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1689437ffb0..4218f4ef0c1 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -12,6 +12,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{AmbigArg, ItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; +use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; use rustc_macros::LintDiagnostic; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::query::Providers; @@ -388,7 +389,12 @@ fn check_trait_item<'tcx>( hir::TraitItemKind::Type(_bounds, Some(ty)) => (None, ty.span), _ => (None, trait_item.span), }; + check_dyn_incompatible_self_trait_by_name(tcx, trait_item); + + // Check that an item definition in a subtrait is shadowing a supertrait item. + lint_item_shadowing_supertrait_item(tcx, def_id); + let mut res = check_associated_item(tcx, def_id, span, method_sig); if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) { @@ -898,6 +904,45 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI } } +fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_id: LocalDefId) { + let item_name = tcx.item_name(trait_item_def_id.to_def_id()); + let trait_def_id = tcx.local_parent(trait_item_def_id); + + let shadowed: Vec<_> = traits::supertrait_def_ids(tcx, trait_def_id.to_def_id()) + .skip(1) + .flat_map(|supertrait_def_id| { + tcx.associated_items(supertrait_def_id).filter_by_name_unhygienic(item_name) + }) + .collect(); + if !shadowed.is_empty() { + let shadowee = if let [shadowed] = shadowed[..] { + errors::SupertraitItemShadowee::Labeled { + span: tcx.def_span(shadowed.def_id), + supertrait: tcx.item_name(shadowed.trait_container(tcx).unwrap()), + } + } else { + let (traits, spans): (Vec<_>, Vec<_>) = shadowed + .iter() + .map(|item| { + (tcx.item_name(item.trait_container(tcx).unwrap()), tcx.def_span(item.def_id)) + }) + .unzip(); + errors::SupertraitItemShadowee::Several { traits: traits.into(), spans: spans.into() } + }; + + tcx.emit_node_span_lint( + SUPERTRAIT_ITEM_SHADOWING_DEFINITION, + tcx.local_def_id_to_hir_id(trait_item_def_id), + tcx.def_span(trait_item_def_id), + errors::SupertraitItemShadowing { + item: item_name, + subtrait: tcx.item_name(trait_def_id.to_def_id()), + shadowee, + }, + ); + } +} + fn check_impl_item<'tcx>( tcx: TyCtxt<'tcx>, impl_item: &'tcx hir::ImplItem<'tcx>, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1574506de60..14ea10461cb 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -3,7 +3,8 @@ use rustc_abi::ExternAbi; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, + Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, + MultiSpan, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; @@ -1733,3 +1734,28 @@ pub(crate) struct RegisterTypeUnstable<'a> { pub span: Span, pub ty: Ty<'a>, } + +#[derive(LintDiagnostic)] +#[diag(hir_analysis_supertrait_item_shadowing)] +pub(crate) struct SupertraitItemShadowing { + pub item: Symbol, + pub subtrait: Symbol, + #[subdiagnostic] + pub shadowee: SupertraitItemShadowee, +} + +#[derive(Subdiagnostic)] +pub(crate) enum SupertraitItemShadowee { + #[note(hir_analysis_supertrait_item_shadowee)] + Labeled { + #[primary_span] + span: Span, + supertrait: Symbol, + }, + #[note(hir_analysis_supertrait_item_multiple_shadowee)] + Several { + #[primary_span] + spans: MultiSpan, + traits: DiagSymbolList, + }, +} |
