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