1
Fork 0

non_local_defs: point the parent item when appropriate

This commit is contained in:
Urgau 2024-05-18 15:07:28 +02:00
parent 98273ec612
commit c7d300442f
13 changed files with 330 additions and 481 deletions

View file

@ -543,11 +543,6 @@ lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may
lint_non_local_definitions_deprecation = this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
.move_help =
move this `impl` block outside of the current {$body_kind_descr} {$depth ->
[one] `{$body_name}`
*[other] `{$body_name}` and up {$depth} bodies
}
.remove_help = remove `{$may_remove_part}` to make the `impl` local
.without_trait = methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
.with_trait = an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
@ -555,6 +550,12 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
.const_anon = use a const-anon item to suppress this lint
lint_non_local_definitions_impl_move_help =
move the `impl` block outside of this {$body_kind_descr} {$depth ->
[one] `{$body_name}`
*[other] `{$body_name}` and up {$depth} bodies
}
lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
.help =
remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->

View file

@ -1336,8 +1336,7 @@ pub enum NonLocalDefinitionsDiag {
body_name: String,
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
const_anon: Option<Option<Span>>,
move_help: Span,
may_move: Vec<Span>,
move_to: Option<(Span, Vec<Span>)>,
may_remove: Option<(Span, String)>,
has_trait: bool,
self_ty_str: String,
@ -1362,8 +1361,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
body_name,
cargo_update,
const_anon,
move_help,
may_move,
move_to,
may_remove,
has_trait,
self_ty_str,
@ -1385,11 +1383,13 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
diag.note(fluent::lint_without_trait);
}
let mut ms = MultiSpan::from_span(move_help);
for sp in may_move {
ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
if let Some((move_help, may_move)) = move_to {
let mut ms = MultiSpan::from_span(move_help);
for sp in may_move {
ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
}
diag.span_help(ms, fluent::lint_non_local_definitions_impl_move_help);
}
diag.span_help(ms, fluent::lint_move_help);
if let Some((span, part)) = may_remove {
diag.arg("may_remove_part", part);

View file

@ -198,17 +198,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
}
collector.visit_generics(&impl_.generics);
let may_move: Vec<Span> = collector
let mut may_move: Vec<Span> = collector
.paths
.into_iter()
.filter_map(|path| {
if path_has_local_parent(&path, cx, parent, parent_parent) {
Some(path_span_without_args(&path))
if let Some(did) = path.res.opt_def_id()
&& did_has_local_parent(did, cx.tcx, parent, parent_parent)
{
Some(cx.tcx.def_span(did))
} else {
None
}
})
.collect();
may_move.sort();
may_move.dedup();
let const_anon = matches!(parent_def_kind, DefKind::Const | DefKind::Static { .. })
.then_some(span_for_const_anon_suggestion);
@ -244,13 +248,21 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
} else {
None
};
let move_to = if may_move.is_empty() {
ms.push_span_label(
cx.tcx.def_span(parent),
fluent::lint_non_local_definitions_impl_move_help,
);
None
} else {
Some((cx.tcx.def_span(parent), may_move))
};
cx.emit_span_lint(
NON_LOCAL_DEFINITIONS,
ms,
NonLocalDefinitionsDiag::Impl {
depth: self.body_depth,
move_help: item.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())
@ -259,7 +271,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
const_anon,
self_ty_str,
of_trait_str,
may_move,
move_to,
may_remove,
has_trait: impl_.of_trait.is_some(),
},