@@ -1613,8 +1613,10 @@ pub enum StatementKind<'tcx> {
1613
1613
Assign ( Place < ' tcx > , Rvalue < ' tcx > ) ,
1614
1614
1615
1615
/// This represents all the reading that a pattern match may do
1616
- /// (e.g. inspecting constants and discriminant values).
1617
- ReadForMatch ( Place < ' tcx > ) ,
1616
+ /// (e.g. inspecting constants and discriminant values), and the
1617
+ /// kind of pattern it comes from. This is in order to adapt potential
1618
+ /// error messages to these specific patterns.
1619
+ FakeRead ( FakeReadCause , Place < ' tcx > ) ,
1618
1620
1619
1621
/// Write the discriminant for a variant to the enum Place.
1620
1622
SetDiscriminant {
@@ -1662,6 +1664,31 @@ pub enum StatementKind<'tcx> {
1662
1664
Nop ,
1663
1665
}
1664
1666
1667
+ /// The `FakeReadCause` describes the type of pattern why a `FakeRead` statement exists.
1668
+ #[ derive( Copy , Clone , RustcEncodable , RustcDecodable , Debug ) ]
1669
+ pub enum FakeReadCause {
1670
+ /// Inject a fake read of the borrowed input at the start of each arm's
1671
+ /// pattern testing code.
1672
+ ///
1673
+ /// This should ensure that you cannot change the variant for an enum
1674
+ /// while you are in the midst of matching on it.
1675
+ ForMatch ,
1676
+
1677
+ /// Officially, the semantics of
1678
+ ///
1679
+ /// `let pattern = <expr>;`
1680
+ ///
1681
+ /// is that `<expr>` is evaluated into a temporary and then this temporary is
1682
+ /// into the pattern.
1683
+ ///
1684
+ /// However, if we see the simple pattern `let var = <expr>`, we optimize this to
1685
+ /// evaluate `<expr>` directly into the variable `var`. This is mostly unobservable,
1686
+ /// but in some cases it can affect the borrow checker, as in #53695.
1687
+ /// Therefore, we insert a "fake read" here to ensure that we get
1688
+ /// appropriate errors.
1689
+ ForLet ,
1690
+ }
1691
+
1665
1692
/// The `ValidationOp` describes what happens with each of the operands of a
1666
1693
/// `Validate` statement.
1667
1694
#[ derive( Copy , Clone , RustcEncodable , RustcDecodable , PartialEq , Eq ) ]
@@ -1718,7 +1745,7 @@ impl<'tcx> Debug for Statement<'tcx> {
1718
1745
use self :: StatementKind :: * ;
1719
1746
match self . kind {
1720
1747
Assign ( ref place, ref rv) => write ! ( fmt, "{:?} = {:?}" , place, rv) ,
1721
- ReadForMatch ( ref place) => write ! ( fmt, "ReadForMatch ({:?})" , place) ,
1748
+ FakeRead ( ref cause , ref place) => write ! ( fmt, "FakeRead ({:?}, {:?})" , cause , place) ,
1722
1749
// (reuse lifetime rendering policy from ppaux.)
1723
1750
EndRegion ( ref ce) => write ! ( fmt, "EndRegion({})" , ty:: ReScope ( * ce) ) ,
1724
1751
Validate ( ref op, ref places) => write ! ( fmt, "Validate({:?}, {:?})" , op, places) ,
@@ -2585,6 +2612,7 @@ CloneTypeFoldableAndLiftImpls! {
2585
2612
Mutability ,
2586
2613
SourceInfo ,
2587
2614
UpvarDecl ,
2615
+ FakeReadCause ,
2588
2616
ValidationOp ,
2589
2617
SourceScope ,
2590
2618
SourceScopeData ,
@@ -2651,7 +2679,7 @@ BraceStructTypeFoldableImpl! {
2651
2679
EnumTypeFoldableImpl ! {
2652
2680
impl <' tcx> TypeFoldable <' tcx> for StatementKind <' tcx> {
2653
2681
( StatementKind :: Assign ) ( a, b) ,
2654
- ( StatementKind :: ReadForMatch ) ( place) ,
2682
+ ( StatementKind :: FakeRead ) ( cause , place) ,
2655
2683
( StatementKind :: SetDiscriminant ) { place, variant_index } ,
2656
2684
( StatementKind :: StorageLive ) ( a) ,
2657
2685
( StatementKind :: StorageDead ) ( a) ,
0 commit comments