@@ -21,7 +21,8 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
2121use syntax:: source_map:: Spanned ;
2222use syntax:: ast:: { self , CrateSugar , Ident , Name , NodeId , AsmDialect } ;
2323use 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 } ;
2526use syntax:: attr:: { InlineAttr , OptimizeAttr } ;
2627use syntax:: symbol:: { Symbol , kw} ;
2728use syntax:: tokenstream:: TokenStream ;
@@ -1493,8 +1494,20 @@ impl Expr {
14931494 }
14941495 }
14951496
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 {
14981511 ExprKind :: Path ( QPath :: Resolved ( _, ref path) ) => {
14991512 match path. res {
15001513 Res :: Local ( ..)
@@ -1504,14 +1517,19 @@ impl Expr {
15041517 }
15051518 }
15061519
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
15071523 ExprKind :: Type ( ref e, _) => {
1508- e. is_place_expr ( )
1524+ e. is_place_expr ( allow_projections_from )
15091525 }
15101526
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)
15151533 }
15161534
15171535 // Partially qualified paths in expressions can only legally
@@ -1646,8 +1664,8 @@ pub enum ExprKind {
16461664 /// Path to a definition, possibly containing lifetime or type parameters.
16471665 Path ( QPath ) ,
16481666
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 > ) ,
16511669 /// A `break`, with an optional label to break.
16521670 Break ( Destination , Option < P < Expr > > ) ,
16531671 /// A `continue`, with an optional label.
0 commit comments