|
1 | 1 | use rustc_errors::MultiSpan; |
2 | | -use rustc_hir::def::DefKind; |
| 2 | +use rustc_hir::def::{DefKind, Res}; |
3 | 3 | use rustc_hir::intravisit::{self, Visitor}; |
4 | | -use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, QPath, TyKind}; |
| 4 | +use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind}; |
5 | 5 | use rustc_middle::ty::TyCtxt; |
6 | 6 | use rustc_session::{declare_lint, impl_lint_pass}; |
7 | 7 | use rustc_span::def_id::{DefId, LOCAL_CRATE}; |
8 | 8 | use rustc_span::symbol::kw; |
9 | | -use rustc_span::{sym, ExpnKind, MacroKind, Span, Symbol}; |
| 9 | +use rustc_span::{sym, ExpnKind, MacroKind, Span}; |
10 | 10 |
|
11 | 11 | use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag}; |
12 | 12 | use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext}; |
@@ -142,6 +142,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { |
142 | 142 | collector.visit_trait_ref(of_trait); |
143 | 143 | } |
144 | 144 |
|
| 145 | + // 1.5. Remove any path that doesn't resolve to a `DefId` or if it resolve to a |
| 146 | + // type-param (e.g. `T`). |
| 147 | + collector.paths.retain( |
| 148 | + |p| matches!(p.res, Res::Def(def_kind, _) if def_kind != DefKind::TyParam), |
| 149 | + ); |
| 150 | + |
145 | 151 | // 2. We check if any of path reference a "local" parent and if that the case |
146 | 152 | // we bail out as asked by T-lang, even though this isn't correct from a |
147 | 153 | // type-system point of view, as inference exists and could still leak the impl. |
@@ -174,23 +180,16 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { |
174 | 180 | let impl_span = item.span.shrink_to_lo().to(impl_.self_ty.span); |
175 | 181 | let mut ms = MultiSpan::from_span(impl_span); |
176 | 182 |
|
177 | | - let (self_ty_span, self_ty_str) = |
178 | | - self_ty_kind_for_diagnostic(&impl_.self_ty, cx.tcx); |
179 | | - |
180 | | - ms.push_span_label( |
181 | | - self_ty_span, |
182 | | - fluent::lint_non_local_definitions_self_ty_not_local, |
183 | | - ); |
184 | | - |
185 | | - let of_trait_str = if let Some(of_trait) = &impl_.of_trait { |
| 183 | + for path in &collector.paths { |
| 184 | + // FIXME: While a translatable diagnostic message can have an argument |
| 185 | + // we (currently) have no way to set different args per diag msg with |
| 186 | + // `MultiSpan::push_span_label`. |
| 187 | + #[allow(rustc::untranslatable_diagnostic)] |
186 | 188 | ms.push_span_label( |
187 | | - path_span_without_args(&of_trait.path), |
188 | | - fluent::lint_non_local_definitions_of_trait_not_local, |
| 189 | + path_span_without_args(path), |
| 190 | + format!("`{}` is not local", path_name_to_string(path)), |
189 | 191 | ); |
190 | | - Some(path_name_to_string(&of_trait.path)) |
191 | | - } else { |
192 | | - None |
193 | | - }; |
| 192 | + } |
194 | 193 |
|
195 | 194 | let doctest = is_at_toplevel_doctest(); |
196 | 195 |
|
@@ -219,8 +218,6 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { |
219 | 218 | .unwrap_or_else(|| "<unnameable>".to_string()), |
220 | 219 | cargo_update: cargo_update(), |
221 | 220 | const_anon, |
222 | | - self_ty_str, |
223 | | - of_trait_str, |
224 | 221 | doctest, |
225 | 222 | has_trait: impl_.of_trait.is_some(), |
226 | 223 | macro_to_change, |
@@ -316,38 +313,3 @@ fn path_span_without_args(path: &Path<'_>) -> Span { |
316 | 313 | fn path_name_to_string(path: &Path<'_>) -> String { |
317 | 314 | path.segments.last().unwrap().ident.name.to_ident_string() |
318 | 315 | } |
319 | | - |
320 | | -/// Compute the `Span` and visual representation for the `Self` we want to point at; |
321 | | -/// It follows part of the actual logic of non-local, and if possible return the least |
322 | | -/// amount possible for the span and representation. |
323 | | -fn self_ty_kind_for_diagnostic(ty: &rustc_hir::Ty<'_>, tcx: TyCtxt<'_>) -> (Span, String) { |
324 | | - match ty.kind { |
325 | | - TyKind::Path(QPath::Resolved(_, ty_path)) => ( |
326 | | - path_span_without_args(ty_path), |
327 | | - ty_path |
328 | | - .res |
329 | | - .opt_def_id() |
330 | | - .map(|did| tcx.opt_item_name(did)) |
331 | | - .flatten() |
332 | | - .as_ref() |
333 | | - .map(|s| Symbol::as_str(s)) |
334 | | - .unwrap_or("<unnameable>") |
335 | | - .to_string(), |
336 | | - ), |
337 | | - TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => { |
338 | | - let path = &principle_poly_trait_ref.0.trait_ref.path; |
339 | | - ( |
340 | | - path_span_without_args(path), |
341 | | - path.res |
342 | | - .opt_def_id() |
343 | | - .map(|did| tcx.opt_item_name(did)) |
344 | | - .flatten() |
345 | | - .as_ref() |
346 | | - .map(|s| Symbol::as_str(s)) |
347 | | - .unwrap_or("<unnameable>") |
348 | | - .to_string(), |
349 | | - ) |
350 | | - } |
351 | | - _ => (ty.span, rustc_hir_pretty::ty_to_string(&tcx, ty)), |
352 | | - } |
353 | | -} |
0 commit comments