Skip to content

Commit

Permalink
Add a variant to fallback_to_outer
Browse files Browse the repository at this point in the history
  • Loading branch information
Nadrieril committed Jan 18, 2025
1 parent 816737b commit 4dc2368
Show file tree
Hide file tree
Showing 120 changed files with 212 additions and 160 deletions.
5 changes: 2 additions & 3 deletions src/ast/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,9 @@ impl Rule {
extras.push(format!("{x:?}"))
}
if let Deref(_, _, x) = *self
&& options.fallback_to_outer
&& x == FallbackToOuter(true)
&& x != FallbackToOuter(FallbackToOuterBehavior::No)
{
extras.push(format!("FallbackToOuter"))
extras.push(format!("FallbackToOuter({:?})", x.0))
}

let mut out = variant_name.to_string();
Expand Down
41 changes: 31 additions & 10 deletions src/rulesets/ty_based.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ pub enum InheritedRefOnRefBehavior {
Error,
}

/// In `InheritedRefOnRefBehavior::EatBoth` or `EatInner` modes, what to do if a reference pattern
/// fails to match against an underlying place of reference type.
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Encode, Decode,
)]
pub enum FallbackToOuterBehavior {
/// Do nothing.
No,
/// If there is an inherited reference, match against it and consume it.
EatOuter,
/// If there is an inherited reference, match against it and consume both references.
EatBoth,
}

/// Choice of typing rules.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode)]
pub struct RuleOptions {
Expand All @@ -55,9 +69,10 @@ pub struct RuleOptions {
/// What happens with a `&mut?p` pattern matching on `&mut?&mut?T` where the outer reference is
/// inherited.
pub inherited_ref_on_ref: InheritedRefOnRefBehavior,
/// In the `EatBoth` and `EatInner` cases, if matching against the underlying place fails this
/// determines whether we try again in `EatOuter` mode.
pub fallback_to_outer: bool,
/// In `InheritedRefOnRefBehavior::EatBoth` or `EatInner` modes, if a reference pattern fails
/// to match against an underlying place of reference type, and there is an inherited
/// reference, this determines if we try matching against it.
pub fallback_to_outer: FallbackToOuterBehavior,
/// Whether a `&p` pattern is allowed on `&mut T`. This is RFC3627 rule 5.
pub allow_ref_pat_on_ref_mut: bool,
/// Whether to simplify some expressions, which removes some borrow errors involving mixes of
Expand Down Expand Up @@ -249,15 +264,21 @@ pub const TY_BASED_OPTIONS_DOC: &[OptionsDoc] = &[
case has a mutability mismatch",
values: &[
OptionValue {
name: "false",
name: "No",
doc: "Don't try matching on the outer reference if \
matching on the inner reference caused a mutability mismatch",
},
OptionValue {
name: "true",
name: "EatOuter",
doc: "Try matching on the outer reference if \
matching on the inner reference caused a mutability mismatch",
},
OptionValue {
name: "EatBoth",
doc: "Try matching on the outer reference if \
matching on the inner reference caused a mutability mismatch. \
If this succeeds, consume both references.",
},
],
},
OptionsDoc {
Expand Down Expand Up @@ -370,7 +391,7 @@ impl RuleOptions {
ref_binding_on_inherited: RefBindingOnInheritedBehavior::ResetBindingMode,
mut_binding_on_inherited: MutBindingOnInheritedBehavior::ResetBindingMode,
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatBoth,
fallback_to_outer: false,
fallback_to_outer: FallbackToOuterBehavior::No,
allow_ref_pat_on_ref_mut: false,
simplify_deref_mut: true,
eat_inherited_ref_alone: false,
Expand All @@ -384,7 +405,7 @@ impl RuleOptions {
ref_binding_on_inherited: RefBindingOnInheritedBehavior::ResetBindingMode,
mut_binding_on_inherited: MutBindingOnInheritedBehavior::Error,
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatInner,
fallback_to_outer: true,
fallback_to_outer: FallbackToOuterBehavior::EatOuter,
allow_ref_pat_on_ref_mut: true,
simplify_deref_mut: true,
eat_inherited_ref_alone: true,
Expand All @@ -399,7 +420,7 @@ impl RuleOptions {
ref_binding_on_inherited: RefBindingOnInheritedBehavior::AllocTemporary,
mut_binding_on_inherited: MutBindingOnInheritedBehavior::Keep,
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatOuter,
fallback_to_outer: false,
fallback_to_outer: FallbackToOuterBehavior::No,
allow_ref_pat_on_ref_mut: true,
simplify_deref_mut: true,
eat_inherited_ref_alone: true,
Expand Down Expand Up @@ -434,14 +455,14 @@ impl RuleOptions {
pub const RFC3627_2021: Self = RuleOptions {
mut_binding_on_inherited: MutBindingOnInheritedBehavior::ResetBindingMode,
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatBoth,
fallback_to_outer: true,
fallback_to_outer: FallbackToOuterBehavior::EatOuter,
..RuleOptions::ERGO2024
};

pub const ERGO2024_BREAKING_ONLY: Self = RuleOptions {
mut_binding_on_inherited: MutBindingOnInheritedBehavior::Error,
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatInner,
fallback_to_outer: false,
fallback_to_outer: FallbackToOuterBehavior::No,
..RuleOptions::STABLE_RUST
};

Expand Down
42 changes: 32 additions & 10 deletions src/solvers/typing_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub enum DowngradeMutToRef {
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FallbackToOuter(pub bool);
pub struct FallbackToOuter(pub FallbackToOuterBehavior);

#[derive(Debug, Clone, Copy)]
pub enum TypeError {
Expand Down Expand Up @@ -134,7 +134,7 @@ impl<'a> TypingPredicate<'a> {
// Dereference rules
(P::Ref(p_mtbl, p_inner), T::Ref(mut t_mtbl, _)) => {
let mut rule_variant = InheritedRefOnRefBehavior::EatOuter;
let mut fallback_to_outer = FallbackToOuter(false);
let mut fallback_to_outer = FallbackToOuter(FallbackToOuterBehavior::No);
let mut reborrow_after = None;

// We only inspect the binding mode if there are options that need it.
Expand Down Expand Up @@ -167,11 +167,22 @@ impl<'a> TypingPredicate<'a> {
reborrow_after = Some(t_mtbl);
t_mtbl = *inner_mtbl;
underlying_place.deref(a)
} else if o.fallback_to_outer {
fallback_to_outer = FallbackToOuter(true);
self.expr.deref(a)
} else {
return Err(TypeError::MutabilityMismatch);
match o.fallback_to_outer {
FallbackToOuterBehavior::No => {
return Err(TypeError::MutabilityMismatch)
}
FallbackToOuterBehavior::EatOuter => {
fallback_to_outer =
FallbackToOuter(o.fallback_to_outer);
self.expr.deref(a)
}
FallbackToOuterBehavior::EatBoth => {
fallback_to_outer =
FallbackToOuter(o.fallback_to_outer);
self.expr.deref(a).deref(a)
}
}
}
}
InheritedRefOnRefBehavior::EatBoth => {
Expand All @@ -186,11 +197,22 @@ impl<'a> TypingPredicate<'a> {
if can_eat_inner {
t_mtbl = *inner_mtbl;
underlying_place.deref(a)
} else if o.fallback_to_outer {
fallback_to_outer = FallbackToOuter(true);
self.expr.deref(a)
} else {
return Err(TypeError::MutabilityMismatch);
match o.fallback_to_outer {
FallbackToOuterBehavior::No => {
return Err(TypeError::MutabilityMismatch)
}
FallbackToOuterBehavior::EatOuter => {
fallback_to_outer =
FallbackToOuter(o.fallback_to_outer);
self.expr.deref(a)
}
FallbackToOuterBehavior::EatBoth => {
fallback_to_outer =
FallbackToOuter(o.fallback_to_outer);
self.expr.deref(a).deref(a)
}
}
}
}
InheritedRefOnRefBehavior::Error => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: Error
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@min_ergonomics-Sequent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: Error
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: Error
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@nadri-Expression.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatOuter
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@nadri-Sequent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatOuter
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@nadri-SequentBindingMode.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatOuter
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
4 changes: 2 additions & 2 deletions tests/snapshots/bundle_rules@rfc3627-Expression.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatInner
fallback_to_outer: true
fallback_to_outer: EatOuter
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: true
Expand Down Expand Up @@ -79,7 +79,7 @@ p @ &mut *e: &mut T
&mut p @ &mut e: &mut &mut T, e mutable

p @ *&mut e: &T
------------------------ "Deref(EatInner, FallbackToOuter)"
------------------------ "Deref(EatInner, FallbackToOuter(EatOuter))"
&mut p @ &mut e: &mut &T

p @ &*e: &T
Expand Down
4 changes: 2 additions & 2 deletions tests/snapshots/bundle_rules@rfc3627-Sequent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatInner
fallback_to_outer: true
fallback_to_outer: EatOuter
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: true
Expand Down Expand Up @@ -79,7 +79,7 @@ inh, rw ⊢ p: &mut T
inh, rw&mut p: &mut &mut T

real, mp: &T
------------------------ "Deref(EatInner, FallbackToOuter)"
------------------------ "Deref(EatInner, FallbackToOuter(EatOuter))"
inh, m&mut p: &mut &T

inh, rop: &T
Expand Down
4 changes: 2 additions & 2 deletions tests/snapshots/bundle_rules@rfc3627-SequentBindingMode.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatInner
fallback_to_outer: true
fallback_to_outer: EatOuter
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: true
Expand Down Expand Up @@ -111,7 +111,7 @@ ref mut, rw ⊢ p: T
ref mut, rw&mut p: &mut T

move, mp: &T
----------------------- "Deref(EatInner, FallbackToOuter)"
----------------------- "Deref(EatInner, FallbackToOuter(EatOuter))"
ref mut, m&mut p: &T

ref, rop: T
Expand Down
4 changes: 2 additions & 2 deletions tests/snapshots/bundle_rules@rfc3627_2021-Expression.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatBoth
fallback_to_outer: true
fallback_to_outer: EatOuter
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: true
Expand Down Expand Up @@ -83,7 +83,7 @@ p @ *e: T
&mut p @ &mut e: &mut &mut T

p @ *&mut e: &T
------------------------ "Deref(EatBoth, FallbackToOuter)"
------------------------ "Deref(EatBoth, FallbackToOuter(EatOuter))"
&mut p @ &mut e: &mut &T

p @ *&*e: T
Expand Down
4 changes: 2 additions & 2 deletions tests/snapshots/bundle_rules@rfc3627_2021-Sequent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatBoth
fallback_to_outer: true
fallback_to_outer: EatOuter
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: true
Expand Down Expand Up @@ -83,7 +83,7 @@ real, m ⊢ p: T
inh, m&mut p: &mut &mut T

real, mp: &T
------------------------ "Deref(EatBoth, FallbackToOuter)"
------------------------ "Deref(EatBoth, FallbackToOuter(EatOuter))"
inh, m&mut p: &mut &T

real, rop: T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: true
inherited_ref_on_ref: EatBoth
fallback_to_outer: true
fallback_to_outer: EatOuter
allow_ref_pat_on_ref_mut: true
simplify_deref_mut: true
downgrade_mut_inside_shared: true
Expand Down Expand Up @@ -115,7 +115,7 @@ move, m ⊢ p: T
ref mut, m&mut p: &mut T

move, mp: &T
----------------------- "Deref(EatBoth, FallbackToOuter)"
----------------------- "Deref(EatBoth, FallbackToOuter(EatOuter))"
ref mut, m&mut p: &T

move, rop: T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: EatInner
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@rfc3627_2024_min-Sequent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: EatInner
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: EatInner
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@stable_rust-Expression.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: EatBoth
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
2 changes: 1 addition & 1 deletion tests/snapshots/bundle_rules@stable_rust-Sequent.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ info:
match_constructor_through_ref: true
eat_inherited_ref_alone: false
inherited_ref_on_ref: EatBoth
fallback_to_outer: false
fallback_to_outer: "No"
allow_ref_pat_on_ref_mut: false
simplify_deref_mut: true
downgrade_mut_inside_shared: false
Expand Down
Loading

0 comments on commit 4dc2368

Please sign in to comment.