From 7af46307705f1ab76d3ad50a25cd8137766ea6b3 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 16 Feb 2025 19:17:52 -0800 Subject: [PATCH 1/2] add a failing test --- .../auxiliary/migration_lint_macros.rs | 7 +++++++ .../migration_lint.fixed | 5 +++++ .../migration_lint.rs | 5 +++++ .../migration_lint.stderr | 16 +++++++++++++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs index daa9b7368fd0e..b18f87fd56995 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs @@ -9,3 +9,10 @@ macro_rules! mixed_edition_pat { Some(mut $foo) }; } + +#[macro_export] +macro_rules! bind_ref { + ($foo:ident) => { + ref $foo + }; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 0a22e939496e5..c81c7d2a87b87 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -239,4 +239,9 @@ fn main() { assert_type_eq(b, &0u32); assert_type_eq(c, &[0u32]); assert_type_eq(d, 0u32); + + // Test that we use the correct message and suggestion style when pointing inside expansions. + let [migration_lint_macros::bind_ref!(a)] = &[0]; + //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 7a6f2269d44a2..10a23e6f2fa18 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -239,4 +239,9 @@ fn main() { assert_type_eq(b, &0u32); assert_type_eq(c, &[0u32]); assert_type_eq(d, 0u32); + + // Test that we use the correct message and suggestion style when pointing inside expansions. + let [migration_lint_macros::bind_ref!(a)] = &[0]; + //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 191800df07a2e..33256e8cbb9b0 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -562,5 +562,19 @@ help: make the implied reference patterns explicit LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; | + + -error: aborting due to 29 previous errors +error: reference patterns may only be written when the default binding mode is `move` + --> $DIR/migration_lint.rs:244:10 + | +LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/migration_lint.rs:244:9 + | +LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` + = note: this error originates in the macro `migration_lint_macros::bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 30 previous errors From 82678df0de4369ca79164df93a56733a7538eac1 Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 16 Feb 2025 19:27:48 -0800 Subject: [PATCH 2/2] bookkeep properly when pointing into macro expansions --- compiler/rustc_hir_typeck/src/pat.rs | 34 ++++++++++--------- .../migration_lint.fixed | 2 +- .../migration_lint.stderr | 6 +++- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 7c2a2b3fdf7da..c5c11c2bd2535 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2806,31 +2806,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !self.tcx.features().ref_pat_eat_one_layer_2024_structural(), }); + let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind { + info.bad_modifiers = true; + // If the user-provided binding modifier doesn't match the default binding mode, we'll + // need to suggest reference patterns, which can affect other bindings. + // For simplicity, we opt to suggest making the pattern fully explicit. + info.suggest_eliding_modes &= + user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not); + "binding modifier" + } else { + info.bad_ref_pats = true; + // For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll + // suggest adding them instead, which can affect the types assigned to bindings. + // As such, we opt to suggest making the pattern fully explicit. + info.suggest_eliding_modes = false; + "reference pattern" + }; // 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 from_expansion = subpat.span.from_expansion(); let primary_label = if from_expansion { + // We can't suggest eliding modifiers within expansions. + info.suggest_eliding_modes = false; // 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".to_owned() } else { - let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind { - info.bad_modifiers |= true; - // If the user-provided binding modifier doesn't match the default binding mode, we'll - // need to suggest reference patterns, which can affect other bindings. - // For simplicity, we opt to suggest making the pattern fully explicit. - info.suggest_eliding_modes &= - user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not); - "binding modifier" - } else { - info.bad_ref_pats |= true; - // For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll - // suggest adding them instead, which can affect the types assigned to bindings. - // As such, we opt to suggest making the pattern fully explicit. - info.suggest_eliding_modes = false; - "reference pattern" - }; let dbm_str = match def_br_mutbl { Mutability::Not => "ref", Mutability::Mut => "ref mut", diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index c81c7d2a87b87..e35896f32ad7d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -241,7 +241,7 @@ fn main() { assert_type_eq(d, 0u32); // Test that we use the correct message and suggestion style when pointing inside expansions. - let [migration_lint_macros::bind_ref!(a)] = &[0]; + let &[migration_lint_macros::bind_ref!(a)] = &[0]; //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 33256e8cbb9b0..3dd91c86a3b8f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -562,7 +562,7 @@ help: make the implied reference patterns explicit LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; | + + -error: reference patterns may only be written when the default binding mode is `move` +error: binding modifiers may only be written when the default binding mode is `move` --> $DIR/migration_lint.rs:244:10 | LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; @@ -575,6 +575,10 @@ note: matching on a reference type with a non-reference pattern changes the defa LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` = note: this error originates in the macro `migration_lint_macros::bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) +help: make the implied reference pattern explicit + | +LL | let &[migration_lint_macros::bind_ref!(a)] = &[0]; + | + error: aborting due to 30 previous errors