diff options
| author | Urgau <urgau@numericable.fr> | 2024-05-15 14:08:28 +0200 |
|---|---|---|
| committer | Urgau <urgau@numericable.fr> | 2024-05-27 23:59:18 +0200 |
| commit | d3dfe14b53e2211138e3a4eae5915351ff62f5bc (patch) | |
| tree | d752a9c0edf2426125a44e543c3df50ca07bc8a1 /compiler | |
| parent | 402580bcd5ade168a3a7edd0713821fa7d06dc2c (diff) | |
| download | rust-d3dfe14b53e2211138e3a4eae5915351ff62f5bc.tar.gz rust-d3dfe14b53e2211138e3a4eae5915351ff62f5bc.zip | |
non_local_defs: be more precise about what needs to be moved
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_lint/src/lints.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/non_local_def.rs | 40 |
2 files changed, 43 insertions, 9 deletions
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 800cd398adb..ad6e7b958c7 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1337,8 +1337,7 @@ pub enum NonLocalDefinitionsDiag { cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>, const_anon: Option<Option<Span>>, move_help: Span, - self_ty: Span, - of_trait: Option<Span>, + may_move: Vec<Span>, has_trait: bool, }, MacroRules { @@ -1361,8 +1360,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { cargo_update, const_anon, move_help, - self_ty, - of_trait, + may_move, has_trait, } => { diag.primary_message(fluent::lint_non_local_definitions_impl); @@ -1376,10 +1374,10 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { } else { diag.note(fluent::lint_without_trait); } + let mut ms = MultiSpan::from_span(move_help); - ms.push_span_label(self_ty, fluent::lint_non_local_definitions_may_move); - if let Some(of_trait) = of_trait { - ms.push_span_label(of_trait, fluent::lint_non_local_definitions_may_move); + for sp in may_move { + ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move); } diag.span_help(ms, fluent::lint_help); diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 6b75e546a66..0805c2e2766 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -1,3 +1,5 @@ +use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, TyKind}; use rustc_hir::{Path, QPath}; use rustc_infer::infer::InferCtxt; @@ -214,6 +216,29 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { None }; + let mut collector = PathCollector { paths: Vec::new() }; + collector.visit_ty(&impl_.self_ty); + if let Some(of_trait) = &impl_.of_trait { + collector.visit_trait_ref(of_trait); + } + collector.visit_generics(&impl_.generics); + + let may_move: Vec<Span> = collector + .paths + .into_iter() + .filter_map(|path| { + if path_has_local_parent(&path, cx, parent, parent_parent) { + if let Some(args) = &path.segments.last().unwrap().args { + Some(path.span.until(args.span_ext)) + } else { + Some(path.span) + } + } else { + None + } + }) + .collect(); + let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. }) .then_some(span_for_const_anon_suggestion); @@ -223,14 +248,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { NonLocalDefinitionsDiag::Impl { depth: self.body_depth, move_help: item.span, - self_ty: impl_.self_ty.span, - of_trait: impl_.of_trait.map(|t| t.path.span), body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent), body_name: parent_opt_item_name .map(|s| s.to_ident_string()) .unwrap_or_else(|| "<unnameable>".to_string()), cargo_update: cargo_update(), const_anon, + may_move, has_trait: impl_.of_trait.is_some(), }, ) @@ -348,6 +372,18 @@ impl<'a, 'tcx, F: FnMut(DefId) -> bool> TypeFolder<TyCtxt<'tcx>> } } +/// Simple hir::Path collector +struct PathCollector<'tcx> { + paths: Vec<Path<'tcx>>, +} + +impl<'tcx> Visitor<'tcx> for PathCollector<'tcx> { + fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) { + self.paths.push(path.clone()); // need to clone, bc of the restricted lifetime + intravisit::walk_path(self, path) + } +} + /// Given a path and a parent impl def id, this checks if the if parent resolution /// def id correspond to the def id of the parent impl definition. /// |
