Skip to content

Commit e69752d

Browse files
Handle subpatterns from macro expansion
Unfortunately, we can't always offer a machine-applicable suggestion in such cases.
1 parent 25b6844 commit e69752d

File tree

6 files changed

+68
-27
lines changed

6 files changed

+68
-27
lines changed

compiler/rustc_mir_build/src/errors.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -968,10 +968,12 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg {
968968
diag: &mut Diag<'_, G>,
969969
_f: &F,
970970
) {
971-
diag.multipart_suggestion(
972-
"desugar the match ergonomics",
973-
self.suggestion,
974-
Applicability::MachineApplicable,
975-
);
971+
let applicability =
972+
if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
973+
Applicability::MachineApplicable
974+
} else {
975+
Applicability::MaybeIncorrect
976+
};
977+
diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability);
976978
}
977979
}

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
340340
&& explicit_ba.0 == ByRef::No
341341
&& let ByRef::Yes(mutbl) = mode.0
342342
{
343-
// `mut` resets binding mode on edition <= 2021
344-
assert_eq!(mode.1, Mutability::Not);
345-
346343
let sugg_str = match mutbl {
347344
Mutability::Not => "ref ",
348345
Mutability::Mut => "ref mut ",
349346
};
350-
s.suggestion.push((pat.span.shrink_to_lo(), sugg_str.to_owned()))
347+
s.suggestion.push((
348+
pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
349+
sugg_str.to_owned(),
350+
))
351351
}
352352

353353
// A ref x pattern is the same node used for x, and as such it has
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
//@ compile-flags: --edition 2024 -Z unstable-options
1+
//@ edition: 2024
2+
//@ compile-flags: -Z unstable-options
23

34
// This contains a binding in edition 2024, so if matched with a reference binding mode it will end
45
// up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with
56
// mixed editions.
67
#[macro_export]
78
macro_rules! mixed_edition_pat {
8-
() => {
9-
Some(mut _x)
9+
($foo:ident) => {
10+
Some(mut $foo)
1011
};
1112
}

tests/ui/pattern/match_ergonomics_2024.fixed

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
//@ edition: 2021
22
//@ run-rustfix
3+
//@ rustfix-only-machine-applicable
4+
//@ aux-build:match_ergonomics_2024_macros.rs
35
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
46
#![allow(incomplete_features, unused)]
5-
#![forbid(rust_2024_incompatible_pat)]
7+
#![deny(rust_2024_incompatible_pat)]
8+
9+
extern crate match_ergonomics_2024_macros;
610

711
struct Foo(u8);
812

@@ -38,4 +42,16 @@ fn main() {
3842
let s = Struct { a: 0, b: 0, c: 0 };
3943
let &Struct { ref a, mut b, ref c } = &s;
4044
//~^ ERROR: the semantics of this pattern will change in edition 2024
45+
46+
#[warn(rust_2024_incompatible_pat)]
47+
match &(Some(0), Some(0)) {
48+
// The two patterns are the same syntactically, but because they're defined in different
49+
// editions they don't mean the same thing.
50+
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
51+
//~^ WARN: the semantics of this pattern will change in edition 2024
52+
_x = 4;
53+
_y = &7;
54+
}
55+
_ => {}
56+
}
4157
}

tests/ui/pattern/match_ergonomics_2024.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//@ edition: 2021
22
//@ run-rustfix
3+
//@ rustfix-only-machine-applicable
34
//@ aux-build:match_ergonomics_2024_macros.rs
45
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
56
#![allow(incomplete_features, unused)]
6-
#![forbid(rust_2024_incompatible_pat)]
7+
#![deny(rust_2024_incompatible_pat)]
78

89
extern crate match_ergonomics_2024_macros;
910

@@ -42,10 +43,15 @@ fn main() {
4243
let Struct { a, mut b, c } = &s;
4344
//~^ ERROR: the semantics of this pattern will change in edition 2024
4445

46+
#[warn(rust_2024_incompatible_pat)]
4547
match &(Some(0), Some(0)) {
4648
// The two patterns are the same syntactically, but because they're defined in different
4749
// editions they don't mean the same thing.
48-
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!()) => {}
50+
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
51+
//~^ WARN: the semantics of this pattern will change in edition 2024
52+
_x = 4;
53+
_y = &7;
54+
}
4955
_ => {}
5056
}
5157
}
+28-12
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
error: the semantics of this pattern will change in edition 2024
2-
--> $DIR/match_ergonomics_2024.rs:10:9
2+
--> $DIR/match_ergonomics_2024.rs:14:9
33
|
44
LL | let Foo(mut a) = &Foo(0);
55
| -^^^^^^^^^
66
| |
77
| help: desugar the match ergonomics: `&`
88
|
99
note: the lint level is defined here
10-
--> $DIR/match_ergonomics_2024.rs:5:11
10+
--> $DIR/match_ergonomics_2024.rs:7:9
1111
|
12-
LL | #![forbid(rust_2024_incompatible_pat)]
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
LL | #![deny(rust_2024_incompatible_pat)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1414

1515
error: the semantics of this pattern will change in edition 2024
16-
--> $DIR/match_ergonomics_2024.rs:14:9
16+
--> $DIR/match_ergonomics_2024.rs:18:9
1717
|
1818
LL | let Foo(mut a) = &mut Foo(0);
1919
| -^^^^^^^^^
2020
| |
2121
| help: desugar the match ergonomics: `&mut`
2222

2323
error: the semantics of this pattern will change in edition 2024
24-
--> $DIR/match_ergonomics_2024.rs:18:12
24+
--> $DIR/match_ergonomics_2024.rs:22:12
2525
|
2626
LL | if let Some(&_) = &&&&&Some(&0u8) {}
2727
| -^^^^^^^
2828
| |
2929
| help: desugar the match ergonomics: `&&&&&`
3030

3131
error: the semantics of this pattern will change in edition 2024
32-
--> $DIR/match_ergonomics_2024.rs:21:12
32+
--> $DIR/match_ergonomics_2024.rs:25:12
3333
|
3434
LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
3535
| -^^^^^^^^^^^
3636
| |
3737
| help: desugar the match ergonomics: `&&&&&`
3838

3939
error: the semantics of this pattern will change in edition 2024
40-
--> $DIR/match_ergonomics_2024.rs:24:12
40+
--> $DIR/match_ergonomics_2024.rs:28:12
4141
|
4242
LL | if let Some(&_) = &&&&&mut Some(&0u8) {}
4343
| -^^^^^^^
4444
| |
4545
| help: desugar the match ergonomics: `&&&&&mut`
4646

4747
error: the semantics of this pattern will change in edition 2024
48-
--> $DIR/match_ergonomics_2024.rs:27:12
48+
--> $DIR/match_ergonomics_2024.rs:31:12
4949
|
5050
LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
5151
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut So
5656
| ++++ ++++
5757

5858
error: the semantics of this pattern will change in edition 2024
59-
--> $DIR/match_ergonomics_2024.rs:30:12
59+
--> $DIR/match_ergonomics_2024.rs:34:12
6060
|
6161
LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
6262
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -67,7 +67,7 @@ LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Som
6767
| ++++ ++++ +++++++
6868

6969
error: the semantics of this pattern will change in edition 2024
70-
--> $DIR/match_ergonomics_2024.rs:39:9
70+
--> $DIR/match_ergonomics_2024.rs:43:9
7171
|
7272
LL | let Struct { a, mut b, c } = &s;
7373
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -77,5 +77,21 @@ help: desugar the match ergonomics
7777
LL | let &Struct { ref a, mut b, ref c } = &s;
7878
| + +++ +++
7979

80-
error: aborting due to 8 previous errors
80+
warning: the semantics of this pattern will change in edition 2024
81+
--> $DIR/match_ergonomics_2024.rs:50:9
82+
|
83+
LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
84+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
85+
|
86+
note: the lint level is defined here
87+
--> $DIR/match_ergonomics_2024.rs:46:12
88+
|
89+
LL | #[warn(rust_2024_incompatible_pat)]
90+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
91+
help: desugar the match ergonomics
92+
|
93+
LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => {
94+
| + +++
95+
96+
error: aborting due to 8 previous errors; 1 warning emitted
8197

0 commit comments

Comments
 (0)