@@ -19,6 +19,7 @@ use rustc_target::abi::VariantIdx;
19
19
use rustc_index:: vec:: Idx ;
20
20
21
21
use std:: assert_matches:: assert_matches;
22
+ use std:: convert:: From ;
22
23
use std:: iter;
23
24
24
25
/// `PlaceBuilder` is used to create places during MIR construction. It allows you to "build up" a
@@ -66,7 +67,7 @@ pub(in crate::build) enum PlaceBuilder<'tcx> {
66
67
///
67
68
/// Note: in contrast to `PlaceBuilder::Local` we have not yet determined all `Field` types
68
69
/// and will only do so once converting to `PlaceBuilder::Local`.
69
- UpVar ( UpVar , Vec < PlaceElem < ' tcx > > ) ,
70
+ UpVar ( UpVar , Vec < UpvarProjectionElem < ' tcx > > ) ,
70
71
}
71
72
72
73
#[ derive( Copy , Clone , Debug , PartialEq ) ]
@@ -82,7 +83,7 @@ pub(crate) struct UpVar {
82
83
/// part of a path that is captured by a closure. We stop applying projections once we see the first
83
84
/// projection that isn't captured by a closure.
84
85
fn convert_to_hir_projections_and_truncate_for_capture < ' tcx > (
85
- mir_projections : & [ PlaceElem < ' tcx > ] ,
86
+ mir_projections : & [ UpvarProjectionElem < ' tcx > ] ,
86
87
) -> Vec < HirProjectionKind > {
87
88
let mut hir_projections = Vec :: new ( ) ;
88
89
let mut variant = None ;
@@ -156,7 +157,7 @@ fn is_ancestor_or_same_capture(
156
157
fn find_capture_matching_projections < ' a , ' tcx > (
157
158
upvars : & ' a CaptureMap < ' tcx > ,
158
159
var_hir_id : LocalVarId ,
159
- projections : & [ PlaceElem < ' tcx > ] ,
160
+ projections : & [ UpvarProjectionElem < ' tcx > ] ,
160
161
) -> Option < ( usize , & ' a Capture < ' tcx > ) > {
161
162
let hir_projections = convert_to_hir_projections_and_truncate_for_capture ( projections) ;
162
163
@@ -212,8 +213,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
212
213
capture. captured_place . place . base_ty ,
213
214
projection,
214
215
& capture. captured_place . place . projections ,
215
- )
216
- . collect :: < Vec < _ > > ( ) ;
216
+ ) ;
217
217
218
218
let upvar_resolved_place_builder = PlaceBuilder :: construct_local_place_builder (
219
219
cx,
@@ -222,6 +222,37 @@ fn to_upvars_resolved_place_builder<'tcx>(
222
222
upvar_projection,
223
223
) ;
224
224
225
+ debug_assert ! ( {
226
+ let builder = upvar_resolved_place_builder. clone( ) ;
227
+ let mut valid_conversion = true ;
228
+ match builder {
229
+ PlaceBuilder :: Local ( _, projections) => {
230
+ for proj in projections. iter( ) {
231
+ match proj {
232
+ ProjectionElem :: Field ( _, field_ty) => {
233
+ if matches!( field_ty. kind( ) , ty:: Infer ( ..) ) {
234
+ debug!(
235
+ "field ty should have been converted for projection {:?} in PlaceBuilder {:?}" ,
236
+ proj,
237
+ upvar_resolved_place_builder. clone( )
238
+ ) ;
239
+
240
+ valid_conversion = false ;
241
+ break ;
242
+ }
243
+ }
244
+ _ => { }
245
+ }
246
+ }
247
+ }
248
+ PlaceBuilder :: UpVar ( ..) => {
249
+ unreachable!( )
250
+ }
251
+ }
252
+
253
+ valid_conversion
254
+ } ) ;
255
+
225
256
Some ( upvar_resolved_place_builder)
226
257
}
227
258
@@ -233,14 +264,14 @@ fn to_upvars_resolved_place_builder<'tcx>(
233
264
/// projection kinds are unsupported.
234
265
fn strip_prefix < ' a , ' tcx > (
235
266
mut base_ty : Ty < ' tcx > ,
236
- projections : & ' a [ PlaceElem < ' tcx > ] ,
267
+ projections : & ' a [ UpvarProjectionElem < ' tcx > ] ,
237
268
prefix_projections : & [ HirProjection < ' tcx > ] ,
238
- ) -> impl Iterator < Item = PlaceElem < ' tcx > > + ' a {
269
+ ) -> Vec < UpvarProjectionElem < ' tcx > > {
239
270
let mut iter = projections
240
271
. iter ( )
241
- . copied ( )
242
272
// Filter out opaque casts, they are unnecessary in the prefix.
243
- . filter ( |elem| !matches ! ( elem, ProjectionElem :: OpaqueCast ( ..) ) ) ;
273
+ . filter ( |elem| !matches ! ( elem, ProjectionElem :: OpaqueCast ( ..) ) )
274
+ . map ( |elem| * elem) ;
244
275
for projection in prefix_projections {
245
276
debug ! ( ?projection, ?projection. ty) ;
246
277
@@ -261,7 +292,8 @@ fn strip_prefix<'a, 'tcx>(
261
292
262
293
base_ty = projection. ty ;
263
294
}
264
- iter
295
+
296
+ iter. collect :: < Vec < _ > > ( )
265
297
}
266
298
267
299
impl < ' tcx > PlaceBuilder < ' tcx > {
@@ -292,11 +324,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
292
324
& self ,
293
325
cx : & Builder < ' _ , ' tcx > ,
294
326
) -> Option < PlaceBuilder < ' tcx > > {
295
- let PlaceBuilder :: Upvar ( Upvar { var_hir_id, closure_def_id } , projection) = self else {
327
+ let PlaceBuilder :: UpVar ( UpVar { var_hir_id, closure_def_id } , projection) = self else {
296
328
return None ;
297
329
} ;
298
330
299
- to_upvars_resolved_place_builder ( cx, var_hir_id, closure_def_id, & projection)
331
+ to_upvars_resolved_place_builder ( cx, * var_hir_id, * closure_def_id, & projection)
300
332
}
301
333
302
334
pub ( crate ) fn get_local_projection ( & self ) -> & [ PlaceElem < ' tcx > ] {
@@ -309,19 +341,16 @@ impl<'tcx> PlaceBuilder<'tcx> {
309
341
}
310
342
311
343
#[ instrument( skip( cx) , level = "debug" ) ]
312
- pub ( crate ) fn field (
313
- self ,
314
- cx : & Builder < ' _ , ' tcx > ,
315
- f : Field ,
316
- default_field_ty : Ty < ' tcx > ,
317
- ) -> Self {
344
+ pub ( crate ) fn field ( self , cx : & Builder < ' _ , ' tcx > , f : Field ) -> Self {
318
345
let field_ty = match self {
319
346
PlaceBuilder :: Local ( ..) => {
320
347
let base_place = self . clone ( ) ;
321
- PlaceBuilder :: try_compute_field_ty ( cx, f, base_place)
322
- . unwrap_or_else ( || default_field_ty)
348
+ PlaceBuilder :: compute_field_ty ( cx, f, base_place)
349
+ }
350
+ PlaceBuilder :: UpVar ( ..) => {
351
+ let dummy_ty = cx. tcx . mk_ty_infer ( ty:: FreshTy ( 0 ) ) ;
352
+ dummy_ty
323
353
}
324
- PlaceBuilder :: UpVar ( ..) => default_field_ty,
325
354
} ;
326
355
327
356
self . project ( ProjectionElem :: Field ( f, field_ty) )
@@ -347,7 +376,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
347
376
PlaceBuilder :: Local ( local, proj)
348
377
}
349
378
PlaceBuilder :: UpVar ( upvar, mut proj) => {
350
- proj. push ( elem) ;
379
+ proj. push ( elem. into ( ) ) ;
351
380
PlaceBuilder :: UpVar ( upvar, proj)
352
381
}
353
382
} ;
@@ -363,8 +392,8 @@ impl<'tcx> PlaceBuilder<'tcx> {
363
392
* local,
364
393
Vec :: from_iter ( proj. iter ( ) . copied ( ) . chain ( [ elem. into ( ) ] ) ) ,
365
394
) ,
366
- PlaceBuilder :: Upvar ( upvar, proj) => PlaceBuilder :: UpVar (
367
- upvar,
395
+ PlaceBuilder :: UpVar ( upvar, proj) => PlaceBuilder :: UpVar (
396
+ * upvar,
368
397
Vec :: from_iter ( proj. iter ( ) . copied ( ) . chain ( [ elem. into ( ) ] ) ) ,
369
398
) ,
370
399
}
@@ -378,11 +407,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
378
407
/// Fallible as the root of this place may be an upvar for
379
408
/// which no base type can be determined.
380
409
#[ instrument( skip( cx) , level = "debug" ) ]
381
- fn try_compute_field_ty (
410
+ fn compute_field_ty (
382
411
cx : & Builder < ' _ , ' tcx > ,
383
412
field : Field ,
384
413
base_place : PlaceBuilder < ' tcx > ,
385
- ) -> Option < Ty < ' tcx > > {
414
+ ) -> Ty < ' tcx > {
386
415
let field_idx = field. as_usize ( ) ;
387
416
let PlaceTy { ty, variant_index } = base_place. to_place ( cx) . ty ( & cx. local_decls , cx. tcx ) ;
388
417
let base_ty = cx. tcx . normalize_erasing_regions ( cx. param_env , ty) ;
@@ -442,7 +471,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
442
471
_ => bug ! ( "couldn't create field type, unexpected base type: {:?}" , base_ty) ,
443
472
} ;
444
473
445
- Some ( cx. tcx . normalize_erasing_regions ( cx. param_env , field_ty) )
474
+ cx. tcx . normalize_erasing_regions ( cx. param_env , field_ty)
446
475
}
447
476
448
477
/// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::UpVar` whose upvars
@@ -455,7 +484,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
455
484
cx : & Builder < ' _ , ' tcx > ,
456
485
local : Local ,
457
486
mut local_projection : Vec < PlaceElem < ' tcx > > ,
458
- upvar_projection : Vec < PlaceElem < ' tcx > > ,
487
+ upvar_projection : Vec < UpvarProjectionElem < ' tcx > > ,
459
488
) -> Self {
460
489
// We iterate through `upvar_projection` and whenever we find a `ProjectionElem::Field` we use
461
490
// the ancestor projections, i.e. those projection elements that come before the field projection,
@@ -464,11 +493,10 @@ impl<'tcx> PlaceBuilder<'tcx> {
464
493
for proj in upvar_projection. iter ( ) {
465
494
debug ! ( "proj: {:?}, local_projection: {:?}" , proj, local_projection) ;
466
495
match * proj {
467
- ProjectionElem :: Field ( field, default_field_ty ) => {
496
+ ProjectionElem :: Field ( field, _ ) => {
468
497
let ancestor_proj = local_projection. to_vec ( ) ;
469
498
let base_place = PlaceBuilder :: Local ( local, ancestor_proj) ;
470
- let field_ty = PlaceBuilder :: try_compute_field_ty ( cx, field, base_place)
471
- . unwrap_or_else ( || default_field_ty) ;
499
+ let field_ty = PlaceBuilder :: compute_field_ty ( cx, field, base_place) ;
472
500
debug ! ( ?field_ty) ;
473
501
474
502
local_projection. push ( ProjectionElem :: Field ( field, field_ty) ) ;
@@ -593,7 +621,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
593
621
place_builder = place_builder. downcast ( * adt_def, variant_index) ;
594
622
}
595
623
}
596
- block. and ( place_builder. field ( this, name, expr . ty ) )
624
+ block. and ( place_builder. field ( this, name) )
597
625
}
598
626
ExprKind :: Deref { arg } => {
599
627
let place_builder = unpack ! (
0 commit comments