@@ -395,11 +395,39 @@ pub fn trans_struct_drop_flag(bcx: @mut Block, t: ty::t, v0: ValueRef, dtor_did:
395
395
let repr = adt:: represent_type ( bcx. ccx ( ) , t) ;
396
396
let drop_flag = adt:: trans_drop_flag_ptr ( bcx, repr, v0) ;
397
397
do with_cond( bcx, IsNotNull ( bcx, Load ( bcx, drop_flag) ) ) |cx| {
398
- trans_struct_drop ( cx, t, v0, dtor_did, class_did, substs)
398
+ let mut bcx = cx;
399
+
400
+ // Find and call the actual destructor
401
+ let dtor_addr = get_res_dtor ( bcx. ccx ( ) , dtor_did,
402
+ class_did, substs. tps . clone ( ) ) ;
403
+
404
+ // The second argument is the "self" argument for drop
405
+ let params = unsafe {
406
+ let ty = Type :: from_ref ( llvm:: LLVMTypeOf ( dtor_addr) ) ;
407
+ ty. element_type ( ) . func_params ( )
408
+ } ;
409
+
410
+ // Class dtors have no explicit args, so the params should
411
+ // just consist of the environment (self)
412
+ assert_eq ! ( params. len( ) , 1 ) ;
413
+
414
+ let self_arg = PointerCast ( bcx, v0, params[ 0 ] ) ;
415
+ let args = ~[ self_arg] ;
416
+
417
+ Call ( bcx, dtor_addr, args, [ ] ) ;
418
+
419
+ // Drop the fields
420
+ let field_tys = ty:: struct_fields ( bcx. tcx ( ) , class_did, substs) ;
421
+ for ( i, fld) in field_tys. iter ( ) . enumerate ( ) {
422
+ let llfld_a = adt:: trans_field_ptr ( bcx, repr, v0, 0 , i) ;
423
+ bcx = drop_ty ( bcx, llfld_a, fld. mt . ty ) ;
424
+ }
425
+
426
+ bcx
399
427
}
400
428
}
401
429
402
- pub fn trans_struct_drop ( bcx : @mut Block , t : ty:: t , v0 : ValueRef , dtor_did : ast:: DefId ,
430
+ pub fn trans_struct_drop ( mut bcx : @mut Block , t : ty:: t , v0 : ValueRef , dtor_did : ast:: DefId ,
403
431
class_did : ast:: DefId , substs : & ty:: substs ) -> @mut Block {
404
432
let repr = adt:: represent_type ( bcx. ccx ( ) , t) ;
405
433
@@ -417,24 +445,19 @@ pub fn trans_struct_drop(bcx: @mut Block, t: ty::t, v0: ValueRef, dtor_did: ast:
417
445
// just consist of the environment (self)
418
446
assert_eq ! ( params. len( ) , 1 ) ;
419
447
420
- // Be sure to put all of the fields into a scope so we can use an invoke
421
- // instruction to call the user destructor but still call the field
422
- // destructors if the user destructor fails.
423
- do with_scope( bcx, None , "field drops" ) |bcx| {
424
- let self_arg = PointerCast ( bcx, v0, params[ 0 ] ) ;
425
- let args = ~[ self_arg] ;
448
+ let self_arg = PointerCast ( bcx, v0, params[ 0 ] ) ;
449
+ let args = ~[ self_arg] ;
426
450
427
- // Add all the fields as a value which needs to be cleaned at the end of
428
- // this scope.
429
- let field_tys = ty:: struct_fields ( bcx. tcx ( ) , class_did, substs) ;
430
- for ( i, fld) in field_tys. iter ( ) . enumerate ( ) {
431
- let llfld_a = adt:: trans_field_ptr ( bcx, repr, v0, 0 , i) ;
432
- add_clean ( bcx, llfld_a, fld. mt . ty ) ;
433
- }
451
+ Call ( bcx, dtor_addr, args, [ ] ) ;
434
452
435
- let ( _, bcx) = invoke ( bcx, dtor_addr, args, [ ] ) ;
436
- bcx
453
+ // Drop the fields
454
+ let field_tys = ty:: struct_fields ( bcx. tcx ( ) , class_did, substs) ;
455
+ for ( i, fld) in field_tys. iter ( ) . enumerate ( ) {
456
+ let llfld_a = adt:: trans_field_ptr ( bcx, repr, v0, 0 , i) ;
457
+ bcx = drop_ty ( bcx, llfld_a, fld. mt . ty ) ;
437
458
}
459
+
460
+ bcx
438
461
}
439
462
440
463
pub fn make_drop_glue ( bcx : @mut Block , v0 : ValueRef , t : ty:: t ) -> @mut Block {
0 commit comments