highlight the whole problem subpattern when pointing out the default binding mode

(cherry picked from commit 4331f55b72)
This commit is contained in:
dianne
2025-02-03 22:18:00 -08:00
parent f8b23cdb75
commit 2ee601ced6
5 changed files with 129 additions and 45 deletions

View File

@@ -2649,29 +2649,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// error if the subpattern is of edition >= 2024.
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
let mut typeck_results = self.typeck_results.borrow_mut();
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
let info = table.entry(pat_id).or_default();
info.primary_spans.push(trimmed_span);
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
let desc = if subpat.span.from_expansion() {
let from_expansion = subpat.span.from_expansion();
let primary_label = if from_expansion {
// NB: This wording assumes the only expansions that can produce problematic reference
// patterns and bindings are macros. If a desugaring or AST pass is added that can do
// so, we may want to inspect the span's source callee or macro backtrace.
"occurs within macro expansion"
} else {
match def_br_mutbl {
Mutability::Not => "default binding mode is `ref`",
Mutability::Mut => "default binding mode is `ref mut`",
if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
info.bad_modifiers |= true;
"this binding modifier"
} else {
info.bad_ref_pats |= true;
"this reference pattern"
}
};
info.span_labels.push((trimmed_span, primary_label.to_owned()));
let mut typeck_results = self.typeck_results.borrow_mut();
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
let info = table.entry(pat_id).or_default();
info.labels.push((trimmed_span, desc.to_owned()));
if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
info.bad_modifiers |= true;
} else {
info.bad_ref_pats |= true;
if !from_expansion {
// Add a secondary label covering the whole pattern noting the default binding mode
let def_br_desc = match def_br_mutbl {
Mutability::Not => "default binding mode is `ref`",
Mutability::Mut => "default binding mode is `ref mut`",
};
info.span_labels.push((subpat.span, def_br_desc.to_owned()));
}
}
}

View File

@@ -816,8 +816,10 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
/// emitted during THIR construction.
#[derive(TyEncodable, TyDecodable, Debug, HashStable, Default)]
pub struct Rust2024IncompatiblePatInfo {
/// Labels for subpatterns incompatible with Rust 2024.
pub labels: Vec<(Span, String)>,
/// Spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024.
pub primary_spans: Vec<Span>,
/// Labels for the primary spans and their patterns, to provide additional context.
pub span_labels: Vec<(Span, String)>,
/// Whether any binding modifiers occur under a non-`move` default binding mode.
pub bad_modifiers: bool,
/// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.

View File

@@ -59,8 +59,8 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
debug!("pat_from_hir({:?}) = {:?}", pat, result);
if let Some(info) = migration_info {
let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present");
let mut spans = MultiSpan::from_spans(info.labels.iter().map(|(span, _)| *span).collect());
for (span, label) in &info.labels {
let mut spans = MultiSpan::from_spans(info.primary_spans.clone());
for (span, label) in &info.span_labels {
spans.push_span_label(*span, label.clone());
}
// If a relevant span is from at least edition 2024, this is a hard error.

View File

@@ -2,7 +2,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/migration_lint.rs:25:13
|
LL | let Foo(mut x) = &Foo(0);
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -20,7 +23,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/migration_lint.rs:30:13
|
LL | let Foo(mut x) = &mut Foo(0);
| ^^^ default binding mode is `ref mut`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -33,7 +39,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/migration_lint.rs:35:13
|
LL | let Foo(ref x) = &Foo(0);
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -46,7 +55,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/migration_lint.rs:40:13
|
LL | let Foo(ref x) = &mut Foo(0);
| ^^^ default binding mode is `ref mut`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -59,7 +71,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:57:13
|
LL | let Foo(&x) = &Foo(&0);
| ^ default binding mode is `ref`
| ^-
| |
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -72,7 +87,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:62:13
|
LL | let Foo(&mut x) = &Foo(&mut 0);
| ^^^^ default binding mode is `ref`
| ^^^^--
| |
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -85,7 +103,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:67:13
|
LL | let Foo(&x) = &mut Foo(&0);
| ^ default binding mode is `ref mut`
| ^-
| |
| this reference pattern
| default binding mode is `ref mut`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -98,7 +119,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:72:13
|
LL | let Foo(&mut x) = &mut Foo(&mut 0);
| ^^^^ default binding mode is `ref mut`
| ^^^^--
| |
| this reference pattern
| default binding mode is `ref mut`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -111,7 +135,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:81:17
|
LL | if let Some(&x) = &&&&&Some(&0u8) {
| ^ default binding mode is `ref`
| ^-
| |
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -124,7 +151,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:87:17
|
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
| ^^^^ default binding mode is `ref`
| ^^^^--
| |
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -137,7 +167,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:93:17
|
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
| ^ default binding mode is `ref`
| ^-
| |
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -150,7 +183,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:99:17
|
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
| ^^^^ default binding mode is `ref mut`
| ^^^^--------------
| |
| this reference pattern
| default binding mode is `ref mut`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -163,7 +199,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/migration_lint.rs:111:21
|
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -176,8 +215,11 @@ error: binding modifiers and reference patterns may only be written when the def
--> $DIR/migration_lint.rs:117:21
|
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
| ^ ^^^ default binding mode is `ref`
| |
| ^- ^^^--
| | |
| | this binding modifier
| | default binding mode is `ref`
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
@@ -191,8 +233,11 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:124:24
|
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
| ^ ^ default binding mode is `ref`
| |
| ^------- ^-
| | |
| | this reference pattern
| | default binding mode is `ref`
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
@@ -206,8 +251,9 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/migration_lint.rs:137:15
|
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
| ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion
| ^^^-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
@@ -221,8 +267,11 @@ error: binding modifiers and reference patterns may only be written when the def
--> $DIR/migration_lint.rs:145:10
|
LL | let [&mut [ref a]] = &mut [&mut &[0]];
| ^^^^ ^^^ default binding mode is `ref`
| |
| ^^^^--^^^---
| | |
| | this binding modifier
| | default binding mode is `ref`
| this reference pattern
| default binding mode is `ref mut`
|
= warning: this changes meaning in Rust 2024
@@ -236,7 +285,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/migration_lint.rs:150:10
|
LL | let [&(_)] = &[&0];
| ^^ default binding mode is `ref`
| ^^--
| |
| this reference pattern
| default binding mode is `ref`
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>

View File

@@ -103,7 +103,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/min_match_ergonomics_fail.rs:24:20
|
LL | test_pat_on_type![(&x,): &(&T,)];
| ^ default binding mode is `ref`
| ^-
| |
| this reference pattern
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
@@ -115,7 +118,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
| ^^^^ default binding mode is `ref`
| ^^^^--
| |
| this reference pattern
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
@@ -127,7 +133,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/min_match_ergonomics_fail.rs:31:28
|
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
| ^ default binding mode is `ref`
| ^----
| |
| this reference pattern
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
@@ -139,7 +148,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/min_match_ergonomics_fail.rs:32:20
|
LL | test_pat_on_type![(mut x,): &(T,)];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
@@ -151,7 +163,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/min_match_ergonomics_fail.rs:33:20
|
LL | test_pat_on_type![(ref x,): &(T,)];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
@@ -163,7 +178,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/min_match_ergonomics_fail.rs:34:20
|
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
| ^^^^^^^ default binding mode is `ref mut`
| ^^^^^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
@@ -175,7 +193,10 @@ error: reference patterns may only be written when the default binding mode is `
--> $DIR/min_match_ergonomics_fail.rs:43:10
|
LL | (&x,) => x,
| ^ default binding mode is `ref`
| ^-
| |
| this reference pattern
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit