@@ -144,12 +144,12 @@ struct DropData<'tcx> {
144
144
/// place to drop
145
145
location : Place < ' tcx > ,
146
146
147
- /// Whether this is a full value Drop, or just a StorageDead.
148
- kind : DropKind
147
+ /// Whether this is a value Drop or a StorageDead.
148
+ kind : DropKind ,
149
149
}
150
150
151
151
#[ derive( Debug , Default , Clone , Copy ) ]
152
- struct CachedBlock {
152
+ pub ( crate ) struct CachedBlock {
153
153
/// The cached block for the cleanups-on-diverge path. This block
154
154
/// contains code to run the current drop and all the preceding
155
155
/// drops (i.e. those having lower index in Drop’s Scope drop
@@ -166,7 +166,7 @@ struct CachedBlock {
166
166
}
167
167
168
168
#[ derive( Debug ) ]
169
- enum DropKind {
169
+ pub ( crate ) enum DropKind {
170
170
Value {
171
171
cached_block : CachedBlock ,
172
172
} ,
@@ -622,25 +622,58 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
622
622
abortblk
623
623
}
624
624
625
+ pub fn schedule_drop_storage_and_value (
626
+ & mut self ,
627
+ span : Span ,
628
+ region_scope : region:: Scope ,
629
+ place : & Place < ' tcx > ,
630
+ place_ty : Ty < ' tcx > ,
631
+ ) {
632
+ self . schedule_drop (
633
+ span, region_scope, place, place_ty,
634
+ DropKind :: Storage ,
635
+ ) ;
636
+ self . schedule_drop (
637
+ span, region_scope, place, place_ty,
638
+ DropKind :: Value {
639
+ cached_block : CachedBlock :: default ( ) ,
640
+ } ,
641
+ ) ;
642
+ }
643
+
625
644
// Scheduling drops
626
645
// ================
627
646
/// Indicates that `place` should be dropped on exit from
628
647
/// `region_scope`.
629
- pub fn schedule_drop ( & mut self ,
630
- span : Span ,
631
- region_scope : region:: Scope ,
632
- place : & Place < ' tcx > ,
633
- place_ty : Ty < ' tcx > ) {
648
+ ///
649
+ /// When called with `DropKind::Storage`, `place` should be a local
650
+ /// with an index higher than the current `self.arg_count`.
651
+ pub fn schedule_drop (
652
+ & mut self ,
653
+ span : Span ,
654
+ region_scope : region:: Scope ,
655
+ place : & Place < ' tcx > ,
656
+ place_ty : Ty < ' tcx > ,
657
+ drop_kind : DropKind ,
658
+ ) {
634
659
let needs_drop = self . hir . needs_drop ( place_ty) ;
635
- let drop_kind = if needs_drop {
636
- DropKind :: Value { cached_block : CachedBlock :: default ( ) }
637
- } else {
638
- // Only temps and vars need their storage dead.
639
- match * place {
640
- Place :: Local ( index) if index. index ( ) > self . arg_count => DropKind :: Storage ,
641
- _ => return
660
+ match drop_kind {
661
+ DropKind :: Value { .. } => if !needs_drop { return } ,
662
+ DropKind :: Storage => {
663
+ match * place {
664
+ Place :: Local ( index) => if index. index ( ) <= self . arg_count {
665
+ span_bug ! (
666
+ span, "`schedule_drop` called with index {} and arg_count {}" ,
667
+ index. index( ) ,
668
+ self . arg_count,
669
+ )
670
+ } ,
671
+ _ => span_bug ! (
672
+ span, "`schedule_drop` called with non-`Local` place {:?}" , place
673
+ ) ,
674
+ }
642
675
}
643
- } ;
676
+ }
644
677
645
678
for scope in self . scopes . iter_mut ( ) . rev ( ) {
646
679
let this_scope = scope. region_scope == region_scope;
@@ -895,24 +928,24 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
895
928
} ) ;
896
929
block = next;
897
930
}
898
- DropKind :: Storage => { }
899
- }
900
-
901
- // We do not need to emit StorageDead for generator drops
902
- if generator_drop {
903
- continue
904
- }
931
+ DropKind :: Storage => {
932
+ // We do not need to emit StorageDead for generator drops
933
+ if generator_drop {
934
+ continue
935
+ }
905
936
906
- // Drop the storage for both value and storage drops.
907
- // Only temps and vars need their storage dead.
908
- match drop_data. location {
909
- Place :: Local ( index) if index. index ( ) > arg_count => {
910
- cfg. push ( block, Statement {
911
- source_info,
912
- kind : StatementKind :: StorageDead ( index)
913
- } ) ;
937
+ // Drop the storage for both value and storage drops.
938
+ // Only temps and vars need their storage dead.
939
+ match drop_data. location {
940
+ Place :: Local ( index) if index. index ( ) > arg_count => {
941
+ cfg. push ( block, Statement {
942
+ source_info,
943
+ kind : StatementKind :: StorageDead ( index)
944
+ } ) ;
945
+ }
946
+ _ => unreachable ! ( ) ,
947
+ }
914
948
}
915
- _ => continue
916
949
}
917
950
}
918
951
block. unit ( )
0 commit comments