@@ -91,6 +91,7 @@ use syntax_pos::{DUMMY_SP, Span};
9191use  rustc_data_structures:: fx:: FxHashMap ; 
9292use  std:: collections:: hash_map:: Entry ; 
9393use  std:: mem; 
94+ use  rustc:: hir:: GeneratorKind ; 
9495
9596#[ derive( Debug ) ]  
9697struct  Scope  { 
@@ -219,7 +220,12 @@ impl Scope {
219220/// `storage_only` controls whether to invalidate only drop paths that run `StorageDead`. 
220221/// `this_scope_only` controls whether to invalidate only drop paths that refer to the current 
221222/// top-of-scope (as opposed to dependent scopes). 
222- fn  invalidate_cache ( & mut  self ,  storage_only :  bool ,  is_generator :  bool ,  this_scope_only :  bool )  { 
223+ fn  invalidate_cache ( 
224+         & mut  self , 
225+         storage_only :  bool , 
226+         generator_kind :  Option < GeneratorKind > , 
227+         this_scope_only :  bool 
228+     )  { 
223229        // FIXME: maybe do shared caching of `cached_exits` etc. to handle functions 
224230        // with lots of `try!`? 
225231
@@ -229,7 +235,7 @@ impl Scope {
229235        // the current generator drop and unwind refer to top-of-scope 
230236        self . cached_generator_drop  = None ; 
231237
232-         let  ignore_unwinds = storage_only && !is_generator ; 
238+         let  ignore_unwinds = storage_only && generator_kind . is_none ( ) ; 
233239        if  !ignore_unwinds { 
234240            self . cached_unwind . invalidate ( ) ; 
235241        } 
@@ -481,7 +487,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
481487
482488        unpack ! ( block = build_scope_drops( 
483489            & mut  self . cfg, 
484-             self . is_generator , 
490+             self . generator_kind , 
485491            & scope, 
486492            block, 
487493            unwind_to, 
@@ -574,7 +580,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
574580
575581            unpack ! ( block = build_scope_drops( 
576582                & mut  self . cfg, 
577-                 self . is_generator , 
583+                 self . generator_kind , 
578584                scope, 
579585                block, 
580586                unwind_to, 
@@ -625,7 +631,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
625631
626632            unpack ! ( block = build_scope_drops( 
627633                & mut  self . cfg, 
628-                 self . is_generator , 
634+                 self . generator_kind , 
629635                scope, 
630636                block, 
631637                unwind_to, 
@@ -809,7 +815,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
809815            // invalidating caches of each scope visited. This way bare minimum of the 
810816            // caches gets invalidated. i.e., if a new drop is added into the middle scope, the 
811817            // cache of outer scope stays intact. 
812-             scope. invalidate_cache ( !needs_drop,  self . is_generator ,  this_scope) ; 
818+             scope. invalidate_cache ( !needs_drop,  self . generator_kind ,  this_scope) ; 
813819            if  this_scope { 
814820                let  region_scope_span = region_scope. span ( self . hir . tcx ( ) , 
815821                                                          & self . hir . region_scope_tree ) ; 
@@ -958,7 +964,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
958964                        } 
959965                    } 
960966
961-                     top_scope. invalidate_cache ( true ,  self . is_generator ,  true ) ; 
967+                     top_scope. invalidate_cache ( true ,  self . generator_kind ,  true ) ; 
962968                }  else  { 
963969                    bug ! ( "Expected as_local_operand to produce a temporary" ) ; 
964970                } 
@@ -1016,7 +1022,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
10161022
10171023        for  scope in  self . scopes . top_scopes ( first_uncached)  { 
10181024            target = build_diverge_scope ( & mut  self . cfg ,  scope. region_scope_span , 
1019-                                          scope,  target,  generator_drop,  self . is_generator ) ; 
1025+                                          scope,  target,  generator_drop,  self . generator_kind ) ; 
10201026        } 
10211027
10221028        target
@@ -1079,14 +1085,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
10791085        assert_eq ! ( top_scope. region_scope,  region_scope) ; 
10801086
10811087        top_scope. drops . clear ( ) ; 
1082-         top_scope. invalidate_cache ( false ,  self . is_generator ,  true ) ; 
1088+         top_scope. invalidate_cache ( false ,  self . generator_kind ,  true ) ; 
10831089    } 
10841090} 
10851091
10861092/// Builds drops for pop_scope and exit_scope. 
10871093fn  build_scope_drops < ' tcx > ( 
10881094    cfg :  & mut  CFG < ' tcx > , 
1089-     is_generator :   bool , 
1095+     generator_kind :   Option < GeneratorKind > , 
10901096    scope :  & Scope , 
10911097    mut  block :  BasicBlock , 
10921098    last_unwind_to :  BasicBlock , 
@@ -1130,7 +1136,7 @@ fn build_scope_drops<'tcx>(
11301136                    continue ; 
11311137                } 
11321138
1133-                 let  unwind_to = get_unwind_to ( scope,  is_generator ,  drop_idx,  generator_drop) 
1139+                 let  unwind_to = get_unwind_to ( scope,  generator_kind ,  drop_idx,  generator_drop) 
11341140                    . unwrap_or ( last_unwind_to) ; 
11351141
11361142                let  next = cfg. start_new_block ( ) ; 
@@ -1156,19 +1162,19 @@ fn build_scope_drops<'tcx>(
11561162
11571163fn  get_unwind_to ( 
11581164    scope :  & Scope , 
1159-     is_generator :   bool , 
1165+     generator_kind :   Option < GeneratorKind > , 
11601166    unwind_from :  usize , 
11611167    generator_drop :  bool , 
11621168)  -> Option < BasicBlock >  { 
11631169    for  drop_idx in  ( 0 ..unwind_from) . rev ( )  { 
11641170        let  drop_data = & scope. drops [ drop_idx] ; 
1165-         match  ( is_generator ,  & drop_data. kind )  { 
1166-             ( true ,  DropKind :: Storage )  => { 
1171+         match  ( generator_kind ,  & drop_data. kind )  { 
1172+             ( Some ( _ ) ,  DropKind :: Storage )  => { 
11671173                return  Some ( drop_data. cached_block . get ( generator_drop) . unwrap_or_else ( || { 
11681174                    span_bug ! ( drop_data. span,  "cached block not present for {:?}" ,  drop_data) 
11691175                } ) ) ; 
11701176            } 
1171-             ( false ,  DropKind :: Value )  => { 
1177+             ( None ,  DropKind :: Value )  => { 
11721178                return  Some ( drop_data. cached_block . get ( generator_drop) . unwrap_or_else ( || { 
11731179                    span_bug ! ( drop_data. span,  "cached block not present for {:?}" ,  drop_data) 
11741180                } ) ) ; 
@@ -1184,7 +1190,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>,
11841190                             scope :  & mut  Scope , 
11851191                             mut  target :  BasicBlock , 
11861192                             generator_drop :  bool , 
1187-                              is_generator :   bool ) 
1193+                              generator_kind :   Option < GeneratorKind > ) 
11881194                             -> BasicBlock 
11891195{ 
11901196    // Build up the drops in **reverse** order. The end result will 
@@ -1224,7 +1230,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>,
12241230        // match the behavior of clang, but on inspection eddyb says 
12251231        // this is not what clang does. 
12261232        match  drop_data. kind  { 
1227-             DropKind :: Storage  if  is_generator  => { 
1233+             DropKind :: Storage  if  generator_kind . is_some ( )  => { 
12281234                storage_deads. push ( Statement  { 
12291235                    source_info :  source_info ( drop_data. span ) , 
12301236                    kind :  StatementKind :: StorageDead ( drop_data. local ) 
0 commit comments