Skip to content

Commit 0a338d1

Browse files
committed
Auto merge of rust-lang#125644 - workingjubilee:rollup-9inx7i9, r=workingjubilee
Rollup of 4 pull requests Successful merges: - rust-lang#125089 (Improve diagnostic output the `non_local_definitions` lint) - rust-lang#125343 (`-Znext-solver`: eagerly normalize when adding goals) - rust-lang#125411 (check host's libstdc++ version when using ci llvm) - rust-lang#125551 (Stabilise `IpvNAddr::{BITS, to_bits, from_bits}` (`ip_bits`)) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c0d6003 + 6ba7807 commit 0a338d1

38 files changed

+1423
-581
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4082,6 +4082,7 @@ dependencies = [
40824082
"rustc_feature",
40834083
"rustc_fluent_macro",
40844084
"rustc_hir",
4085+
"rustc_hir_pretty",
40854086
"rustc_index",
40864087
"rustc_infer",
40874088
"rustc_macros",

compiler/rustc_lint/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ rustc_errors = { path = "../rustc_errors" }
1313
rustc_feature = { path = "../rustc_feature" }
1414
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1515
rustc_hir = { path = "../rustc_hir" }
16+
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
1617
rustc_index = { path = "../rustc_index" }
1718
rustc_infer = { path = "../rustc_infer" }
1819
rustc_macros = { path = "../rustc_macros" }

compiler/rustc_lint/messages.ftl

+19-10
Original file line numberDiff line numberDiff line change
@@ -542,17 +542,21 @@ lint_non_local_definitions_cargo_update = the {$macro_kind} `{$macro_name}` may
542542
543543
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>
544544
545-
lint_non_local_definitions_impl = non-local `impl` definition, they should be avoided as they go against expectation
546-
.help =
547-
move this `impl` block outside the of the current {$body_kind_descr} {$depth ->
548-
[one] `{$body_name}`
549-
*[other] `{$body_name}` and up {$depth} bodies
550-
}
551-
.non_local = an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
552-
.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
545+
lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks should be written at the same level as their item
546+
.remove_help = remove `{$may_remove_part}` to make the `impl` local
547+
.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`
548+
.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`
549+
.bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
550+
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
553551
.const_anon = use a const-anon item to suppress this lint
554552
555-
lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, they should be avoided as they go against expectation
553+
lint_non_local_definitions_impl_move_help =
554+
move the `impl` block outside of this {$body_kind_descr} {$depth ->
555+
[one] `{$body_name}`
556+
*[other] `{$body_name}` and up {$depth} bodies
557+
}
558+
559+
lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module
556560
.help =
557561
remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth ->
558562
[one] `{$body_name}`
@@ -561,7 +565,12 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, th
561565
.help_doctest =
562566
remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
563567
.non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
564-
.exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module
568+
569+
lint_non_local_definitions_may_move = may need to be moved as well
570+
571+
lint_non_local_definitions_of_trait_not_local = `{$of_trait_str}` is not local
572+
573+
lint_non_local_definitions_self_ty_not_local = `{$self_ty_str}` is not local
565574
566575
lint_non_snake_case = {$sort} `{$name}` should have a snake case name
567576
.rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier

compiler/rustc_lint/src/lints.rs

+104-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::errors::RequestedLevel;
66
use crate::fluent_generated as fluent;
77
use rustc_errors::{
88
codes::*, Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString,
9-
ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, SubdiagMessageOp,
9+
ElidedLifetimeInPathSubdiag, EmissionGuarantee, LintDiagnostic, MultiSpan, SubdiagMessageOp,
1010
Subdiagnostic, SuggestionStyle,
1111
};
1212
use rustc_hir::{def::Namespace, def_id::DefId};
@@ -1329,40 +1329,126 @@ pub struct SuspiciousDoubleRefCloneDiag<'a> {
13291329
}
13301330

13311331
// non_local_defs.rs
1332-
#[derive(LintDiagnostic)]
13331332
pub enum NonLocalDefinitionsDiag {
1334-
#[diag(lint_non_local_definitions_impl)]
1335-
#[help]
1336-
#[note(lint_non_local)]
1337-
#[note(lint_exception)]
1338-
#[note(lint_non_local_definitions_deprecation)]
13391333
Impl {
13401334
depth: u32,
13411335
body_kind_descr: &'static str,
13421336
body_name: String,
1343-
#[subdiagnostic]
13441337
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
1345-
#[suggestion(lint_const_anon, code = "_", applicability = "machine-applicable")]
1346-
const_anon: Option<Span>,
1338+
const_anon: Option<Option<Span>>,
1339+
move_to: Option<(Span, Vec<Span>)>,
1340+
may_remove: Option<(Span, String)>,
1341+
has_trait: bool,
1342+
self_ty_str: String,
1343+
of_trait_str: Option<String>,
13471344
},
1348-
#[diag(lint_non_local_definitions_macro_rules)]
13491345
MacroRules {
13501346
depth: u32,
13511347
body_kind_descr: &'static str,
13521348
body_name: String,
1353-
#[help]
13541349
help: Option<()>,
1355-
#[help(lint_help_doctest)]
13561350
doctest_help: Option<()>,
1357-
#[note(lint_non_local)]
1358-
#[note(lint_exception)]
1359-
#[note(lint_non_local_definitions_deprecation)]
1360-
notes: (),
1361-
#[subdiagnostic]
13621351
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
13631352
},
13641353
}
13651354

1355+
impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
1356+
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1357+
match self {
1358+
NonLocalDefinitionsDiag::Impl {
1359+
depth,
1360+
body_kind_descr,
1361+
body_name,
1362+
cargo_update,
1363+
const_anon,
1364+
move_to,
1365+
may_remove,
1366+
has_trait,
1367+
self_ty_str,
1368+
of_trait_str,
1369+
} => {
1370+
diag.primary_message(fluent::lint_non_local_definitions_impl);
1371+
diag.arg("depth", depth);
1372+
diag.arg("body_kind_descr", body_kind_descr);
1373+
diag.arg("body_name", body_name);
1374+
diag.arg("self_ty_str", self_ty_str);
1375+
if let Some(of_trait_str) = of_trait_str {
1376+
diag.arg("of_trait_str", of_trait_str);
1377+
}
1378+
1379+
if has_trait {
1380+
diag.note(fluent::lint_bounds);
1381+
diag.note(fluent::lint_with_trait);
1382+
} else {
1383+
diag.note(fluent::lint_without_trait);
1384+
}
1385+
1386+
if let Some((move_help, may_move)) = move_to {
1387+
let mut ms = MultiSpan::from_span(move_help);
1388+
for sp in may_move {
1389+
ms.push_span_label(sp, fluent::lint_non_local_definitions_may_move);
1390+
}
1391+
diag.span_help(ms, fluent::lint_non_local_definitions_impl_move_help);
1392+
}
1393+
1394+
if let Some((span, part)) = may_remove {
1395+
diag.arg("may_remove_part", part);
1396+
diag.span_suggestion(
1397+
span,
1398+
fluent::lint_remove_help,
1399+
"",
1400+
Applicability::MaybeIncorrect,
1401+
);
1402+
}
1403+
1404+
if let Some(cargo_update) = cargo_update {
1405+
diag.subdiagnostic(&diag.dcx, cargo_update);
1406+
}
1407+
if let Some(const_anon) = const_anon {
1408+
diag.note(fluent::lint_exception);
1409+
if let Some(const_anon) = const_anon {
1410+
diag.span_suggestion(
1411+
const_anon,
1412+
fluent::lint_const_anon,
1413+
"_",
1414+
Applicability::MachineApplicable,
1415+
);
1416+
}
1417+
}
1418+
1419+
diag.note(fluent::lint_non_local_definitions_deprecation);
1420+
}
1421+
NonLocalDefinitionsDiag::MacroRules {
1422+
depth,
1423+
body_kind_descr,
1424+
body_name,
1425+
help,
1426+
doctest_help,
1427+
cargo_update,
1428+
} => {
1429+
diag.primary_message(fluent::lint_non_local_definitions_macro_rules);
1430+
diag.arg("depth", depth);
1431+
diag.arg("body_kind_descr", body_kind_descr);
1432+
diag.arg("body_name", body_name);
1433+
1434+
if let Some(()) = help {
1435+
diag.help(fluent::lint_help);
1436+
}
1437+
if let Some(()) = doctest_help {
1438+
diag.help(fluent::lint_help_doctest);
1439+
}
1440+
1441+
diag.note(fluent::lint_non_local);
1442+
diag.note(fluent::lint_non_local_definitions_deprecation);
1443+
1444+
if let Some(cargo_update) = cargo_update {
1445+
diag.subdiagnostic(&diag.dcx, cargo_update);
1446+
}
1447+
}
1448+
}
1449+
}
1450+
}
1451+
13661452
#[derive(Subdiagnostic)]
13671453
#[note(lint_non_local_definitions_cargo_update)]
13681454
pub struct NonLocalDefinitionsCargoUpdateNote {

0 commit comments

Comments
 (0)