@@ -393,19 +393,22 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
393
393
must_unwind : common:: type_needs_unwind_cleanup ( self . ccx , ty) ,
394
394
val : val,
395
395
ty : ty,
396
- zero : false
396
+ fill_on_drop : false ,
397
+ skip_dtor : false ,
397
398
} ;
398
399
399
- debug ! ( "schedule_drop_mem({:?}, val={}, ty={})" ,
400
+ debug ! ( "schedule_drop_mem({:?}, val={}, ty={}) fill_on_drop={} skip_dtor={} " ,
400
401
cleanup_scope,
401
402
self . ccx. tn( ) . val_to_string( val) ,
402
- ty. repr( self . ccx. tcx( ) ) ) ;
403
+ ty. repr( self . ccx. tcx( ) ) ,
404
+ drop. fill_on_drop,
405
+ drop. skip_dtor) ;
403
406
404
407
self . schedule_clean ( cleanup_scope, drop as CleanupObj ) ;
405
408
}
406
409
407
- /// Schedules a (deep) drop and zero-ing of `val`, which is a pointer to an instance of `ty`
408
- fn schedule_drop_and_zero_mem ( & self ,
410
+ /// Schedules a (deep) drop and filling of `val`, which is a pointer to an instance of `ty`
411
+ fn schedule_drop_and_fill_mem ( & self ,
409
412
cleanup_scope : ScopeId ,
410
413
val : ValueRef ,
411
414
ty : Ty < ' tcx > ) {
@@ -416,14 +419,48 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
416
419
must_unwind : common:: type_needs_unwind_cleanup ( self . ccx , ty) ,
417
420
val : val,
418
421
ty : ty,
419
- zero : true
422
+ fill_on_drop : true ,
423
+ skip_dtor : false ,
424
+ } ;
425
+
426
+ debug ! ( "schedule_drop_and_fill_mem({:?}, val={}, ty={}, fill_on_drop={}, skip_dtor={})" ,
427
+ cleanup_scope,
428
+ self . ccx. tn( ) . val_to_string( val) ,
429
+ ty. repr( self . ccx. tcx( ) ) ,
430
+ drop. fill_on_drop,
431
+ drop. skip_dtor) ;
432
+
433
+ self . schedule_clean ( cleanup_scope, drop as CleanupObj ) ;
434
+ }
435
+
436
+ /// Issue #23611: Schedules a (deep) drop of the contents of
437
+ /// `val`, which is a pointer to an instance of struct/enum type
438
+ /// `ty`. The scheduled code handles extracting the discriminant
439
+ /// and dropping the contents associated with that variant
440
+ /// *without* executing any associated drop implementation.
441
+ fn schedule_drop_enum_contents ( & self ,
442
+ cleanup_scope : ScopeId ,
443
+ val : ValueRef ,
444
+ ty : Ty < ' tcx > ) {
445
+ // `if` below could be "!contents_needs_drop"; skipping drop
446
+ // is just an optimization, so sound to be conservative.
447
+ if !self . type_needs_drop ( ty) { return ; }
448
+
449
+ let drop = box DropValue {
450
+ is_immediate : false ,
451
+ must_unwind : common:: type_needs_unwind_cleanup ( self . ccx , ty) ,
452
+ val : val,
453
+ ty : ty,
454
+ fill_on_drop : false ,
455
+ skip_dtor : true ,
420
456
} ;
421
457
422
- debug ! ( "schedule_drop_and_zero_mem ({:?}, val={}, ty={}, zero ={}) " ,
458
+ debug ! ( "schedule_drop_enum_contents ({:?}, val={}, ty={}) fill_on_drop ={} skip_dtor={} " ,
423
459
cleanup_scope,
424
460
self . ccx. tn( ) . val_to_string( val) ,
425
461
ty. repr( self . ccx. tcx( ) ) ,
426
- true ) ;
462
+ drop. fill_on_drop,
463
+ drop. skip_dtor) ;
427
464
428
465
self . schedule_clean ( cleanup_scope, drop as CleanupObj ) ;
429
466
}
@@ -440,13 +477,16 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
440
477
must_unwind : common:: type_needs_unwind_cleanup ( self . ccx , ty) ,
441
478
val : val,
442
479
ty : ty,
443
- zero : false
480
+ fill_on_drop : false ,
481
+ skip_dtor : false ,
444
482
} ;
445
483
446
- debug ! ( "schedule_drop_immediate({:?}, val={}, ty={:?})" ,
484
+ debug ! ( "schedule_drop_immediate({:?}, val={}, ty={:?}) fill_on_drop={} skip_dtor={} " ,
447
485
cleanup_scope,
448
486
self . ccx. tn( ) . val_to_string( val) ,
449
- ty. repr( self . ccx. tcx( ) ) ) ;
487
+ ty. repr( self . ccx. tcx( ) ) ,
488
+ drop. fill_on_drop,
489
+ drop. skip_dtor) ;
450
490
451
491
self . schedule_clean ( cleanup_scope, drop as CleanupObj ) ;
452
492
}
@@ -987,7 +1027,8 @@ pub struct DropValue<'tcx> {
987
1027
must_unwind : bool ,
988
1028
val : ValueRef ,
989
1029
ty : Ty < ' tcx > ,
990
- zero : bool
1030
+ fill_on_drop : bool ,
1031
+ skip_dtor : bool ,
991
1032
}
992
1033
993
1034
impl < ' tcx > Cleanup < ' tcx > for DropValue < ' tcx > {
@@ -1007,13 +1048,18 @@ impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> {
1007
1048
bcx : Block < ' blk , ' tcx > ,
1008
1049
debug_loc : DebugLoc )
1009
1050
-> Block < ' blk , ' tcx > {
1010
- let _icx = base:: push_ctxt ( "<DropValue as Cleanup>::trans" ) ;
1051
+ let skip_dtor = self . skip_dtor ;
1052
+ let _icx = if skip_dtor {
1053
+ base:: push_ctxt ( "<DropValue as Cleanup>::trans skip_dtor=true" )
1054
+ } else {
1055
+ base:: push_ctxt ( "<DropValue as Cleanup>::trans skip_dtor=false" )
1056
+ } ;
1011
1057
let bcx = if self . is_immediate {
1012
- glue:: drop_ty_immediate ( bcx, self . val , self . ty , debug_loc)
1058
+ glue:: drop_ty_immediate ( bcx, self . val , self . ty , debug_loc, self . skip_dtor )
1013
1059
} else {
1014
- glue:: drop_ty ( bcx, self . val , self . ty , debug_loc)
1060
+ glue:: drop_ty_core ( bcx, self . val , self . ty , debug_loc, self . skip_dtor )
1015
1061
} ;
1016
- if self . zero {
1062
+ if self . fill_on_drop {
1017
1063
base:: drop_done_fill_mem ( bcx, self . val , self . ty ) ;
1018
1064
}
1019
1065
bcx
@@ -1190,10 +1236,14 @@ pub trait CleanupMethods<'blk, 'tcx> {
1190
1236
cleanup_scope : ScopeId ,
1191
1237
val : ValueRef ,
1192
1238
ty : Ty < ' tcx > ) ;
1193
- fn schedule_drop_and_zero_mem ( & self ,
1239
+ fn schedule_drop_and_fill_mem ( & self ,
1194
1240
cleanup_scope : ScopeId ,
1195
1241
val : ValueRef ,
1196
1242
ty : Ty < ' tcx > ) ;
1243
+ fn schedule_drop_enum_contents ( & self ,
1244
+ cleanup_scope : ScopeId ,
1245
+ val : ValueRef ,
1246
+ ty : Ty < ' tcx > ) ;
1197
1247
fn schedule_drop_immediate ( & self ,
1198
1248
cleanup_scope : ScopeId ,
1199
1249
val : ValueRef ,
0 commit comments