Skip to content

Commit

Permalink
Rollup merge of rust-lang#137161 - dianne:pat-migration-bookkeeping-f…
Browse files Browse the repository at this point in the history
…or-macros, r=Nadrieril

Pattern Migration 2024: fix incorrect messages/suggestions when errors arise in macro expansions

See the diff between the two commits for how this affected the error message and suggestion. In order to decide how to format those, the pattern migration diagnostic keeps track of which parts of the user's pattern cause problems in Edition 2024. However, it neglected to do some of this bookkeeping when pointing to macro expansion sites. This fixes that.
  • Loading branch information
matthiaskrgr authored Feb 18, 2025
2 parents 387e069 + 82678df commit 809a28e
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 17 deletions.
34 changes: 18 additions & 16 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ macro_rules! mixed_edition_pat {
Some(mut $foo)
};
}

#[macro_export]
macro_rules! bind_ref {
($foo:ident) => {
ref $foo
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -562,5 +562,23 @@ 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: 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];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
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)
help: make the implied reference pattern explicit
|
LL | let &[migration_lint_macros::bind_ref!(a)] = &[0];
| +

error: aborting due to 30 previous errors

0 comments on commit 809a28e

Please sign in to comment.