Skip to content

Commit e2f3ce9

Browse files
committed
always track patterns' MutblCap
If Rules 3 or 5 are adopted in any edition, we'll need to track the `MutblCap` in all editions for macro hygiene purposes. Previously, the check for whether to track it was conflated with the checks for whether to apply Rules 3 and 5, so to make it a bit clearer, this always tracks the `MutblCap`. If needed, we could check if Rules 3 or 5 are present in any edition before tracking the `MutblCap`, but since it's not that much more expensive to always track it, I've figured that's simplest. My main concern with removing the checks is that it may not be clear that the `MutblCap` is tracked for those specific purposes. To try and mitigate this, I've made its doc comment a bit more precise regarding the extent of how and why it's used. This leaves the condition untouched on the `cap_to_weakly_not` call needed for Rule 5, since it's only needed for that and it can affect diagnostics.
1 parent ff165d5 commit e2f3ce9

File tree

1 file changed

+13
-12
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+13
-12
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,16 @@ enum AdjustMode {
168168
Pass,
169169
}
170170

171-
/// `ref mut` patterns (explicit or match-ergonomics)
172-
/// are not allowed behind an `&` reference.
171+
/// `ref mut` bindings (explicit or match-ergonomics) are not allowed behind an `&` reference.
172+
/// Normally, the borrow checker enforces this, but for (currently experimental) match ergonomics,
173+
/// we track this when typing patterns for two purposes:
173174
///
174-
/// This includes explicit `ref mut` behind `&` patterns
175-
/// that match against `&mut` references,
176-
/// where the code would have compiled
177-
/// had the pattern been written as `&mut`.
178-
/// However, the borrow checker will not catch
179-
/// this last case, so we need to throw an error ourselves.
175+
/// - For RFC 3627's Rule 3, when this would prevent us from binding with `ref mut`, we limit the
176+
/// default binding mode to be by shared `ref` when it would otherwise be `ref mut`.
177+
///
178+
/// - For RFC 3627's Rule 5, we allow `&` patterns to match against `&mut` references, treating them
179+
/// as if they were shared references. Since the scrutinee is mutable in this case, the borrow
180+
/// checker won't catch if we bind with `ref mut`, so we need to throw an error ourselves.
180181
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
181182
enum MutblCap {
182183
/// Mutability restricted to immutable.
@@ -477,9 +478,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
477478
if features.ref_pat_eat_one_layer_2024() || features.ref_pat_eat_one_layer_2024_structural()
478479
{
479480
def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl());
480-
if def_br == ByRef::Yes(Mutability::Not) {
481-
max_ref_mutbl = MutblCap::Not;
482-
}
481+
}
482+
if def_br == ByRef::Yes(Mutability::Not) {
483+
max_ref_mutbl = MutblCap::Not;
483484
}
484485

485486
if !pat_adjustments.is_empty() {
@@ -2292,7 +2293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22922293
if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl)
22932294
|| r_mutbl == pat_mutbl =>
22942295
{
2295-
if no_ref_mut_behind_and && r_mutbl == Mutability::Not {
2296+
if r_mutbl == Mutability::Not {
22962297
pat_info.max_ref_mutbl = MutblCap::Not;
22972298
}
22982299

0 commit comments

Comments
 (0)