@@ -646,8 +646,10 @@ impl Pat {
646646 PatKind :: MacCall ( mac) => TyKind :: MacCall ( mac. clone ( ) ) ,
647647 // `&mut? P` can be reinterpreted as `&mut? T` where `T` is `P` reparsed as a type.
648648 PatKind :: Ref ( pat, pinned, mutbl) => pat. to_ty ( ) . map ( |ty| match pinned {
649- Pinnedness :: Not => TyKind :: Ref ( None , MutTy { ty, mutbl : * mutbl } ) ,
650- Pinnedness :: Pinned => TyKind :: PinnedRef ( None , MutTy { ty, mutbl : * mutbl } ) ,
649+ Pinnedness :: Not => TyKind :: Ref ( None , MutTy { ty, mutbl : * mutbl } , ViewKind :: Full ) ,
650+ Pinnedness :: Pinned => {
651+ TyKind :: PinnedRef ( None , MutTy { ty, mutbl : * mutbl } , ViewKind :: Full )
652+ }
651653 } ) ?,
652654 // A slice/array pattern `[P]` can be reparsed as `[T]`, an unsized array,
653655 // when `P` can be reparsed as a type `T`.
@@ -1510,9 +1512,9 @@ impl Expr {
15101512
15111513 ExprKind :: Paren ( expr) => expr. to_ty ( ) . map ( TyKind :: Paren ) ?,
15121514
1513- ExprKind :: AddrOf ( BorrowKind :: Ref , mutbl, expr) => {
1514- expr . to_ty ( ) . map ( |ty| TyKind :: Ref ( None , MutTy { ty , mutbl : * mutbl } ) ) ?
1515- }
1515+ ExprKind :: AddrOf ( BorrowKind :: Ref , mutbl, expr) => expr
1516+ . to_ty ( )
1517+ . map ( |ty| TyKind :: Ref ( None , MutTy { ty , mutbl : * mutbl } , ViewKind :: Full ) ) ? ,
15161518
15171519 ExprKind :: Repeat ( expr, expr_len) => {
15181520 expr. to_ty ( ) . map ( |ty| TyKind :: Array ( ty, expr_len. clone ( ) ) ) ?
@@ -2473,7 +2475,8 @@ impl From<Box<Ty>> for Ty {
24732475impl Ty {
24742476 pub fn peel_refs ( & self ) -> & Self {
24752477 let mut final_ty = self ;
2476- while let TyKind :: Ref ( _, MutTy { ty, .. } ) | TyKind :: Ptr ( MutTy { ty, .. } ) = & final_ty. kind
2478+ while let TyKind :: Ref ( _, MutTy { ty, .. } , _) | TyKind :: Ptr ( MutTy { ty, .. } ) =
2479+ & final_ty. kind
24772480 {
24782481 final_ty = ty;
24792482 }
@@ -2518,11 +2521,11 @@ pub enum TyKind {
25182521 /// A raw pointer (`*const T` or `*mut T`).
25192522 Ptr ( MutTy ) ,
25202523 /// A reference (`&'a T` or `&'a mut T`).
2521- Ref ( #[ visitable( extra = LifetimeCtxt :: Ref ) ] Option < Lifetime > , MutTy ) ,
2524+ Ref ( #[ visitable( extra = LifetimeCtxt :: Ref ) ] Option < Lifetime > , MutTy , ViewKind ) ,
25222525 /// A pinned reference (`&'a pin const T` or `&'a pin mut T`).
25232526 ///
25242527 /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`.
2525- PinnedRef ( #[ visitable( extra = LifetimeCtxt :: Ref ) ] Option < Lifetime > , MutTy ) ,
2528+ PinnedRef ( #[ visitable( extra = LifetimeCtxt :: Ref ) ] Option < Lifetime > , MutTy , ViewKind ) ,
25262529 /// A function pointer type (e.g., `fn(usize) -> bool`).
25272530 FnPtr ( Box < FnPtrTy > ) ,
25282531 /// An unsafe existential lifetime binder (e.g., `unsafe<'a> &'a ()`).
@@ -2660,6 +2663,19 @@ pub enum TraitObjectSyntax {
26602663 None = 1 ,
26612664}
26622665
2666+ /// Represents how a reference is viewed.
2667+ #[ derive( Clone , Encodable , Decodable , Debug , Walkable ) ]
2668+ pub enum ViewKind {
2669+ /// `&mut T`. All the fields can be observed.
2670+ Full ,
2671+ /// `&mut T.{ foo, bar }`. Only `foo` and `bar` can be observed.
2672+ Partial {
2673+ span : Span ,
2674+ #[ visitable( ignore) ]
2675+ fields : ThinVec < Ident > ,
2676+ } ,
2677+ }
2678+
26632679/// SAFETY: `TraitObjectSyntax` only has 3 data-less variants which means
26642680/// it can be represented with a `u2`. We use `repr(u8)` to guarantee the
26652681/// discriminants of the variants are no greater than `3`.
@@ -2933,21 +2949,21 @@ pub struct Param {
29332949pub enum SelfKind {
29342950 /// `self`, `mut self`
29352951 Value ( Mutability ) ,
2936- /// `&'lt self`, `&'lt mut self`
2937- Region ( Option < Lifetime > , Mutability ) ,
2938- /// `&'lt pin const self`, `&'lt pin mut self`
2939- Pinned ( Option < Lifetime > , Mutability ) ,
2952+ /// `&'lt self`, `&'lt mut self`, `&'lt mut self.{ a, b }`
2953+ Region ( Option < Lifetime > , Mutability , ViewKind ) ,
2954+ /// `&'lt pin const self`, `&'lt pin mut self`, `&'lt pin mut self.{ a, b }`.
2955+ Pinned ( Option < Lifetime > , Mutability , ViewKind ) ,
29402956 /// `self: TYPE`, `mut self: TYPE`
29412957 Explicit ( Box < Ty > , Mutability ) ,
29422958}
29432959
29442960impl SelfKind {
29452961 pub fn to_ref_suggestion ( & self ) -> String {
29462962 match self {
2947- SelfKind :: Region ( None , mutbl) => mutbl. ref_prefix_str ( ) . to_string ( ) ,
2948- SelfKind :: Region ( Some ( lt) , mutbl) => format ! ( "&{lt} {}" , mutbl. prefix_str( ) ) ,
2949- SelfKind :: Pinned ( None , mutbl) => format ! ( "&pin {}" , mutbl. ptr_str( ) ) ,
2950- SelfKind :: Pinned ( Some ( lt) , mutbl) => format ! ( "&{lt} pin {}" , mutbl. ptr_str( ) ) ,
2963+ SelfKind :: Region ( None , mutbl, _ ) => mutbl. ref_prefix_str ( ) . to_string ( ) ,
2964+ SelfKind :: Region ( Some ( lt) , mutbl, _ ) => format ! ( "&{lt} {}" , mutbl. prefix_str( ) ) ,
2965+ SelfKind :: Pinned ( None , mutbl, _ ) => format ! ( "&pin {}" , mutbl. ptr_str( ) ) ,
2966+ SelfKind :: Pinned ( Some ( lt) , mutbl, _ ) => format ! ( "&{lt} pin {}" , mutbl. ptr_str( ) ) ,
29512967 SelfKind :: Value ( _) | SelfKind :: Explicit ( _, _) => {
29522968 unreachable ! ( "if we had an explicit self, we wouldn't be here" )
29532969 }
@@ -2964,13 +2980,18 @@ impl Param {
29642980 if ident. name == kw:: SelfLower {
29652981 return match self . ty . kind {
29662982 TyKind :: ImplicitSelf => Some ( respan ( self . pat . span , SelfKind :: Value ( mutbl) ) ) ,
2967- TyKind :: Ref ( lt, MutTy { ref ty, mutbl } ) if ty. kind . is_implicit_self ( ) => {
2968- Some ( respan ( self . pat . span , SelfKind :: Region ( lt, mutbl) ) )
2983+ TyKind :: Ref ( lt, MutTy { ref ty, mutbl } , ref view_fields)
2984+ if ty. kind . is_implicit_self ( ) =>
2985+ {
2986+ Some ( respan (
2987+ self . pat . span ,
2988+ SelfKind :: Region ( lt, mutbl, view_fields. clone ( ) ) ,
2989+ ) )
29692990 }
2970- TyKind :: PinnedRef ( lt, MutTy { ref ty, mutbl } )
2991+ TyKind :: PinnedRef ( lt, MutTy { ref ty, mutbl } , ref view )
29712992 if ty. kind . is_implicit_self ( ) =>
29722993 {
2973- Some ( respan ( self . pat . span , SelfKind :: Pinned ( lt, mutbl) ) )
2994+ Some ( respan ( self . pat . span , SelfKind :: Pinned ( lt, mutbl, view . clone ( ) ) ) )
29742995 }
29752996 _ => Some ( respan (
29762997 self . pat . span . to ( self . ty . span ) ,
@@ -3003,20 +3024,20 @@ impl Param {
30033024 let ( mutbl, ty) = match eself. node {
30043025 SelfKind :: Explicit ( ty, mutbl) => ( mutbl, ty) ,
30053026 SelfKind :: Value ( mutbl) => ( mutbl, infer_ty) ,
3006- SelfKind :: Region ( lt, mutbl) => (
3027+ SelfKind :: Region ( lt, mutbl, views ) => (
30073028 Mutability :: Not ,
30083029 Box :: new ( Ty {
30093030 id : DUMMY_NODE_ID ,
3010- kind : TyKind :: Ref ( lt, MutTy { ty : infer_ty, mutbl } ) ,
3031+ kind : TyKind :: Ref ( lt, MutTy { ty : infer_ty, mutbl } , views ) ,
30113032 span,
30123033 tokens : None ,
30133034 } ) ,
30143035 ) ,
3015- SelfKind :: Pinned ( lt, mutbl) => (
3036+ SelfKind :: Pinned ( lt, mutbl, view ) => (
30163037 mutbl,
30173038 Box :: new ( Ty {
30183039 id : DUMMY_NODE_ID ,
3019- kind : TyKind :: PinnedRef ( lt, MutTy { ty : infer_ty, mutbl } ) ,
3040+ kind : TyKind :: PinnedRef ( lt, MutTy { ty : infer_ty, mutbl } , view ) ,
30203041 span,
30213042 tokens : None ,
30223043 } ) ,
@@ -4340,7 +4361,7 @@ mod size_asserts {
43404361 static_assert_size ! ( Stmt , 32 ) ;
43414362 static_assert_size ! ( StmtKind , 16 ) ;
43424363 static_assert_size ! ( TraitImplHeader , 72 ) ;
4343- static_assert_size ! ( Ty , 64 ) ;
4344- static_assert_size ! ( TyKind , 40 ) ;
4364+ static_assert_size ! ( Ty , 80 ) ;
4365+ static_assert_size ! ( TyKind , 56 ) ;
43454366 // tidy-alphabetical-end
43464367}
0 commit comments