@@ -88,26 +88,31 @@ impl<'tcx> PlaceTy<'tcx> {
8888/// 
8989/// Note that the resulting type has not been normalized. 
9090#[ instrument( level = "debug" ,  skip( tcx) ,  ret) ]  
91-     pub  fn  field_ty ( self ,  tcx :  TyCtxt < ' tcx > ,  f :  FieldIdx )  -> Ty < ' tcx >  { 
92-         if  let  Some ( variant_index)  = self . variant_index  { 
93-             match  * self . ty . kind ( )  { 
91+     pub  fn  field_ty ( 
92+         tcx :  TyCtxt < ' tcx > , 
93+         self_ty :  Ty < ' tcx > , 
94+         variant_idx :  Option < VariantIdx > , 
95+         f :  FieldIdx , 
96+     )  -> Ty < ' tcx >  { 
97+         if  let  Some ( variant_index)  = variant_idx { 
98+             match  * self_ty. kind ( )  { 
9499                ty:: Adt ( adt_def,  args)  if  adt_def. is_enum ( )  => { 
95100                    adt_def. variant ( variant_index) . fields [ f] . ty ( tcx,  args) 
96101                } 
97102                ty:: Coroutine ( def_id,  args)  => { 
98103                    let  mut  variants = args. as_coroutine ( ) . state_tys ( def_id,  tcx) ; 
99104                    let  Some ( mut  variant)  = variants. nth ( variant_index. into ( ) )  else  { 
100-                         bug ! ( "variant {variant_index:?} of coroutine out of range: {self :?}" ) ; 
105+                         bug ! ( "variant {variant_index:?} of coroutine out of range: {self_ty :?}" ) ; 
101106                    } ; 
102107
103-                     variant
104-                         . nth ( f . index ( ) ) 
105-                          . unwrap_or_else ( ||  bug ! ( "field {f:?} out of range: {self:?}" ) ) 
108+                     variant. nth ( f . index ( ) ) . unwrap_or_else ( ||  { 
109+                         bug ! ( "field {f:?} out of range of variant: {self_ty:?} {variant_idx:?}" ) 
110+                     } ) 
106111                } 
107-                 _ => bug ! ( "can't downcast non-adt non-coroutine type: {self :?}" ) , 
112+                 _ => bug ! ( "can't downcast non-adt non-coroutine type: {self_ty :?}" ) , 
108113            } 
109114        }  else  { 
110-             match  self . ty . kind ( )  { 
115+             match  self_ty . kind ( )  { 
111116                ty:: Adt ( adt_def,  args)  if  !adt_def. is_enum ( )  => { 
112117                    adt_def. non_enum_variant ( ) . fields [ f] . ty ( tcx,  args) 
113118                } 
@@ -116,26 +121,25 @@ impl<'tcx> PlaceTy<'tcx> {
116121                    . upvar_tys ( ) 
117122                    . get ( f. index ( ) ) 
118123                    . copied ( ) 
119-                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self :?}" ) ) , 
124+                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self_ty :?}" ) ) , 
120125                ty:: CoroutineClosure ( _,  args)  => args
121126                    . as_coroutine_closure ( ) 
122127                    . upvar_tys ( ) 
123128                    . get ( f. index ( ) ) 
124129                    . copied ( ) 
125-                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self :?}" ) ) , 
130+                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self_ty :?}" ) ) , 
126131                // Only prefix fields (upvars and current state) are 
127132                // accessible without a variant index. 
128-                 ty:: Coroutine ( _,  args)  => args
129-                     . as_coroutine ( ) 
130-                     . prefix_tys ( ) 
131-                     . get ( f. index ( ) ) 
132-                     . copied ( ) 
133-                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self:?}" ) ) , 
133+                 ty:: Coroutine ( _,  args)  => { 
134+                     args. as_coroutine ( ) . prefix_tys ( ) . get ( f. index ( ) ) . copied ( ) . unwrap_or_else ( || { 
135+                         bug ! ( "field {f:?} out of range of prefixes for {self_ty}" ) 
136+                     } ) 
137+                 } 
134138                ty:: Tuple ( tys)  => tys
135139                    . get ( f. index ( ) ) 
136140                    . copied ( ) 
137-                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self :?}" ) ) , 
138-                 _ => bug ! ( "can't project out of {self :?}" ) , 
141+                     . unwrap_or_else ( || bug ! ( "field {f:?} out of range: {self_ty :?}" ) ) , 
142+                 _ => bug ! ( "can't project out of {self_ty :?}" ) , 
139143            } 
140144        } 
141145    } 
@@ -148,11 +152,11 @@ impl<'tcx> PlaceTy<'tcx> {
148152        elems. iter ( ) . fold ( self ,  |place_ty,  & elem| place_ty. projection_ty ( tcx,  elem) ) 
149153    } 
150154
151-     /// Convenience wrapper around `projection_ty_core` for 
152- /// `PlaceElem`,  where we can just use the `Ty` that is already 
153- /// stored inline on  field projection elems. 
155+     /// Convenience wrapper around `projection_ty_core` for `PlaceElem`,  
156+ /// where we can just use the `Ty` that is already stored inline on  
157+ /// field projection elems. 
154158pub  fn  projection_ty ( self ,  tcx :  TyCtxt < ' tcx > ,  elem :  PlaceElem < ' tcx > )  -> PlaceTy < ' tcx >  { 
155-         self . projection_ty_core ( tcx,  & elem,  |_,  _,  ty| ty,  |_ ,   ty| ty) 
159+         self . projection_ty_core ( tcx,  & elem,  |ty| ty ,  | _,  _,  _ ,   ty| ty,  |ty| ty) 
156160    } 
157161
158162    /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` 
@@ -164,8 +168,9 @@ impl<'tcx> PlaceTy<'tcx> {
164168        self , 
165169        tcx :  TyCtxt < ' tcx > , 
166170        elem :  & ProjectionElem < V ,  T > , 
167-         mut  handle_field :  impl  FnMut ( & Self ,  FieldIdx ,  T )  -> Ty < ' tcx > , 
168-         mut  handle_opaque_cast_and_subtype :  impl  FnMut ( & Self ,  T )  -> Ty < ' tcx > , 
171+         mut  structurally_normalize :  impl  FnMut ( Ty < ' tcx > )  -> Ty < ' tcx > , 
172+         mut  handle_field :  impl  FnMut ( Ty < ' tcx > ,  Option < VariantIdx > ,  FieldIdx ,  T )  -> Ty < ' tcx > , 
173+         mut  handle_opaque_cast_and_subtype :  impl  FnMut ( T )  -> Ty < ' tcx > , 
169174    )  -> PlaceTy < ' tcx > 
170175    where 
171176        V :  :: std:: fmt:: Debug , 
@@ -176,16 +181,16 @@ impl<'tcx> PlaceTy<'tcx> {
176181        } 
177182        let  answer = match  * elem { 
178183            ProjectionElem :: Deref  => { 
179-                 let  ty = self . ty . builtin_deref ( true ) . unwrap_or_else ( || { 
184+                 let  ty = structurally_normalize ( self . ty ) . builtin_deref ( true ) . unwrap_or_else ( || { 
180185                    bug ! ( "deref projection of non-dereferenceable ty {:?}" ,  self ) 
181186                } ) ; 
182187                PlaceTy :: from_ty ( ty) 
183188            } 
184189            ProjectionElem :: Index ( _)  | ProjectionElem :: ConstantIndex  {  .. }  => { 
185-                 PlaceTy :: from_ty ( self . ty . builtin_index ( ) . unwrap ( ) ) 
190+                 PlaceTy :: from_ty ( structurally_normalize ( self . ty ) . builtin_index ( ) . unwrap ( ) ) 
186191            } 
187192            ProjectionElem :: Subslice  {  from,  to,  from_end }  => { 
188-                 PlaceTy :: from_ty ( match  self . ty . kind ( )  { 
193+                 PlaceTy :: from_ty ( match  structurally_normalize ( self . ty ) . kind ( )  { 
189194                    ty:: Slice ( ..)  => self . ty , 
190195                    ty:: Array ( inner,  _)  if  !from_end => Ty :: new_array ( tcx,  * inner,  to - from) , 
191196                    ty:: Array ( inner,  size)  if  from_end => { 
@@ -201,17 +206,18 @@ impl<'tcx> PlaceTy<'tcx> {
201206            ProjectionElem :: Downcast ( _name,  index)  => { 
202207                PlaceTy  {  ty :  self . ty ,  variant_index :  Some ( index)  } 
203208            } 
204-             ProjectionElem :: Field ( f,  fty)  => PlaceTy :: from_ty ( handle_field ( & self ,  f,  fty) ) , 
205-             ProjectionElem :: OpaqueCast ( ty)  => { 
206-                 PlaceTy :: from_ty ( handle_opaque_cast_and_subtype ( & self ,  ty) ) 
207-             } 
208-             ProjectionElem :: Subtype ( ty)  => { 
209-                 PlaceTy :: from_ty ( handle_opaque_cast_and_subtype ( & self ,  ty) ) 
210-             } 
209+             ProjectionElem :: Field ( f,  fty)  => PlaceTy :: from_ty ( handle_field ( 
210+                 structurally_normalize ( self . ty ) , 
211+                 self . variant_index , 
212+                 f, 
213+                 fty, 
214+             ) ) , 
215+             ProjectionElem :: OpaqueCast ( ty)  => PlaceTy :: from_ty ( handle_opaque_cast_and_subtype ( ty) ) , 
216+             ProjectionElem :: Subtype ( ty)  => PlaceTy :: from_ty ( handle_opaque_cast_and_subtype ( ty) ) , 
211217
212218            // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general. 
213219            ProjectionElem :: UnwrapUnsafeBinder ( ty)  => { 
214-                 PlaceTy :: from_ty ( handle_opaque_cast_and_subtype ( & self ,   ty) ) 
220+                 PlaceTy :: from_ty ( handle_opaque_cast_and_subtype ( ty) ) 
215221            } 
216222        } ; 
217223        debug ! ( "projection_ty self: {:?} elem: {:?} yields: {:?}" ,  self ,  elem,  answer) ; 
0 commit comments