@@ -74,13 +74,19 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
7474 _block : mir:: BasicBlock ,
7575 return_places : CallReturnPlaces < ' _ , ' tcx > ,
7676 ) {
77- return_places . for_each ( |place| {
78- CallReturnEffect ( trans) . visit_place (
79- & place ,
80- PlaceContext :: MutatingUse ( MutatingUseContext :: Store ) ,
77+ if let CallReturnPlaces :: Yield ( resume_place ) = return_places {
78+ YieldResumeEffect ( trans) . visit_place (
79+ & resume_place ,
80+ PlaceContext :: MutatingUse ( MutatingUseContext :: Yield ) ,
8181 Location :: START ,
8282 )
83- } ) ;
83+ } else {
84+ return_places. for_each ( |place| {
85+ if let Some ( local) = place. as_local ( ) {
86+ trans. kill ( local) ;
87+ }
88+ } ) ;
89+ }
8490 }
8591}
8692
@@ -91,12 +97,16 @@ where
9197 T : GenKill < Local > ,
9298{
9399 fn visit_place ( & mut self , place : & mir:: Place < ' tcx > , context : PlaceContext , location : Location ) {
100+ if let PlaceContext :: MutatingUse ( MutatingUseContext :: Yield ) = context {
101+ // The resume place is evaluated and assigned to only after generator resumes, so its
102+ // effect is handled separately in `call_resume_effect`.
103+ return ;
104+ }
105+
94106 match DefUse :: for_place ( * place, context) {
95107 Some ( DefUse :: Def ) => {
96108 if let PlaceContext :: MutatingUse (
97- MutatingUseContext :: Yield
98- | MutatingUseContext :: Call
99- | MutatingUseContext :: AsmOutput ,
109+ MutatingUseContext :: Call | MutatingUseContext :: AsmOutput ,
100110 ) = context
101111 {
102112 // For the associated terminators, this is only a `Def` when the terminator returns
@@ -119,9 +129,9 @@ where
119129 }
120130}
121131
122- struct CallReturnEffect < ' a , T > ( & ' a mut T ) ;
132+ struct YieldResumeEffect < ' a , T > ( & ' a mut T ) ;
123133
124- impl < ' tcx , T > Visitor < ' tcx > for CallReturnEffect < ' _ , T >
134+ impl < ' tcx , T > Visitor < ' tcx > for YieldResumeEffect < ' _ , T >
125135where
126136 T : GenKill < Local > ,
127137{
@@ -291,12 +301,18 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
291301 _block : mir:: BasicBlock ,
292302 return_places : CallReturnPlaces < ' _ , ' tcx > ,
293303 ) {
294- return_places . for_each ( |place| {
295- CallReturnEffect ( trans) . visit_place (
296- & place ,
297- PlaceContext :: MutatingUse ( MutatingUseContext :: Store ) ,
304+ if let CallReturnPlaces :: Yield ( resume_place ) = return_places {
305+ YieldResumeEffect ( trans) . visit_place (
306+ & resume_place ,
307+ PlaceContext :: MutatingUse ( MutatingUseContext :: Yield ) ,
298308 Location :: START ,
299309 )
300- } ) ;
310+ } else {
311+ return_places. for_each ( |place| {
312+ if let Some ( local) = place. as_local ( ) {
313+ trans. remove ( local) ;
314+ }
315+ } ) ;
316+ }
301317 }
302318}
0 commit comments