|
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