@@ -90,15 +90,13 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
90
90
let hir_projection = match mir_projection {
91
91
ProjectionElem :: Deref => HirProjectionKind :: Deref ,
92
92
ProjectionElem :: Field ( field, _) => {
93
- // We will never encouter this for multivariant enums,
94
- // read the comment for `Downcast`.
95
93
let variant = variant. unwrap_or ( VariantIdx :: new ( 0 ) ) ;
96
94
HirProjectionKind :: Field ( field. index ( ) as u32 , variant)
97
95
}
98
96
ProjectionElem :: Downcast ( .., idx) => {
99
- // This projections exist for enums that have
100
- // single and multiple variants.
101
- // For single variants, enums are not captured completely .
97
+ // We don't expect to see multi-variant enums here, as earlier
98
+ // phases will have truncated them already. However, there can
99
+ // still be downcasts, thanks to single-variant enums .
102
100
// We keep track of VariantIdx so we can use this information
103
101
// if the next ProjectionElem is a Field.
104
102
variant = Some ( * idx) ;
@@ -200,7 +198,7 @@ fn find_capture_matching_projections<'a, 'tcx>(
200
198
/// Takes a PlaceBuilder and resolves the upvar (if any) within it, so that the
201
199
/// `PlaceBuilder` now starts from `PlaceBase::Local`.
202
200
///
203
- /// Returns a Result with the error being the HirId of the Upvar that was not found.
201
+ /// Returns a Result with the error being the PlaceBuilder (`from_builder`) that was not found.
204
202
fn to_upvars_resolved_place_builder < ' a , ' tcx > (
205
203
from_builder : PlaceBuilder < ' tcx > ,
206
204
tcx : TyCtxt < ' tcx > ,
@@ -305,15 +303,23 @@ impl<'tcx> PlaceBuilder<'tcx> {
305
303
to_upvars_resolved_place_builder ( self , tcx, typeck_results) . unwrap ( )
306
304
}
307
305
306
+ /// Attempts to resolve the `PlaceBuilder`.
307
+ /// On success, it will return the resolved `PlaceBuilder`.
308
+ /// On failure, it will return itself.
309
+ ///
310
+ /// Upvars resolve may fail for a `PlaceBuilder` when attempting to
311
+ /// resolve a disjoint field whose root variable is not captured
312
+ /// (destructured assignments) or when attempting to resolve a root
313
+ /// variable (discriminant matching with only wildcard arm) that is
314
+ /// not captured. This can happen because the final mir that will be
315
+ /// generated doesn't require a read for this place. Failures will only
316
+ /// happen inside closures.
308
317
crate fn try_upvars_resolved < ' a > (
309
318
self ,
310
319
tcx : TyCtxt < ' tcx > ,
311
320
typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
312
321
) -> Result < PlaceBuilder < ' tcx > , PlaceBuilder < ' tcx > > {
313
- match to_upvars_resolved_place_builder ( self , tcx, typeck_results) {
314
- Ok ( upvars_resolved) => Ok ( upvars_resolved) ,
315
- Err ( upvars_unresolved) => Err ( upvars_unresolved) ,
316
- }
322
+ to_upvars_resolved_place_builder ( self , tcx, typeck_results)
317
323
}
318
324
319
325
crate fn base ( & self ) -> PlaceBase {
@@ -662,7 +668,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
662
668
block,
663
669
source_info,
664
670
len,
665
- Rvalue :: Len ( slice. clone ( ) . into_place ( self . tcx , self . typeck_results ) ) ,
671
+ Rvalue :: Len ( slice. into_place ( self . tcx , self . typeck_results ) ) ,
666
672
) ;
667
673
// lt = idx < len
668
674
self . cfg . push_assign (
0 commit comments