Skip to content

Commit

Permalink
Handle subpatterns from macro expansion
Browse files Browse the repository at this point in the history
Unfortunately, we can't always offer a machine-applicable suggestion in such cases.
  • Loading branch information
Jules-Bertholet committed May 12, 2024
1 parent 25b6844 commit e69752d
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 27 deletions.
12 changes: 7 additions & 5 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,10 +968,12 @@ impl Subdiagnostic for Rust2024IncompatiblePatSugg {
diag: &mut Diag<'_, G>,
_f: &F,
) {
diag.multipart_suggestion(
"desugar the match ergonomics",
self.suggestion,
Applicability::MachineApplicable,
);
let applicability =
if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) {
Applicability::MachineApplicable
} else {
Applicability::MaybeIncorrect
};
diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability);
}
}
8 changes: 4 additions & 4 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,14 +340,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
&& explicit_ba.0 == ByRef::No
&& let ByRef::Yes(mutbl) = mode.0
{
// `mut` resets binding mode on edition <= 2021
assert_eq!(mode.1, Mutability::Not);

let sugg_str = match mutbl {
Mutability::Not => "ref ",
Mutability::Mut => "ref mut ",
};
s.suggestion.push((pat.span.shrink_to_lo(), sugg_str.to_owned()))
s.suggestion.push((
pat.span.with_lo(ident.span.lo()).shrink_to_lo(),
sugg_str.to_owned(),
))
}

// A ref x pattern is the same node used for x, and as such it has
Expand Down
7 changes: 4 additions & 3 deletions tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//@ compile-flags: --edition 2024 -Z unstable-options
//@ edition: 2024
//@ compile-flags: -Z unstable-options

// This contains a binding in edition 2024, so if matched with a reference binding mode it will end
// up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with
// mixed editions.
#[macro_export]
macro_rules! mixed_edition_pat {
() => {
Some(mut _x)
($foo:ident) => {
Some(mut $foo)
};
}
18 changes: 17 additions & 1 deletion tests/ui/pattern/match_ergonomics_2024.fixed
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//@ edition: 2021
//@ run-rustfix
//@ rustfix-only-machine-applicable
//@ aux-build:match_ergonomics_2024_macros.rs
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)]
#![forbid(rust_2024_incompatible_pat)]
#![deny(rust_2024_incompatible_pat)]

extern crate match_ergonomics_2024_macros;

struct Foo(u8);

Expand Down Expand Up @@ -38,4 +42,16 @@ fn main() {
let s = Struct { a: 0, b: 0, c: 0 };
let &Struct { ref a, mut b, ref c } = &s;
//~^ ERROR: the semantics of this pattern will change in edition 2024

#[warn(rust_2024_incompatible_pat)]
match &(Some(0), Some(0)) {
// The two patterns are the same syntactically, but because they're defined in different
// editions they don't mean the same thing.
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
//~^ WARN: the semantics of this pattern will change in edition 2024
_x = 4;
_y = &7;
}
_ => {}
}
}
10 changes: 8 additions & 2 deletions tests/ui/pattern/match_ergonomics_2024.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//@ edition: 2021
//@ run-rustfix
//@ rustfix-only-machine-applicable
//@ aux-build:match_ergonomics_2024_macros.rs
#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)]
#![allow(incomplete_features, unused)]
#![forbid(rust_2024_incompatible_pat)]
#![deny(rust_2024_incompatible_pat)]

extern crate match_ergonomics_2024_macros;

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

#[warn(rust_2024_incompatible_pat)]
match &(Some(0), Some(0)) {
// The two patterns are the same syntactically, but because they're defined in different
// editions they don't mean the same thing.
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!()) => {}
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
//~^ WARN: the semantics of this pattern will change in edition 2024
_x = 4;
_y = &7;
}
_ => {}
}
}
40 changes: 28 additions & 12 deletions tests/ui/pattern/match_ergonomics_2024.stderr
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
error: the semantics of this pattern will change in edition 2024
--> $DIR/match_ergonomics_2024.rs:10:9
--> $DIR/match_ergonomics_2024.rs:14:9
|
LL | let Foo(mut a) = &Foo(0);
| -^^^^^^^^^
| |
| help: desugar the match ergonomics: `&`
|
note: the lint level is defined here
--> $DIR/match_ergonomics_2024.rs:5:11
--> $DIR/match_ergonomics_2024.rs:7:9
|
LL | #![forbid(rust_2024_incompatible_pat)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #![deny(rust_2024_incompatible_pat)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

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

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

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

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

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

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

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

error: aborting due to 8 previous errors
warning: the semantics of this pattern will change in edition 2024
--> $DIR/match_ergonomics_2024.rs:50:9
|
LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/match_ergonomics_2024.rs:46:12
|
LL | #[warn(rust_2024_incompatible_pat)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
help: desugar the match ergonomics
|
LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => {
| + +++

error: aborting due to 8 previous errors; 1 warning emitted

0 comments on commit e69752d

Please sign in to comment.