@@ -451,11 +451,32 @@ impl From<Mutability> for hir::Mutability {
451
451
}
452
452
}
453
453
454
- #[ derive( Copy , Clone , Debug , PartialEq , Eq , RustcEncodable , RustcDecodable ) ]
454
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord , RustcEncodable , RustcDecodable ) ]
455
455
pub enum BorrowKind {
456
456
/// Data must be immutable and is aliasable.
457
457
Shared ,
458
458
459
+ /// The immediately borrowed place must be immutable, but projections from
460
+ /// it don't need to be. For example, a shallow borrow of `a.b` doesn't
461
+ /// conflict with a mutable borrow of `a.b.c`.
462
+ ///
463
+ /// This is used when lowering matches: when matching on a place we want to
464
+ /// ensure that place have the same value from the start of the match until
465
+ /// an arm is selected. This prevents this code from compiling:
466
+ ///
467
+ /// let mut x = &Some(0);
468
+ /// match *x {
469
+ /// None => (),
470
+ /// Some(_) if { x = &None; false } => (),
471
+ /// Some(_) => (),
472
+ /// }
473
+ ///
474
+ /// This can't be a shared borrow because mutably borrowing (*x as Some).0
475
+ /// should not prevent `if let None = x { ... }`, for example, becase the
476
+ /// mutating `(*x as Some).0` can't affect the discriminant of `x`.
477
+ /// We can also report errors with this kind of borrow differently.
478
+ Shallow ,
479
+
459
480
/// Data must be immutable but not aliasable. This kind of borrow
460
481
/// cannot currently be expressed by the user and is used only in
461
482
/// implicit closure bindings. It is needed when the closure is
@@ -504,7 +525,7 @@ pub enum BorrowKind {
504
525
impl BorrowKind {
505
526
pub fn allows_two_phase_borrow ( & self ) -> bool {
506
527
match * self {
507
- BorrowKind :: Shared | BorrowKind :: Unique => false ,
528
+ BorrowKind :: Shared | BorrowKind :: Shallow | BorrowKind :: Unique => false ,
508
529
BorrowKind :: Mut {
509
530
allow_two_phase_borrow,
510
531
} => allow_two_phase_borrow,
@@ -1672,7 +1693,11 @@ pub enum FakeReadCause {
1672
1693
///
1673
1694
/// This should ensure that you cannot change the variant for an enum
1674
1695
/// while you are in the midst of matching on it.
1675
- ForMatch ,
1696
+ ForMatchGuard ,
1697
+
1698
+ /// `let x: !; match x {}` doesn't generate any read of x so we need to
1699
+ /// generate a read of x to check that it is initialized and safe.
1700
+ ForMatchedPlace ,
1676
1701
1677
1702
/// Officially, the semantics of
1678
1703
///
@@ -1773,7 +1798,7 @@ impl<'tcx> Debug for Statement<'tcx> {
1773
1798
1774
1799
/// A path to a value; something that can be evaluated without
1775
1800
/// changing or disturbing program state.
1776
- #[ derive( Clone , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1801
+ #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
1777
1802
pub enum Place < ' tcx > {
1778
1803
/// local variable
1779
1804
Local ( Local ) ,
@@ -1790,7 +1815,7 @@ pub enum Place<'tcx> {
1790
1815
1791
1816
/// The def-id of a static, along with its normalized type (which is
1792
1817
/// stored to avoid requiring normalization when reading MIR).
1793
- #[ derive( Clone , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1818
+ #[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
1794
1819
pub struct Static < ' tcx > {
1795
1820
pub def_id : DefId ,
1796
1821
pub ty : Ty < ' tcx > ,
@@ -1805,13 +1830,13 @@ impl_stable_hash_for!(struct Static<'tcx> {
1805
1830
/// or `*B` or `B[index]`. Note that it is parameterized because it is
1806
1831
/// shared between `Constant` and `Place`. See the aliases
1807
1832
/// `PlaceProjection` etc below.
1808
- #[ derive( Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1833
+ #[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
1809
1834
pub struct Projection < ' tcx , B , V , T > {
1810
1835
pub base : B ,
1811
1836
pub elem : ProjectionElem < ' tcx , V , T > ,
1812
1837
}
1813
1838
1814
- #[ derive( Clone , Debug , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
1839
+ #[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash , RustcEncodable , RustcDecodable ) ]
1815
1840
pub enum ProjectionElem < ' tcx , V , T > {
1816
1841
Deref ,
1817
1842
Field ( Field , T ) ,
@@ -2198,6 +2223,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
2198
2223
Ref ( region, borrow_kind, ref place) => {
2199
2224
let kind_str = match borrow_kind {
2200
2225
BorrowKind :: Shared => "" ,
2226
+ BorrowKind :: Shallow => "shallow " ,
2201
2227
BorrowKind :: Mut { .. } | BorrowKind :: Unique => "mut " ,
2202
2228
} ;
2203
2229
0 commit comments