Skip to content

Commit

Permalink
always track patterns' MutblCap
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dianne committed Jan 8, 2025
1 parent ff165d5 commit e2f3ce9
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit e2f3ce9

Please # to comment.