@@ -7,6 +7,7 @@ use rustc_hir::def_id::LocalDefId;
77use rustc_middle:: hir:: place:: Projection as HirProjection ;
88use rustc_middle:: hir:: place:: ProjectionKind as HirProjectionKind ;
99use rustc_middle:: middle:: region;
10+ use rustc_middle:: mir:: tcx:: PlaceTy ;
1011use rustc_middle:: mir:: AssertKind :: BoundsCheck ;
1112use rustc_middle:: mir:: * ;
1213use rustc_middle:: thir:: * ;
@@ -324,56 +325,35 @@ impl<'tcx> PlaceBuilder<'tcx> {
324325 }
325326 }
326327
327- pub fn try_ty < D > ( & self , local_decls : & D , cx : & Builder < ' _ , ' tcx > ) -> Option < Ty < ' tcx > >
328+ pub fn try_compute_ty < D > (
329+ & self ,
330+ local_decls : & D ,
331+ cx : & Builder < ' _ , ' tcx > ,
332+ ) -> Option < PlaceTy < ' tcx > >
328333 where
329334 D : HasLocalDecls < ' tcx > ,
330335 {
331- let tcx = cx. tcx ;
332-
333- let project_ty = |ty : Ty < ' tcx > , elem : & PlaceElem < ' tcx > | -> Ty < ' tcx > {
334- match elem {
335- ProjectionElem :: Deref => {
336- ty. builtin_deref ( true )
337- . unwrap_or_else ( || {
338- bug ! ( "deref projection of non-dereferenceable ty {:?}" , ty)
339- } )
340- . ty
341- }
342- ProjectionElem :: Index ( _) | ProjectionElem :: ConstantIndex { .. } => {
343- ty. builtin_index ( ) . unwrap ( )
344- }
345- ProjectionElem :: Subslice { from, to, from_end } => match ty. kind ( ) {
346- ty:: Slice ( ..) => ty,
347- ty:: Array ( inner, _) if !from_end => tcx. mk_array ( * inner, ( to - from) as u64 ) ,
348- ty:: Array ( inner, size) if * from_end => {
349- let size = size. eval_usize ( tcx, ty:: ParamEnv :: empty ( ) ) ;
350- let len = size - ( * from as u64 ) - ( * to as u64 ) ;
351- tcx. mk_array ( * inner, len)
352- }
353- _ => bug ! ( "cannot subslice non-array type: `{:?}`" , ty) ,
354- } ,
355- ProjectionElem :: Downcast ( ..) => ty,
356- ProjectionElem :: Field ( _, ty) | ProjectionElem :: OpaqueCast ( ty) => * ty,
357- }
358- } ;
359-
360336 match self . base {
361- PlaceBase :: Local ( local) => {
362- let base_ty = local_decls. local_decls ( ) [ local] . ty ;
363- Some ( self . projection . iter ( ) . fold ( base_ty, |ty, & elem| project_ty ( ty, & elem) ) )
364- }
337+ PlaceBase :: Local ( _) => Some ( self . clone ( ) . into_place ( cx) . ty ( local_decls, cx. tcx ) ) ,
365338 PlaceBase :: Upvar { .. } => {
366339 match to_upvars_resolved_place_builder ( self . clone ( ) , cx) {
367340 Ok ( resolved_place_builder) => {
368341 // `base` is guaranteed to be `PlaceBase::Local` now, so recursive call is ok
369- resolved_place_builder. try_ty ( local_decls, cx)
342+ resolved_place_builder. try_compute_ty ( local_decls, cx)
370343 }
371344 Err ( place_builder) => {
372345 match & place_builder. projection [ ..] {
373- & [ ProjectionElem :: OpaqueCast ( base_ty) , ref projections @ ..] => Some (
374- projections. iter ( ) . fold ( base_ty, |ty, & elem| project_ty ( ty, & elem) ) ,
375- ) ,
346+ & [ ProjectionElem :: OpaqueCast ( base_ty) , ref projections @ ..] => {
347+ let place_ty = projections
348+ . iter ( )
349+ . fold ( PlaceTy :: from_ty ( base_ty) , |place_ty, & elem| {
350+ place_ty. projection_ty ( cx. tcx , elem)
351+ } ) ;
352+
353+ debug ! ( ?place_ty) ;
376354
355+ Some ( place_ty)
356+ }
377357 _ => None , // would need a base `Ty` for these
378358 }
379359 }
0 commit comments