@@ -90,15 +90,13 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
9090 let hir_projection = match mir_projection {
9191 ProjectionElem :: Deref => HirProjectionKind :: Deref ,
9292 ProjectionElem :: Field ( field, _) => {
93- // We will never encouter this for multivariant enums,
94- // read the comment for `Downcast`.
9593 let variant = variant. unwrap_or ( VariantIdx :: new ( 0 ) ) ;
9694 HirProjectionKind :: Field ( field. index ( ) as u32 , variant)
9795 }
9896 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 .
102100 // We keep track of VariantIdx so we can use this information
103101 // if the next ProjectionElem is a Field.
104102 variant = Some ( * idx) ;
@@ -200,7 +198,7 @@ fn find_capture_matching_projections<'a, 'tcx>(
200198/// Takes a PlaceBuilder and resolves the upvar (if any) within it, so that the
201199/// `PlaceBuilder` now starts from `PlaceBase::Local`.
202200///
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.
204202fn to_upvars_resolved_place_builder < ' a , ' tcx > (
205203 from_builder : PlaceBuilder < ' tcx > ,
206204 tcx : TyCtxt < ' tcx > ,
@@ -305,15 +303,23 @@ impl<'tcx> PlaceBuilder<'tcx> {
305303 to_upvars_resolved_place_builder ( self , tcx, typeck_results) . unwrap ( )
306304 }
307305
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.
308317 crate fn try_upvars_resolved < ' a > (
309318 self ,
310319 tcx : TyCtxt < ' tcx > ,
311320 typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
312321 ) -> 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)
317323 }
318324
319325 crate fn base ( & self ) -> PlaceBase {
@@ -662,7 +668,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
662668 block,
663669 source_info,
664670 len,
665- Rvalue :: Len ( slice. clone ( ) . into_place ( self . tcx , self . typeck_results ) ) ,
671+ Rvalue :: Len ( slice. into_place ( self . tcx , self . typeck_results ) ) ,
666672 ) ;
667673 // lt = idx < len
668674 self . cfg . push_assign (
0 commit comments