Skip to content

Commit 4dc2368

Browse files
committed
Add a variant to fallback_to_outer
1 parent 816737b commit 4dc2368

File tree

120 files changed

+212
-160
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+212
-160
lines changed

src/ast/printer.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -346,10 +346,9 @@ impl Rule {
346346
extras.push(format!("{x:?}"))
347347
}
348348
if let Deref(_, _, x) = *self
349-
&& options.fallback_to_outer
350-
&& x == FallbackToOuter(true)
349+
&& x != FallbackToOuter(FallbackToOuterBehavior::No)
351350
{
352-
extras.push(format!("FallbackToOuter"))
351+
extras.push(format!("FallbackToOuter({:?})", x.0))
353352
}
354353

355354
let mut out = variant_name.to_string();

src/rulesets/ty_based.rs

+31-10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ pub enum InheritedRefOnRefBehavior {
4444
Error,
4545
}
4646

47+
/// In `InheritedRefOnRefBehavior::EatBoth` or `EatInner` modes, what to do if a reference pattern
48+
/// fails to match against an underlying place of reference type.
49+
#[derive(
50+
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Encode, Decode,
51+
)]
52+
pub enum FallbackToOuterBehavior {
53+
/// Do nothing.
54+
No,
55+
/// If there is an inherited reference, match against it and consume it.
56+
EatOuter,
57+
/// If there is an inherited reference, match against it and consume both references.
58+
EatBoth,
59+
}
60+
4761
/// Choice of typing rules.
4862
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode)]
4963
pub struct RuleOptions {
@@ -55,9 +69,10 @@ pub struct RuleOptions {
5569
/// What happens with a `&mut?p` pattern matching on `&mut?&mut?T` where the outer reference is
5670
/// inherited.
5771
pub inherited_ref_on_ref: InheritedRefOnRefBehavior,
58-
/// In the `EatBoth` and `EatInner` cases, if matching against the underlying place fails this
59-
/// determines whether we try again in `EatOuter` mode.
60-
pub fallback_to_outer: bool,
72+
/// In `InheritedRefOnRefBehavior::EatBoth` or `EatInner` modes, if a reference pattern fails
73+
/// to match against an underlying place of reference type, and there is an inherited
74+
/// reference, this determines if we try matching against it.
75+
pub fallback_to_outer: FallbackToOuterBehavior,
6176
/// Whether a `&p` pattern is allowed on `&mut T`. This is RFC3627 rule 5.
6277
pub allow_ref_pat_on_ref_mut: bool,
6378
/// Whether to simplify some expressions, which removes some borrow errors involving mixes of
@@ -249,15 +264,21 @@ pub const TY_BASED_OPTIONS_DOC: &[OptionsDoc] = &[
249264
case has a mutability mismatch",
250265
values: &[
251266
OptionValue {
252-
name: "false",
267+
name: "No",
253268
doc: "Don't try matching on the outer reference if \
254269
matching on the inner reference caused a mutability mismatch",
255270
},
256271
OptionValue {
257-
name: "true",
272+
name: "EatOuter",
258273
doc: "Try matching on the outer reference if \
259274
matching on the inner reference caused a mutability mismatch",
260275
},
276+
OptionValue {
277+
name: "EatBoth",
278+
doc: "Try matching on the outer reference if \
279+
matching on the inner reference caused a mutability mismatch. \
280+
If this succeeds, consume both references.",
281+
},
261282
],
262283
},
263284
OptionsDoc {
@@ -370,7 +391,7 @@ impl RuleOptions {
370391
ref_binding_on_inherited: RefBindingOnInheritedBehavior::ResetBindingMode,
371392
mut_binding_on_inherited: MutBindingOnInheritedBehavior::ResetBindingMode,
372393
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatBoth,
373-
fallback_to_outer: false,
394+
fallback_to_outer: FallbackToOuterBehavior::No,
374395
allow_ref_pat_on_ref_mut: false,
375396
simplify_deref_mut: true,
376397
eat_inherited_ref_alone: false,
@@ -384,7 +405,7 @@ impl RuleOptions {
384405
ref_binding_on_inherited: RefBindingOnInheritedBehavior::ResetBindingMode,
385406
mut_binding_on_inherited: MutBindingOnInheritedBehavior::Error,
386407
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatInner,
387-
fallback_to_outer: true,
408+
fallback_to_outer: FallbackToOuterBehavior::EatOuter,
388409
allow_ref_pat_on_ref_mut: true,
389410
simplify_deref_mut: true,
390411
eat_inherited_ref_alone: true,
@@ -399,7 +420,7 @@ impl RuleOptions {
399420
ref_binding_on_inherited: RefBindingOnInheritedBehavior::AllocTemporary,
400421
mut_binding_on_inherited: MutBindingOnInheritedBehavior::Keep,
401422
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatOuter,
402-
fallback_to_outer: false,
423+
fallback_to_outer: FallbackToOuterBehavior::No,
403424
allow_ref_pat_on_ref_mut: true,
404425
simplify_deref_mut: true,
405426
eat_inherited_ref_alone: true,
@@ -434,14 +455,14 @@ impl RuleOptions {
434455
pub const RFC3627_2021: Self = RuleOptions {
435456
mut_binding_on_inherited: MutBindingOnInheritedBehavior::ResetBindingMode,
436457
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatBoth,
437-
fallback_to_outer: true,
458+
fallback_to_outer: FallbackToOuterBehavior::EatOuter,
438459
..RuleOptions::ERGO2024
439460
};
440461

441462
pub const ERGO2024_BREAKING_ONLY: Self = RuleOptions {
442463
mut_binding_on_inherited: MutBindingOnInheritedBehavior::Error,
443464
inherited_ref_on_ref: InheritedRefOnRefBehavior::EatInner,
444-
fallback_to_outer: false,
465+
fallback_to_outer: FallbackToOuterBehavior::No,
445466
..RuleOptions::STABLE_RUST
446467
};
447468

src/solvers/typing_rules.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub enum DowngradeMutToRef {
3030
}
3131

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

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

140140
// We only inspect the binding mode if there are options that need it.
@@ -167,11 +167,22 @@ impl<'a> TypingPredicate<'a> {
167167
reborrow_after = Some(t_mtbl);
168168
t_mtbl = *inner_mtbl;
169169
underlying_place.deref(a)
170-
} else if o.fallback_to_outer {
171-
fallback_to_outer = FallbackToOuter(true);
172-
self.expr.deref(a)
173170
} else {
174-
return Err(TypeError::MutabilityMismatch);
171+
match o.fallback_to_outer {
172+
FallbackToOuterBehavior::No => {
173+
return Err(TypeError::MutabilityMismatch)
174+
}
175+
FallbackToOuterBehavior::EatOuter => {
176+
fallback_to_outer =
177+
FallbackToOuter(o.fallback_to_outer);
178+
self.expr.deref(a)
179+
}
180+
FallbackToOuterBehavior::EatBoth => {
181+
fallback_to_outer =
182+
FallbackToOuter(o.fallback_to_outer);
183+
self.expr.deref(a).deref(a)
184+
}
185+
}
175186
}
176187
}
177188
InheritedRefOnRefBehavior::EatBoth => {
@@ -186,11 +197,22 @@ impl<'a> TypingPredicate<'a> {
186197
if can_eat_inner {
187198
t_mtbl = *inner_mtbl;
188199
underlying_place.deref(a)
189-
} else if o.fallback_to_outer {
190-
fallback_to_outer = FallbackToOuter(true);
191-
self.expr.deref(a)
192200
} else {
193-
return Err(TypeError::MutabilityMismatch);
201+
match o.fallback_to_outer {
202+
FallbackToOuterBehavior::No => {
203+
return Err(TypeError::MutabilityMismatch)
204+
}
205+
FallbackToOuterBehavior::EatOuter => {
206+
fallback_to_outer =
207+
FallbackToOuter(o.fallback_to_outer);
208+
self.expr.deref(a)
209+
}
210+
FallbackToOuterBehavior::EatBoth => {
211+
fallback_to_outer =
212+
FallbackToOuter(o.fallback_to_outer);
213+
self.expr.deref(a).deref(a)
214+
}
215+
}
194216
}
195217
}
196218
InheritedRefOnRefBehavior::Error => {

tests/snapshots/bundle_rules@min_ergonomics-Expression.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: Error
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/bundle_rules@min_ergonomics-Sequent.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: Error
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/bundle_rules@min_ergonomics-SequentBindingMode.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: Error
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/[email protected]

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatOuter
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/[email protected]

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatOuter
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/[email protected]

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatOuter
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/[email protected]

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatInner
9-
fallback_to_outer: true
9+
fallback_to_outer: EatOuter
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: true
@@ -79,7 +79,7 @@ p @ &mut *e: &mut T
7979
&mut p @ &mut e: &mut &mut T, e mutable
8080

8181
p @ *&mut e: &T
82-
------------------------ "Deref(EatInner, FallbackToOuter)"
82+
------------------------ "Deref(EatInner, FallbackToOuter(EatOuter))"
8383
&mut p @ &mut e: &mut &T
8484

8585
p @ &*e: &T

tests/snapshots/[email protected]

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatInner
9-
fallback_to_outer: true
9+
fallback_to_outer: EatOuter
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: true
@@ -79,7 +79,7 @@ inh, rw ⊢ p: &mut T
7979
inh, rw&mut p: &mut &mut T
8080

8181
real, mp: &T
82-
------------------------ "Deref(EatInner, FallbackToOuter)"
82+
------------------------ "Deref(EatInner, FallbackToOuter(EatOuter))"
8383
inh, m&mut p: &mut &T
8484

8585
inh, rop: &T

tests/snapshots/[email protected]

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatInner
9-
fallback_to_outer: true
9+
fallback_to_outer: EatOuter
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: true
@@ -111,7 +111,7 @@ ref mut, rw ⊢ p: T
111111
ref mut, rw&mut p: &mut T
112112

113113
move, mp: &T
114-
----------------------- "Deref(EatInner, FallbackToOuter)"
114+
----------------------- "Deref(EatInner, FallbackToOuter(EatOuter))"
115115
ref mut, m&mut p: &T
116116

117117
ref, rop: T

tests/snapshots/bundle_rules@rfc3627_2021-Expression.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatBoth
9-
fallback_to_outer: true
9+
fallback_to_outer: EatOuter
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: true
@@ -83,7 +83,7 @@ p @ *e: T
8383
&mut p @ &mut e: &mut &mut T
8484

8585
p @ *&mut e: &T
86-
------------------------ "Deref(EatBoth, FallbackToOuter)"
86+
------------------------ "Deref(EatBoth, FallbackToOuter(EatOuter))"
8787
&mut p @ &mut e: &mut &T
8888

8989
p @ *&*e: T

tests/snapshots/bundle_rules@rfc3627_2021-Sequent.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatBoth
9-
fallback_to_outer: true
9+
fallback_to_outer: EatOuter
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: true
@@ -83,7 +83,7 @@ real, m ⊢ p: T
8383
inh, m&mut p: &mut &mut T
8484

8585
real, mp: &T
86-
------------------------ "Deref(EatBoth, FallbackToOuter)"
86+
------------------------ "Deref(EatBoth, FallbackToOuter(EatOuter))"
8787
inh, m&mut p: &mut &T
8888

8989
real, rop: T

tests/snapshots/bundle_rules@rfc3627_2021-SequentBindingMode.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: true
88
inherited_ref_on_ref: EatBoth
9-
fallback_to_outer: true
9+
fallback_to_outer: EatOuter
1010
allow_ref_pat_on_ref_mut: true
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: true
@@ -115,7 +115,7 @@ move, m ⊢ p: T
115115
ref mut, m&mut p: &mut T
116116

117117
move, mp: &T
118-
----------------------- "Deref(EatBoth, FallbackToOuter)"
118+
----------------------- "Deref(EatBoth, FallbackToOuter(EatOuter))"
119119
ref mut, m&mut p: &T
120120

121121
move, rop: T

tests/snapshots/bundle_rules@rfc3627_2024_min-Expression.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: EatInner
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/bundle_rules@rfc3627_2024_min-Sequent.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: EatInner
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/bundle_rules@rfc3627_2024_min-SequentBindingMode.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: EatInner
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/bundle_rules@stable_rust-Expression.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: EatBoth
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

tests/snapshots/bundle_rules@stable_rust-Sequent.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ info:
66
match_constructor_through_ref: true
77
eat_inherited_ref_alone: false
88
inherited_ref_on_ref: EatBoth
9-
fallback_to_outer: false
9+
fallback_to_outer: "No"
1010
allow_ref_pat_on_ref_mut: false
1111
simplify_deref_mut: true
1212
downgrade_mut_inside_shared: false

0 commit comments

Comments
 (0)