@@ -21,7 +21,8 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
21
21
use syntax:: source_map:: Spanned ;
22
22
use syntax:: ast:: { self , CrateSugar , Ident , Name , NodeId , AsmDialect } ;
23
23
use syntax:: ast:: { Attribute , Label , LitKind , StrStyle , FloatTy , IntTy , UintTy } ;
24
- pub use syntax:: ast:: { Mutability , Constness , Unsafety , Movability , CaptureBy , IsAuto , ImplPolarity } ;
24
+ pub use syntax:: ast:: { Mutability , Constness , Unsafety , Movability , CaptureBy } ;
25
+ pub use syntax:: ast:: { IsAuto , ImplPolarity , BorrowKind } ;
25
26
use syntax:: attr:: { InlineAttr , OptimizeAttr } ;
26
27
use syntax:: symbol:: { Symbol , kw} ;
27
28
use syntax:: tokenstream:: TokenStream ;
@@ -1493,8 +1494,20 @@ impl Expr {
1493
1494
}
1494
1495
}
1495
1496
1496
- pub fn is_place_expr ( & self ) -> bool {
1497
- match self . kind {
1497
+ // Whether this looks like a place expr, without checking for deref
1498
+ // adjustments.
1499
+ // This will return `true` in some potentially surprising cases such as
1500
+ // `CONSTANT.field`.
1501
+ pub fn is_syntactic_place_expr ( & self ) -> bool {
1502
+ self . is_place_expr ( |_| true )
1503
+ }
1504
+
1505
+ // Whether this is a place expression.
1506
+ // `allow_projections_from` should return `true` if indexing a field or
1507
+ // index expression based on the given expression should be considered a
1508
+ // place expression.
1509
+ pub fn is_place_expr ( & self , mut allow_projections_from : impl FnMut ( & Self ) -> bool ) -> bool {
1510
+ match self . kind {
1498
1511
ExprKind :: Path ( QPath :: Resolved ( _, ref path) ) => {
1499
1512
match path. res {
1500
1513
Res :: Local ( ..)
@@ -1504,14 +1517,19 @@ impl Expr {
1504
1517
}
1505
1518
}
1506
1519
1520
+ // Type ascription inherits its place expression kind from its
1521
+ // operand. See:
1522
+ // https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md#type-ascription-and-temporaries
1507
1523
ExprKind :: Type ( ref e, _) => {
1508
- e. is_place_expr ( )
1524
+ e. is_place_expr ( allow_projections_from )
1509
1525
}
1510
1526
1511
- ExprKind :: Unary ( UnDeref , _) |
1512
- ExprKind :: Field ( ..) |
1513
- ExprKind :: Index ( ..) => {
1514
- true
1527
+ ExprKind :: Unary ( UnDeref , _) => true ,
1528
+
1529
+ ExprKind :: Field ( ref base, _) |
1530
+ ExprKind :: Index ( ref base, _) => {
1531
+ allow_projections_from ( base)
1532
+ || base. is_place_expr ( allow_projections_from)
1515
1533
}
1516
1534
1517
1535
// Partially qualified paths in expressions can only legally
@@ -1646,8 +1664,8 @@ pub enum ExprKind {
1646
1664
/// Path to a definition, possibly containing lifetime or type parameters.
1647
1665
Path ( QPath ) ,
1648
1666
1649
- /// A referencing operation (i.e., `&a` or `&mut a`).
1650
- AddrOf ( Mutability , P < Expr > ) ,
1667
+ /// A referencing operation (i.e., `&a`, `&mut a`, `&raw const a`, or `&raw mut a`).
1668
+ AddrOf ( BorrowKind , Mutability , P < Expr > ) ,
1651
1669
/// A `break`, with an optional label to break.
1652
1670
Break ( Destination , Option < P < Expr > > ) ,
1653
1671
/// A `continue`, with an optional label.
0 commit comments