diff options
| author | dianne <diannes.gm@gmail.com> | 2025-01-01 15:19:11 -0800 |
|---|---|---|
| committer | dianne <diannes.gm@gmail.com> | 2025-01-07 23:15:42 -0800 |
| commit | e2f3ce956809dd98adf271afe0b024c7febdf47f (patch) | |
| tree | 9201d8842eab14b1bb67959b415556240bd8abbd | |
| parent | ff165d54cbfc4734ae889e861ef9fd94ecfc5375 (diff) | |
| download | rust-e2f3ce956809dd98adf271afe0b024c7febdf47f.tar.gz rust-e2f3ce956809dd98adf271afe0b024c7febdf47f.zip | |
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.
| -rw-r--r-- | compiler/rustc_hir_typeck/src/pat.rs | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 5e6cca51c92..391acce97bd 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -168,15 +168,16 @@ enum AdjustMode { Pass, } -/// `ref mut` patterns (explicit or match-ergonomics) -/// are not allowed behind an `&` reference. +/// `ref mut` bindings (explicit or match-ergonomics) are not allowed behind an `&` reference. +/// Normally, the borrow checker enforces this, but for (currently experimental) match ergonomics, +/// we track this when typing patterns for two purposes: /// -/// This includes explicit `ref mut` behind `&` patterns -/// that match against `&mut` references, -/// where the code would have compiled -/// had the pattern been written as `&mut`. -/// However, the borrow checker will not catch -/// this last case, so we need to throw an error ourselves. +/// - For RFC 3627's Rule 3, when this would prevent us from binding with `ref mut`, we limit the +/// default binding mode to be by shared `ref` when it would otherwise be `ref mut`. +/// +/// - For RFC 3627's Rule 5, we allow `&` patterns to match against `&mut` references, treating them +/// as if they were shared references. Since the scrutinee is mutable in this case, the borrow +/// checker won't catch if we bind with `ref mut`, so we need to throw an error ourselves. #[derive(Clone, Copy, Debug, PartialEq, Eq)] enum MutblCap { /// Mutability restricted to immutable. @@ -477,9 +478,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if features.ref_pat_eat_one_layer_2024() || features.ref_pat_eat_one_layer_2024_structural() { def_br = def_br.cap_ref_mutability(max_ref_mutbl.as_mutbl()); - if def_br == ByRef::Yes(Mutability::Not) { - max_ref_mutbl = MutblCap::Not; - } + } + if def_br == ByRef::Yes(Mutability::Not) { + max_ref_mutbl = MutblCap::Not; } if !pat_adjustments.is_empty() { @@ -2292,7 +2293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if (no_ref_mut_behind_and && r_mutbl >= pat_mutbl) || r_mutbl == pat_mutbl => { - if no_ref_mut_behind_and && r_mutbl == Mutability::Not { + if r_mutbl == Mutability::Not { pat_info.max_ref_mutbl = MutblCap::Not; } |
