@@ -7,6 +7,7 @@ use rustc_hir::def_id::LocalDefId;
7
7
use rustc_middle:: hir:: place:: Projection as HirProjection ;
8
8
use rustc_middle:: hir:: place:: ProjectionKind as HirProjectionKind ;
9
9
use rustc_middle:: middle:: region;
10
+ use rustc_middle:: mir:: tcx:: PlaceTy ;
10
11
use rustc_middle:: mir:: AssertKind :: BoundsCheck ;
11
12
use rustc_middle:: mir:: * ;
12
13
use rustc_middle:: thir:: * ;
@@ -324,56 +325,35 @@ impl<'tcx> PlaceBuilder<'tcx> {
324
325
}
325
326
}
326
327
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 > >
328
333
where
329
334
D : HasLocalDecls < ' tcx > ,
330
335
{
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
-
360
336
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 ) ) ,
365
338
PlaceBase :: Upvar { .. } => {
366
339
match to_upvars_resolved_place_builder ( self . clone ( ) , cx) {
367
340
Ok ( resolved_place_builder) => {
368
341
// `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)
370
343
}
371
344
Err ( place_builder) => {
372
345
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) ;
376
354
355
+ Some ( place_ty)
356
+ }
377
357
_ => None , // would need a base `Ty` for these
378
358
}
379
359
}
0 commit comments