@@ -91,6 +91,7 @@ use syntax_pos::{DUMMY_SP, Span};
91
91
use rustc_data_structures:: fx:: FxHashMap ;
92
92
use std:: collections:: hash_map:: Entry ;
93
93
use std:: mem;
94
+ use rustc:: hir:: GeneratorKind ;
94
95
95
96
#[ derive( Debug ) ]
96
97
struct Scope {
@@ -219,7 +220,12 @@ impl Scope {
219
220
/// `storage_only` controls whether to invalidate only drop paths that run `StorageDead`.
220
221
/// `this_scope_only` controls whether to invalidate only drop paths that refer to the current
221
222
/// 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
+ ) {
223
229
// FIXME: maybe do shared caching of `cached_exits` etc. to handle functions
224
230
// with lots of `try!`?
225
231
@@ -229,7 +235,7 @@ impl Scope {
229
235
// the current generator drop and unwind refer to top-of-scope
230
236
self . cached_generator_drop = None ;
231
237
232
- let ignore_unwinds = storage_only && !is_generator ;
238
+ let ignore_unwinds = storage_only && generator_kind . is_none ( ) ;
233
239
if !ignore_unwinds {
234
240
self . cached_unwind . invalidate ( ) ;
235
241
}
@@ -481,7 +487,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
481
487
482
488
unpack ! ( block = build_scope_drops(
483
489
& mut self . cfg,
484
- self . is_generator ,
490
+ self . generator_kind ,
485
491
& scope,
486
492
block,
487
493
unwind_to,
@@ -574,7 +580,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
574
580
575
581
unpack ! ( block = build_scope_drops(
576
582
& mut self . cfg,
577
- self . is_generator ,
583
+ self . generator_kind ,
578
584
scope,
579
585
block,
580
586
unwind_to,
@@ -625,7 +631,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
625
631
626
632
unpack ! ( block = build_scope_drops(
627
633
& mut self . cfg,
628
- self . is_generator ,
634
+ self . generator_kind ,
629
635
scope,
630
636
block,
631
637
unwind_to,
@@ -809,7 +815,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
809
815
// invalidating caches of each scope visited. This way bare minimum of the
810
816
// caches gets invalidated. i.e., if a new drop is added into the middle scope, the
811
817
// 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) ;
813
819
if this_scope {
814
820
let region_scope_span = region_scope. span ( self . hir . tcx ( ) ,
815
821
& self . hir . region_scope_tree ) ;
@@ -958,7 +964,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
958
964
}
959
965
}
960
966
961
- top_scope. invalidate_cache ( true , self . is_generator , true ) ;
967
+ top_scope. invalidate_cache ( true , self . generator_kind , true ) ;
962
968
} else {
963
969
bug ! ( "Expected as_local_operand to produce a temporary" ) ;
964
970
}
@@ -1016,7 +1022,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1016
1022
1017
1023
for scope in self . scopes . top_scopes ( first_uncached) {
1018
1024
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 ) ;
1020
1026
}
1021
1027
1022
1028
target
@@ -1079,14 +1085,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1079
1085
assert_eq ! ( top_scope. region_scope, region_scope) ;
1080
1086
1081
1087
top_scope. drops . clear ( ) ;
1082
- top_scope. invalidate_cache ( false , self . is_generator , true ) ;
1088
+ top_scope. invalidate_cache ( false , self . generator_kind , true ) ;
1083
1089
}
1084
1090
}
1085
1091
1086
1092
/// Builds drops for pop_scope and exit_scope.
1087
1093
fn build_scope_drops < ' tcx > (
1088
1094
cfg : & mut CFG < ' tcx > ,
1089
- is_generator : bool ,
1095
+ generator_kind : Option < GeneratorKind > ,
1090
1096
scope : & Scope ,
1091
1097
mut block : BasicBlock ,
1092
1098
last_unwind_to : BasicBlock ,
@@ -1130,7 +1136,7 @@ fn build_scope_drops<'tcx>(
1130
1136
continue ;
1131
1137
}
1132
1138
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)
1134
1140
. unwrap_or ( last_unwind_to) ;
1135
1141
1136
1142
let next = cfg. start_new_block ( ) ;
@@ -1156,19 +1162,19 @@ fn build_scope_drops<'tcx>(
1156
1162
1157
1163
fn get_unwind_to (
1158
1164
scope : & Scope ,
1159
- is_generator : bool ,
1165
+ generator_kind : Option < GeneratorKind > ,
1160
1166
unwind_from : usize ,
1161
1167
generator_drop : bool ,
1162
1168
) -> Option < BasicBlock > {
1163
1169
for drop_idx in ( 0 ..unwind_from) . rev ( ) {
1164
1170
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 ) => {
1167
1173
return Some ( drop_data. cached_block . get ( generator_drop) . unwrap_or_else ( || {
1168
1174
span_bug ! ( drop_data. span, "cached block not present for {:?}" , drop_data)
1169
1175
} ) ) ;
1170
1176
}
1171
- ( false , DropKind :: Value ) => {
1177
+ ( None , DropKind :: Value ) => {
1172
1178
return Some ( drop_data. cached_block . get ( generator_drop) . unwrap_or_else ( || {
1173
1179
span_bug ! ( drop_data. span, "cached block not present for {:?}" , drop_data)
1174
1180
} ) ) ;
@@ -1184,7 +1190,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>,
1184
1190
scope : & mut Scope ,
1185
1191
mut target : BasicBlock ,
1186
1192
generator_drop : bool ,
1187
- is_generator : bool )
1193
+ generator_kind : Option < GeneratorKind > )
1188
1194
-> BasicBlock
1189
1195
{
1190
1196
// Build up the drops in **reverse** order. The end result will
@@ -1224,7 +1230,7 @@ fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>,
1224
1230
// match the behavior of clang, but on inspection eddyb says
1225
1231
// this is not what clang does.
1226
1232
match drop_data. kind {
1227
- DropKind :: Storage if is_generator => {
1233
+ DropKind :: Storage if generator_kind . is_some ( ) => {
1228
1234
storage_deads. push ( Statement {
1229
1235
source_info : source_info ( drop_data. span ) ,
1230
1236
kind : StatementKind :: StorageDead ( drop_data. local )
0 commit comments