@@ -19,6 +19,7 @@ use rustc_target::abi::VariantIdx;
1919use rustc_index:: vec:: Idx ;
2020
2121use std:: assert_matches:: assert_matches;
22+ use std:: convert:: From ;
2223use std:: iter;
2324
2425/// `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> {
6667 ///
6768 /// Note: in contrast to `PlaceBuilder::Local` we have not yet determined all `Field` types
6869 /// and will only do so once converting to `PlaceBuilder::Local`.
69- UpVar ( UpVar , Vec < PlaceElem < ' tcx > > ) ,
70+ UpVar ( UpVar , Vec < UpvarProjectionElem < ' tcx > > ) ,
7071}
7172
7273#[ derive( Copy , Clone , Debug , PartialEq ) ]
@@ -82,7 +83,7 @@ pub(crate) struct UpVar {
8283/// part of a path that is captured by a closure. We stop applying projections once we see the first
8384/// projection that isn't captured by a closure.
8485fn convert_to_hir_projections_and_truncate_for_capture < ' tcx > (
85- mir_projections : & [ PlaceElem < ' tcx > ] ,
86+ mir_projections : & [ UpvarProjectionElem < ' tcx > ] ,
8687) -> Vec < HirProjectionKind > {
8788 let mut hir_projections = Vec :: new ( ) ;
8889 let mut variant = None ;
@@ -156,7 +157,7 @@ fn is_ancestor_or_same_capture(
156157fn find_capture_matching_projections < ' a , ' tcx > (
157158 upvars : & ' a CaptureMap < ' tcx > ,
158159 var_hir_id : LocalVarId ,
159- projections : & [ PlaceElem < ' tcx > ] ,
160+ projections : & [ UpvarProjectionElem < ' tcx > ] ,
160161) -> Option < ( usize , & ' a Capture < ' tcx > ) > {
161162 let hir_projections = convert_to_hir_projections_and_truncate_for_capture ( projections) ;
162163
@@ -212,8 +213,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
212213 capture. captured_place . place . base_ty ,
213214 projection,
214215 & capture. captured_place . place . projections ,
215- )
216- . collect :: < Vec < _ > > ( ) ;
216+ ) ;
217217
218218 let upvar_resolved_place_builder = PlaceBuilder :: construct_local_place_builder (
219219 cx,
@@ -222,6 +222,37 @@ fn to_upvars_resolved_place_builder<'tcx>(
222222 upvar_projection,
223223 ) ;
224224
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+
225256 Some ( upvar_resolved_place_builder)
226257}
227258
@@ -233,14 +264,14 @@ fn to_upvars_resolved_place_builder<'tcx>(
233264/// projection kinds are unsupported.
234265fn strip_prefix < ' a , ' tcx > (
235266 mut base_ty : Ty < ' tcx > ,
236- projections : & ' a [ PlaceElem < ' tcx > ] ,
267+ projections : & ' a [ UpvarProjectionElem < ' tcx > ] ,
237268 prefix_projections : & [ HirProjection < ' tcx > ] ,
238- ) -> impl Iterator < Item = PlaceElem < ' tcx > > + ' a {
269+ ) -> Vec < UpvarProjectionElem < ' tcx > > {
239270 let mut iter = projections
240271 . iter ( )
241- . copied ( )
242272 // 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) ;
244275 for projection in prefix_projections {
245276 debug ! ( ?projection, ?projection. ty) ;
246277
@@ -261,7 +292,8 @@ fn strip_prefix<'a, 'tcx>(
261292
262293 base_ty = projection. ty ;
263294 }
264- iter
295+
296+ iter. collect :: < Vec < _ > > ( )
265297}
266298
267299impl < ' tcx > PlaceBuilder < ' tcx > {
@@ -292,11 +324,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
292324 & self ,
293325 cx : & Builder < ' _ , ' tcx > ,
294326 ) -> 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 {
296328 return None ;
297329 } ;
298330
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)
300332 }
301333
302334 pub ( crate ) fn get_local_projection ( & self ) -> & [ PlaceElem < ' tcx > ] {
@@ -309,19 +341,16 @@ impl<'tcx> PlaceBuilder<'tcx> {
309341 }
310342
311343 #[ 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 {
318345 let field_ty = match self {
319346 PlaceBuilder :: Local ( ..) => {
320347 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
323353 }
324- PlaceBuilder :: UpVar ( ..) => default_field_ty,
325354 } ;
326355
327356 self . project ( ProjectionElem :: Field ( f, field_ty) )
@@ -347,7 +376,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
347376 PlaceBuilder :: Local ( local, proj)
348377 }
349378 PlaceBuilder :: UpVar ( upvar, mut proj) => {
350- proj. push ( elem) ;
379+ proj. push ( elem. into ( ) ) ;
351380 PlaceBuilder :: UpVar ( upvar, proj)
352381 }
353382 } ;
@@ -363,8 +392,8 @@ impl<'tcx> PlaceBuilder<'tcx> {
363392 * local,
364393 Vec :: from_iter ( proj. iter ( ) . copied ( ) . chain ( [ elem. into ( ) ] ) ) ,
365394 ) ,
366- PlaceBuilder :: Upvar ( upvar, proj) => PlaceBuilder :: UpVar (
367- upvar,
395+ PlaceBuilder :: UpVar ( upvar, proj) => PlaceBuilder :: UpVar (
396+ * upvar,
368397 Vec :: from_iter ( proj. iter ( ) . copied ( ) . chain ( [ elem. into ( ) ] ) ) ,
369398 ) ,
370399 }
@@ -378,11 +407,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
378407 /// Fallible as the root of this place may be an upvar for
379408 /// which no base type can be determined.
380409 #[ instrument( skip( cx) , level = "debug" ) ]
381- fn try_compute_field_ty (
410+ fn compute_field_ty (
382411 cx : & Builder < ' _ , ' tcx > ,
383412 field : Field ,
384413 base_place : PlaceBuilder < ' tcx > ,
385- ) -> Option < Ty < ' tcx > > {
414+ ) -> Ty < ' tcx > {
386415 let field_idx = field. as_usize ( ) ;
387416 let PlaceTy { ty, variant_index } = base_place. to_place ( cx) . ty ( & cx. local_decls , cx. tcx ) ;
388417 let base_ty = cx. tcx . normalize_erasing_regions ( cx. param_env , ty) ;
@@ -442,7 +471,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
442471 _ => bug ! ( "couldn't create field type, unexpected base type: {:?}" , base_ty) ,
443472 } ;
444473
445- Some ( cx. tcx . normalize_erasing_regions ( cx. param_env , field_ty) )
474+ cx. tcx . normalize_erasing_regions ( cx. param_env , field_ty)
446475 }
447476
448477 /// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::UpVar` whose upvars
@@ -455,7 +484,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
455484 cx : & Builder < ' _ , ' tcx > ,
456485 local : Local ,
457486 mut local_projection : Vec < PlaceElem < ' tcx > > ,
458- upvar_projection : Vec < PlaceElem < ' tcx > > ,
487+ upvar_projection : Vec < UpvarProjectionElem < ' tcx > > ,
459488 ) -> Self {
460489 // We iterate through `upvar_projection` and whenever we find a `ProjectionElem::Field` we use
461490 // the ancestor projections, i.e. those projection elements that come before the field projection,
@@ -464,11 +493,10 @@ impl<'tcx> PlaceBuilder<'tcx> {
464493 for proj in upvar_projection. iter ( ) {
465494 debug ! ( "proj: {:?}, local_projection: {:?}" , proj, local_projection) ;
466495 match * proj {
467- ProjectionElem :: Field ( field, default_field_ty ) => {
496+ ProjectionElem :: Field ( field, _ ) => {
468497 let ancestor_proj = local_projection. to_vec ( ) ;
469498 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) ;
472500 debug ! ( ?field_ty) ;
473501
474502 local_projection. push ( ProjectionElem :: Field ( field, field_ty) ) ;
@@ -593,7 +621,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
593621 place_builder = place_builder. downcast ( * adt_def, variant_index) ;
594622 }
595623 }
596- block. and ( place_builder. field ( this, name, expr . ty ) )
624+ block. and ( place_builder. field ( this, name) )
597625 }
598626 ExprKind :: Deref { arg } => {
599627 let place_builder = unpack ! (
0 commit comments