@@ -30,7 +30,6 @@ use trans::callee;
3030use trans:: cleanup;
3131use trans:: cleanup:: CleanupMethods ;
3232use trans:: common:: * ;
33- use trans:: datum;
3433use trans:: debuginfo:: DebugLoc ;
3534use trans:: declare;
3635use trans:: expr;
@@ -361,75 +360,36 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
361360 substs : & subst:: Substs < ' tcx > )
362361 -> Block < ' blk , ' tcx >
363362{
364- let repr = adt :: represent_type ( bcx. ccx ( ) , t ) ;
363+ debug ! ( "trans_struct_drop t: {}" , bcx. ty_to_string ( t ) ) ;
365364
366365 // 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) ;
369367
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).
371370 let params = unsafe {
372371 let ty = Type :: from_ref ( llvm:: LLVMTypeOf ( dtor_addr) ) ;
373372 ty. element_type ( ) . func_params ( )
374373 } ;
374+ assert_eq ! ( params. len( ) , 1 ) ;
375375
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 ( ) ;
394383
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) ;
424387
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 ) ;
430391
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)
433393}
434394
435395fn size_and_align_of_dst < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , t : Ty < ' tcx > , info : ValueRef )
0 commit comments