|
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