about summary refs log tree commit diff
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-02-16 19:27:48 -0800
committerdianne <diannes.gm@gmail.com>2025-02-16 19:27:48 -0800
commit82678df0de4369ca79164df93a56733a7538eac1 (patch)
treeb7fa7d81c7608635b56b8d59c60b1ddcdf2b5963
parent7af46307705f1ab76d3ad50a25cd8137766ea6b3 (diff)
downloadrust-82678df0de4369ca79164df93a56733a7538eac1.tar.gz
rust-82678df0de4369ca79164df93a56733a7538eac1.zip
bookkeep properly when pointing into macro expansions
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs34
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed2
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr6
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 7c2a2b3fdf7..c5c11c2bd25 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 c81c7d2a87b..e35896f32ad 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 33256e8cbb9..3dd91c86a3b 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