@@ -160,7 +160,7 @@ struct BreakableScope<'tcx> {
160
160
161
161
/// The target of an expression that breaks out of a scope
162
162
#[ derive( Clone , Copy , Debug ) ]
163
- pub enum BreakableTarget {
163
+ pub ( crate ) enum BreakableTarget {
164
164
Continue ( region:: Scope ) ,
165
165
Break ( region:: Scope ) ,
166
166
Return ,
@@ -287,7 +287,7 @@ impl<'tcx> Scopes<'tcx> {
287
287
288
288
/// Returns the topmost active scope, which is known to be alive until
289
289
/// the next scope expression.
290
- pub ( super ) fn topmost ( & self ) -> region:: Scope {
290
+ fn topmost ( & self ) -> region:: Scope {
291
291
self . scopes . last ( ) . expect ( "topmost_scope: no scopes present" ) . region_scope
292
292
}
293
293
@@ -301,7 +301,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
301
301
// ==========================
302
302
// Start a breakable scope, which tracks where `continue`, `break` and
303
303
// `return` should branch to.
304
- pub fn in_breakable_scope < F > (
304
+ crate fn in_breakable_scope < F > (
305
305
& mut self ,
306
306
loop_block : Option < BasicBlock > ,
307
307
break_destination : Place < ' tcx > ,
@@ -342,7 +342,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
342
342
}
343
343
}
344
344
345
- pub fn in_opt_scope < F , R > ( & mut self ,
345
+ crate fn in_opt_scope < F , R > ( & mut self ,
346
346
opt_scope : Option < ( region:: Scope , SourceInfo ) > ,
347
347
f : F )
348
348
-> BlockAnd < R >
@@ -361,7 +361,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
361
361
362
362
/// Convenience wrapper that pushes a scope and then executes `f`
363
363
/// to build its contents, popping the scope afterwards.
364
- pub fn in_scope < F , R > ( & mut self ,
364
+ crate fn in_scope < F , R > ( & mut self ,
365
365
region_scope : ( region:: Scope , SourceInfo ) ,
366
366
lint_level : LintLevel ,
367
367
f : F )
@@ -406,14 +406,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
406
406
/// scope and call `pop_scope` afterwards. Note that these two
407
407
/// calls must be paired; using `in_scope` as a convenience
408
408
/// wrapper maybe preferable.
409
- pub fn push_scope ( & mut self , region_scope : ( region:: Scope , SourceInfo ) ) {
409
+ crate fn push_scope ( & mut self , region_scope : ( region:: Scope , SourceInfo ) ) {
410
410
self . scopes . push_scope ( region_scope, self . source_scope ) ;
411
411
}
412
412
413
413
/// Pops a scope, which should have region scope `region_scope`,
414
414
/// adding any drops onto the end of `block` that are needed.
415
415
/// This must match 1-to-1 with `push_scope`.
416
- pub fn pop_scope ( & mut self ,
416
+ crate fn pop_scope ( & mut self ,
417
417
region_scope : ( region:: Scope , SourceInfo ) ,
418
418
mut block : BasicBlock )
419
419
-> BlockAnd < ( ) > {
@@ -427,7 +427,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
427
427
}
428
428
429
429
/// Sets up the drops for breaking from `block` to `target`.
430
- pub fn break_scope (
430
+ crate fn break_scope (
431
431
& mut self ,
432
432
mut block : BasicBlock ,
433
433
value : Option < ExprRef < ' tcx > > ,
@@ -496,7 +496,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
496
496
}
497
497
498
498
// TODO: use in pop_top_scope.
499
- pub fn exit_top_scope (
499
+ crate fn exit_top_scope (
500
500
& mut self ,
501
501
mut block : BasicBlock ,
502
502
target : BasicBlock ,
@@ -546,7 +546,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
546
546
///
547
547
/// This path terminates in GeneratorDrop. Returns the start of the path.
548
548
/// None indicates there’s no cleanup to do at this point.
549
- pub fn generator_drop_cleanup ( & mut self , yield_block : BasicBlock ) {
549
+ crate fn generator_drop_cleanup ( & mut self , yield_block : BasicBlock ) {
550
550
let drops = self . scopes . scopes . iter ( ) . flat_map ( |scope| & scope. drops ) ;
551
551
let mut next_drop = ROOT_NODE ;
552
552
for drop in drops {
@@ -556,7 +556,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
556
556
}
557
557
558
558
/// Creates a new source scope, nested in the current one.
559
- pub fn new_source_scope ( & mut self ,
559
+ crate fn new_source_scope ( & mut self ,
560
560
span : Span ,
561
561
lint_level : LintLevel ,
562
562
safety : Option < Safety > ) -> SourceScope {
@@ -583,7 +583,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
583
583
}
584
584
585
585
/// Given a span and the current source scope, make a SourceInfo.
586
- pub fn source_info ( & self , span : Span ) -> SourceInfo {
586
+ crate fn source_info ( & self , span : Span ) -> SourceInfo {
587
587
SourceInfo {
588
588
span,
589
589
scope : self . source_scope
@@ -614,7 +614,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
614
614
///
615
615
/// When building statics/constants, returns `None` since
616
616
/// intermediate values do not have to be dropped in that case.
617
- pub fn local_scope ( & self ) -> Option < region:: Scope > {
617
+ crate fn local_scope ( & self ) -> Option < region:: Scope > {
618
618
match self . hir . body_owner_kind {
619
619
hir:: BodyOwnerKind :: Const |
620
620
hir:: BodyOwnerKind :: Static ( _) =>
@@ -628,7 +628,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
628
628
629
629
// Scheduling drops
630
630
// ================
631
- pub fn schedule_drop_storage_and_value (
631
+ crate fn schedule_drop_storage_and_value (
632
632
& mut self ,
633
633
span : Span ,
634
634
region_scope : region:: Scope ,
@@ -642,7 +642,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
642
642
///
643
643
/// When called with `DropKind::Storage`, `place` shouldn't be the return
644
644
/// place, or a function parameter.
645
- pub fn schedule_drop (
645
+ crate fn schedule_drop (
646
646
& mut self ,
647
647
span : Span ,
648
648
region_scope : region:: Scope ,
@@ -720,7 +720,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
720
720
/// spurious borrow-check errors -- the problem, ironically, is
721
721
/// not the `DROP(_X)` itself, but the (spurious) unwind pathways
722
722
/// that it creates. See #64391 for an example.
723
- pub fn record_operands_moved ( & mut self , operands : & [ Operand < ' tcx > ] ) {
723
+ crate fn record_operands_moved ( & mut self , operands : & [ Operand < ' tcx > ] ) {
724
724
let scope = match self . local_scope ( ) {
725
725
None => {
726
726
// if there is no local scope, operands won't be dropped anyway
@@ -756,7 +756,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
756
756
///
757
757
/// This is a special case because the temporary for the condition needs to
758
758
/// be dropped on both the true and the false arm.
759
- pub fn test_bool (
759
+ crate fn test_bool (
760
760
& mut self ,
761
761
mut block : BasicBlock ,
762
762
condition : Expr < ' tcx > ,
@@ -836,13 +836,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
836
836
///
837
837
/// This path terminates in Resume. The path isn't created until after all
838
838
/// of the non-unwind paths in this item have been lowered.
839
- pub fn diverge_from ( & mut self , start : BasicBlock ) {
839
+ crate fn diverge_from ( & mut self , start : BasicBlock ) {
840
840
let next_drop = self . diverge_cleanup ( ) ;
841
841
self . scopes . unwind_drops . add_entry ( start, next_drop) ;
842
842
}
843
843
844
844
/// Utility function for *non*-scope code to build their own drops
845
- pub fn build_drop_and_replace ( & mut self ,
845
+ crate fn build_drop_and_replace ( & mut self ,
846
846
block : BasicBlock ,
847
847
span : Span ,
848
848
location : Place < ' tcx > ,
@@ -863,7 +863,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
863
863
/// Creates an Assert terminator and return the success block.
864
864
/// If the boolean condition operand is not the expected value,
865
865
/// a runtime panic will be caused with the given message.
866
- pub fn assert ( & mut self , block : BasicBlock ,
866
+ crate fn assert ( & mut self , block : BasicBlock ,
867
867
cond : Operand < ' tcx > ,
868
868
expected : bool ,
869
869
msg : AssertMessage < ' tcx > ,
@@ -892,7 +892,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
892
892
///
893
893
/// This is only needed for `match` arm scopes, because they have one
894
894
/// entrance per pattern, but only one exit.
895
- pub ( crate ) fn clear_top_scope ( & mut self , region_scope : region:: Scope ) {
895
+ crate fn clear_top_scope ( & mut self , region_scope : region:: Scope ) {
896
896
let top_scope = self . scopes . scopes . last_mut ( ) . unwrap ( ) ;
897
897
898
898
assert_eq ! ( top_scope. region_scope, region_scope) ;
@@ -1027,30 +1027,26 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
1027
1027
1028
1028
crate fn build_drop_trees ( & mut self , should_abort : bool ) {
1029
1029
if self . is_generator {
1030
- Self :: build_generator_drop_tree (
1030
+ self . build_generator_drop_trees (
1031
+ should_abort,
1032
+ ) ;
1033
+ } else {
1034
+ Self :: build_unwind_tree (
1031
1035
& mut self . cfg ,
1032
- & mut self . scopes . generator_drops ,
1036
+ & mut self . scopes . unwind_drops ,
1033
1037
self . fn_span ,
1034
1038
should_abort,
1035
1039
) ;
1036
1040
}
1037
- Self :: build_unwind_tree (
1038
- & mut self . cfg ,
1039
- & mut self . scopes . unwind_drops ,
1040
- self . fn_span ,
1041
- should_abort,
1042
- ) ;
1043
1041
}
1044
1042
1045
- fn build_generator_drop_tree (
1046
- cfg : & mut CFG < ' tcx > ,
1047
- drops : & mut DropTree ,
1048
- fn_span : Span ,
1049
- should_abort : bool ,
1050
- ) {
1043
+ fn build_generator_drop_trees ( & mut self , should_abort : bool ) {
1044
+ // Build the drop tree for dropping the generator while it's suspended.
1045
+ let drops = & mut self . scopes . generator_drops ;
1046
+ let cfg = & mut self . cfg ;
1047
+ let fn_span = self . fn_span ;
1051
1048
let mut blocks = IndexVec :: from_elem ( None , & drops. drops ) ;
1052
1049
build_drop_tree :: < GeneratorDrop > ( cfg, drops, & mut blocks) ;
1053
- // TODO: unwind?
1054
1050
if let Some ( root_block) = blocks[ ROOT_NODE ] {
1055
1051
cfg. terminate (
1056
1052
root_block,
@@ -1061,7 +1057,17 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
1061
1057
TerminatorKind :: GeneratorDrop ,
1062
1058
) ;
1063
1059
}
1064
- // Reuse the generator drop tree as the unwind tree.
1060
+
1061
+ // Build the drop tree for unwinding in the normal control flow paths.
1062
+ let resume_block = Self :: build_unwind_tree (
1063
+ cfg,
1064
+ & mut self . scopes . unwind_drops ,
1065
+ fn_span,
1066
+ should_abort,
1067
+ ) ;
1068
+
1069
+ // Build the drop tree for unwinding when dropping a suspended
1070
+ // generator.
1065
1071
//
1066
1072
// This is a different tree to the standard unwind paths here to
1067
1073
// prevent drop elaboration from creating drop flags that would have
@@ -1072,15 +1078,32 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
1072
1078
drops. entry_points . push ( ( drop_data. 1 , blocks[ drop_idx] . unwrap ( ) ) ) ;
1073
1079
}
1074
1080
}
1075
- Self :: build_unwind_tree ( cfg, drops, fn_span, should_abort) ;
1081
+ let mut blocks = IndexVec :: from_elem ( None , & drops. drops ) ;
1082
+ blocks[ ROOT_NODE ] = resume_block;
1083
+ build_drop_tree :: < Unwind > ( cfg, drops, & mut blocks) ;
1084
+ if let ( None , Some ( new_resume_block) ) = ( resume_block, blocks[ ROOT_NODE ] ) {
1085
+ let terminator = if should_abort {
1086
+ TerminatorKind :: Abort
1087
+ } else {
1088
+ TerminatorKind :: Resume
1089
+ } ;
1090
+ cfg. terminate (
1091
+ new_resume_block,
1092
+ SourceInfo {
1093
+ scope : OUTERMOST_SOURCE_SCOPE ,
1094
+ span : fn_span
1095
+ } ,
1096
+ terminator,
1097
+ ) ;
1098
+ }
1076
1099
}
1077
1100
1078
1101
fn build_unwind_tree (
1079
1102
cfg : & mut CFG < ' tcx > ,
1080
1103
drops : & mut DropTree ,
1081
1104
fn_span : Span ,
1082
1105
should_abort : bool ,
1083
- ) {
1106
+ ) -> Option < BasicBlock > {
1084
1107
let mut blocks = IndexVec :: from_elem ( None , & drops. drops ) ;
1085
1108
build_drop_tree :: < Unwind > ( cfg, drops, & mut blocks) ;
1086
1109
if let Some ( resume_block) = blocks[ ROOT_NODE ] {
@@ -1097,6 +1120,9 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
1097
1120
} ,
1098
1121
terminator,
1099
1122
) ;
1123
+ Some ( resume_block)
1124
+ } else {
1125
+ None
1100
1126
}
1101
1127
}
1102
1128
}
0 commit comments