Skip to content

Commit 85e3a2e

Browse files
committed
Add const-anon suggestion for non local impl
1 parent a8ae117 commit 85e3a2e

File tree

4 files changed

+26
-2
lines changed

4 files changed

+26
-2
lines changed

compiler/rustc_lint/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, they should be av
421421
}
422422
.non_local = an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
423423
.exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module and anon-const at the same nesting as the trait or type
424+
.const_anon = use a const-anon item to suppress this lint
424425
425426
lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, they should be avoided as they go against expectation
426427
.help =

compiler/rustc_lint/src/lints.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,13 @@ pub enum NonLocalDefinitionsDiag {
13011301
#[note(lint_non_local)]
13021302
#[note(lint_exception)]
13031303
#[note(lint_non_local_definitions_deprecation)]
1304-
Impl { depth: u32, body_kind_descr: &'static str, body_name: String },
1304+
Impl {
1305+
depth: u32,
1306+
body_kind_descr: &'static str,
1307+
body_name: String,
1308+
#[suggestion(lint_const_anon, code = "_", applicability = "machine-applicable")]
1309+
const_anon: Option<Span>,
1310+
},
13051311
#[diag(lint_non_local_definitions_macro_rules)]
13061312
#[help]
13071313
#[note(lint_non_local)]

compiler/rustc_lint/src/non_local_def.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_hir::{def::DefKind, Body, Item, ItemKind, Path, QPath, TyKind};
1+
use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
22
use rustc_span::{def_id::DefId, sym, symbol::kw, MacroKind};
33

44
use smallvec::{smallvec, SmallVec};
@@ -140,6 +140,19 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
140140
// If none of them have a local parent (LOGICAL NOR) this means that
141141
// this impl definition is a non-local definition and so we lint on it.
142142
if !(self_ty_has_local_parent || of_trait_has_local_parent) {
143+
let const_anon = if self.body_depth == 1
144+
&& parent_def_kind == DefKind::Const
145+
&& parent_opt_item_name != Some(kw::Underscore)
146+
&& let Some(parent) = parent.as_local()
147+
&& let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
148+
&& let ItemKind::Const(ty, _, _) = item.kind
149+
&& let TyKind::Tup(&[]) = ty.kind
150+
{
151+
Some(item.ident.span)
152+
} else {
153+
None
154+
};
155+
143156
cx.emit_span_lint(
144157
NON_LOCAL_DEFINITIONS,
145158
item.span,
@@ -149,6 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
149162
body_name: parent_opt_item_name
150163
.map(|s| s.to_ident_string())
151164
.unwrap_or_else(|| "<unnameable>".to_string()),
165+
const_anon,
152166
},
153167
)
154168
}

tests/ui/lint/non_local_definitions.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
warning: non-local `impl` definition, they should be avoided as they go against expectation
22
--> $DIR/non_local_definitions.rs:32:5
33
|
4+
LL | const Z: () = {
5+
| - help: use a const-anon item to suppress this lint: `_`
6+
...
47
LL | impl Uto for &Test {}
58
| ^^^^^^^^^^^^^^^^^^^^^
69
|

0 commit comments

Comments
 (0)