1
Fork 0

Point to every relevant types in the main diag

This commit is contained in:
Urgau 2024-06-28 14:00:14 +02:00
parent 00a6ebfbf5
commit 0f665e2bf3
9 changed files with 76 additions and 124 deletions

View file

@ -1377,8 +1377,6 @@ pub(crate) enum NonLocalDefinitionsDiag {
const_anon: Option<Option<Span>>,
doctest: bool,
has_trait: bool,
self_ty_str: String,
of_trait_str: Option<String>,
macro_to_change: Option<(String, &'static str)>,
},
MacroRules {
@ -1401,18 +1399,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
const_anon,
doctest,
has_trait,
self_ty_str,
of_trait_str,
macro_to_change,
} => {
diag.primary_message(fluent::lint_non_local_definitions_impl);
diag.arg("depth", depth);
diag.arg("body_kind_descr", body_kind_descr);
diag.arg("body_name", body_name);
diag.arg("self_ty_str", self_ty_str);
if let Some(of_trait_str) = of_trait_str {
diag.arg("of_trait_str", of_trait_str);
}
if let Some((macro_to_change, macro_kind)) = macro_to_change {
diag.arg("macro_to_change", macro_to_change);

View file

@ -1,12 +1,12 @@
use rustc_errors::MultiSpan;
use rustc_hir::def::DefKind;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, QPath, TyKind};
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind};
use rustc_middle::ty::TyCtxt;
use rustc_session::{declare_lint, impl_lint_pass};
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::kw;
use rustc_span::{ExpnKind, MacroKind, Span, Symbol, sym, sym};
use rustc_span::{ExpnKind, MacroKind, Span, sym};
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
@ -142,6 +142,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
collector.visit_trait_ref(of_trait);
}
// 1.5. Remove any path that doesn't resolve to a `DefId` or if it resolve to a
// type-param (e.g. `T`).
collector.paths.retain(
|p| matches!(p.res, Res::Def(def_kind, _) if def_kind != DefKind::TyParam),
);
// 2. We check if any of path reference a "local" parent and if that the case
// we bail out as asked by T-lang, even though this isn't correct from a
// type-system point of view, as inference exists and could still leak the impl.
@ -174,23 +180,16 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
let impl_span = item.span.shrink_to_lo().to(impl_.self_ty.span);
let mut ms = MultiSpan::from_span(impl_span);
let (self_ty_span, self_ty_str) =
self_ty_kind_for_diagnostic(&impl_.self_ty, cx.tcx);
ms.push_span_label(
self_ty_span,
fluent::lint_non_local_definitions_self_ty_not_local,
);
let of_trait_str = if let Some(of_trait) = &impl_.of_trait {
for path in &collector.paths {
// FIXME: While a translatable diagnostic message can have an argument
// we (currently) have no way to set different args per diag msg with
// `MultiSpan::push_span_label`.
#[allow(rustc::untranslatable_diagnostic)]
ms.push_span_label(
path_span_without_args(&of_trait.path),
fluent::lint_non_local_definitions_of_trait_not_local,
path_span_without_args(path),
format!("`{}` is not local", path_name_to_string(path)),
);
Some(path_name_to_string(&of_trait.path))
} else {
None
};
}
let doctest = is_at_toplevel_doctest();
@ -216,8 +215,6 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
.unwrap_or_else(|| "<unnameable>".to_string()),
cargo_update: cargo_update(),
const_anon,
self_ty_str,
of_trait_str,
doctest,
has_trait: impl_.of_trait.is_some(),
macro_to_change,
@ -312,38 +309,3 @@ fn path_span_without_args(path: &Path<'_>) -> Span {
fn path_name_to_string(path: &Path<'_>) -> String {
path.segments.last().unwrap().ident.name.to_ident_string()
}
/// Compute the `Span` and visual representation for the `Self` we want to point at;
/// It follows part of the actual logic of non-local, and if possible return the least
/// amount possible for the span and representation.
fn self_ty_kind_for_diagnostic(ty: &rustc_hir::Ty<'_>, tcx: TyCtxt<'_>) -> (Span, String) {
match ty.kind {
TyKind::Path(QPath::Resolved(_, ty_path)) => (
path_span_without_args(ty_path),
ty_path
.res
.opt_def_id()
.map(|did| tcx.opt_item_name(did))
.flatten()
.as_ref()
.map(|s| Symbol::as_str(s))
.unwrap_or("<unnameable>")
.to_string(),
),
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
let path = &principle_poly_trait_ref.0.trait_ref.path;
(
path_span_without_args(path),
path.res
.opt_def_id()
.map(|did| tcx.opt_item_name(did))
.flatten()
.as_ref()
.map(|s| Symbol::as_str(s))
.unwrap_or("<unnameable>")
.to_string(),
)
}
_ => (ty.span, rustc_hir_pretty::ty_to_string(&tcx, ty)),
}
}