@@ -30,7 +30,6 @@ use trans::callee;
30
30
use trans:: cleanup;
31
31
use trans:: cleanup:: CleanupMethods ;
32
32
use trans:: common:: * ;
33
- use trans:: datum;
34
33
use trans:: debuginfo:: DebugLoc ;
35
34
use trans:: declare;
36
35
use trans:: expr;
@@ -361,75 +360,36 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
361
360
substs : & subst:: Substs < ' tcx > )
362
361
-> Block < ' blk , ' tcx >
363
362
{
364
- let repr = adt :: represent_type ( bcx. ccx ( ) , t ) ;
363
+ debug ! ( "trans_struct_drop t: {}" , bcx. ty_to_string ( t ) ) ;
365
364
366
365
// Find and call the actual destructor
367
- let dtor_addr = get_res_dtor ( bcx. ccx ( ) , dtor_did, t,
368
- class_did, substs) ;
366
+ let dtor_addr = get_res_dtor ( bcx. ccx ( ) , dtor_did, t, class_did, substs) ;
369
367
370
- // The first argument is the "self" argument for drop
368
+ // Class dtors have no explicit args, so the params should
369
+ // just consist of the environment (self).
371
370
let params = unsafe {
372
371
let ty = Type :: from_ref ( llvm:: LLVMTypeOf ( dtor_addr) ) ;
373
372
ty. element_type ( ) . func_params ( )
374
373
} ;
374
+ assert_eq ! ( params. len( ) , 1 ) ;
375
375
376
- let fty = ty:: lookup_item_type ( bcx. tcx ( ) , dtor_did) . ty . subst ( bcx. tcx ( ) , substs) ;
377
- let self_ty = match fty. sty {
378
- ty:: ty_bare_fn( _, ref f) => {
379
- let sig = ty:: erase_late_bound_regions ( bcx. tcx ( ) , & f. sig ) ;
380
- assert ! ( sig. inputs. len( ) == 1 ) ;
381
- sig. inputs [ 0 ]
382
- }
383
- _ => bcx. sess ( ) . bug ( & format ! ( "Expected function type, found {}" ,
384
- bcx. ty_to_string( fty) ) )
385
- } ;
386
-
387
- let ( struct_data, info) = if type_is_sized ( bcx. tcx ( ) , t) {
388
- ( v0, None )
389
- } else {
390
- let data = GEPi ( bcx, v0, & [ 0 , abi:: FAT_PTR_ADDR ] ) ;
391
- let info = GEPi ( bcx, v0, & [ 0 , abi:: FAT_PTR_EXTRA ] ) ;
392
- ( Load ( bcx, data) , Some ( Load ( bcx, info) ) )
393
- } ;
376
+ // Be sure to put the contents into a scope so we can use an invoke
377
+ // instruction to call the user destructor but still call the field
378
+ // destructors if the user destructor panics.
379
+ //
380
+ // FIXME (#14875) panic-in-drop semantics might be unsupported; we
381
+ // might well consider changing below to more direct code.
382
+ let contents_scope = bcx. fcx . push_custom_cleanup_scope ( ) ;
394
383
395
- debug ! ( "trans_struct_drop t: {} fty: {} self_ty: {}" ,
396
- bcx. ty_to_string( t) , bcx. ty_to_string( fty) , bcx. ty_to_string( self_ty) ) ;
397
- // TODO: surely no reason to keep dispatching on variants here.
398
- adt:: fold_variants ( bcx, & * repr, struct_data, |variant_cx, struct_info, value| {
399
- debug ! ( "trans_struct_drop fold_variant: struct_info: {:?}" , struct_info) ;
400
- // Be sure to put the enum contents into a scope so we can use an invoke
401
- // instruction to call the user destructor but still call the field
402
- // destructors if the user destructor panics.
403
- let field_scope = variant_cx. fcx . push_custom_cleanup_scope ( ) ;
404
- variant_cx. fcx . schedule_drop_enum_contents ( cleanup:: CustomScope ( field_scope) , v0, t) ;
405
-
406
- // Class dtors have no explicit args, so the params should
407
- // just consist of the environment (self).
408
- assert_eq ! ( params. len( ) , 1 ) ;
409
- let self_arg = if type_is_fat_ptr ( bcx. tcx ( ) , self_ty) {
410
- // The dtor expects a fat pointer, so make one, even if we have to fake it.
411
- let scratch = datum:: rvalue_scratch_datum ( bcx, t, "__fat_ptr_drop_self" ) ;
412
- Store ( bcx, value, GEPi ( bcx, scratch. val , & [ 0 , abi:: FAT_PTR_ADDR ] ) ) ;
413
- Store ( bcx,
414
- // If we just had a thin pointer, make a fat pointer by sticking
415
- // null where we put the unsizing info. This works because t
416
- // is a sized type, so we will only unpack the fat pointer, never
417
- // use the fake info.
418
- info. unwrap_or ( C_null ( Type :: i8p ( bcx. ccx ( ) ) ) ) ,
419
- GEPi ( bcx, scratch. val , & [ 0 , abi:: FAT_PTR_EXTRA ] ) ) ;
420
- PointerCast ( variant_cx, scratch. val , params[ 0 ] )
421
- } else {
422
- PointerCast ( variant_cx, value, params[ 0 ] )
423
- } ;
384
+ // Issue #23611: schedule cleanup of contents, re-inspecting the
385
+ // discriminant (if any) in case of variant swap in drop code.
386
+ bcx. fcx . schedule_drop_enum_contents ( cleanup:: CustomScope ( contents_scope) , v0, t) ;
424
387
425
- let dtor_ty = ty:: mk_ctor_fn ( bcx. tcx ( ) ,
426
- class_did,
427
- & [ get_drop_glue_type ( bcx. ccx ( ) , t) ] ,
428
- ty:: mk_nil ( bcx. tcx ( ) ) ) ;
429
- let ( _, variant_cx) = invoke ( variant_cx, dtor_addr, & [ self_arg] , dtor_ty, DebugLoc :: None ) ;
388
+ let glue_type = get_drop_glue_type ( bcx. ccx ( ) , t) ;
389
+ let dtor_ty = ty:: mk_ctor_fn ( bcx. tcx ( ) , class_did, & [ glue_type] , ty:: mk_nil ( bcx. tcx ( ) ) ) ;
390
+ let ( _, bcx) = invoke ( bcx, dtor_addr, & [ v0] , dtor_ty, DebugLoc :: None ) ;
430
391
431
- variant_cx. fcx . pop_and_trans_custom_cleanup_scope ( variant_cx, field_scope)
432
- } )
392
+ bcx. fcx . pop_and_trans_custom_cleanup_scope ( bcx, contents_scope)
433
393
}
434
394
435
395
fn size_and_align_of_dst < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , t : Ty < ' tcx > , info : ValueRef )
0 commit comments