non_local_defs: point the parent item when appropriate
This commit is contained in:
parent
98273ec612
commit
c7d300442f
13 changed files with 330 additions and 481 deletions
|
@ -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 ->
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue