16
16
use back:: link:: * ;
17
17
use llvm;
18
18
use llvm:: { ValueRef , get_param} ;
19
- use metadata:: csearch;
20
- use middle:: def_id:: { DefId , LOCAL_CRATE } ;
21
19
use middle:: lang_items:: ExchangeFreeFnLangItem ;
22
- use middle:: subst;
23
- use middle:: subst :: { Subst , Substs } ;
20
+ use middle:: subst:: { Substs } ;
21
+ use middle:: traits ;
24
22
use middle:: ty:: { self , Ty } ;
25
23
use trans:: adt;
26
24
use trans:: adt:: GetDtorType ; // for tcx.dtor_type()
@@ -33,16 +31,15 @@ use trans::common::*;
33
31
use trans:: debuginfo:: DebugLoc ;
34
32
use trans:: declare;
35
33
use trans:: expr;
36
- use trans:: foreign;
37
- use trans:: inline;
38
34
use trans:: machine:: * ;
39
35
use trans:: monomorphize;
40
- use trans:: type_of:: { type_of, type_of_dtor , sizing_type_of, align_of} ;
36
+ use trans:: type_of:: { type_of, sizing_type_of, align_of} ;
41
37
use trans:: type_:: Type ;
42
38
43
39
use arena:: TypedArena ;
44
40
use libc:: c_uint;
45
41
use syntax:: ast;
42
+ use syntax:: codemap:: DUMMY_SP ;
46
43
47
44
pub fn trans_exchange_free_dyn < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > ,
48
45
v : ValueRef ,
@@ -287,10 +284,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
287
284
288
285
fn trans_struct_drop_flag < ' blk , ' tcx > ( mut bcx : Block < ' blk , ' tcx > ,
289
286
t : Ty < ' tcx > ,
290
- struct_data : ValueRef ,
291
- dtor_did : DefId ,
292
- class_did : DefId ,
293
- substs : & subst:: Substs < ' tcx > )
287
+ struct_data : ValueRef )
294
288
-> Block < ' blk , ' tcx > {
295
289
assert ! ( type_is_sized( bcx. tcx( ) , t) , "Precondition: caller must ensure t is sized" ) ;
296
290
@@ -318,59 +312,19 @@ fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
318
312
319
313
let drop_flag_dtor_needed = ICmp ( bcx, llvm:: IntEQ , loaded, init_val, DebugLoc :: None ) ;
320
314
with_cond ( bcx, drop_flag_dtor_needed, |cx| {
321
- trans_struct_drop ( cx, t, struct_data, dtor_did , class_did , substs )
315
+ trans_struct_drop ( cx, t, struct_data)
322
316
} )
323
317
}
324
-
325
- pub fn get_res_dtor < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
326
- did : DefId ,
327
- parent_id : DefId ,
328
- substs : & Substs < ' tcx > )
329
- -> ValueRef {
330
- let _icx = push_ctxt ( "trans_res_dtor" ) ;
331
- let did = inline:: maybe_instantiate_inline ( ccx, did) ;
332
-
333
- if !substs. types . is_empty ( ) {
334
- assert_eq ! ( did. krate, LOCAL_CRATE ) ;
335
-
336
- // Since we're in trans we don't care for any region parameters
337
- let substs = ccx. tcx ( ) . mk_substs ( Substs :: erased ( substs. types . clone ( ) ) ) ;
338
-
339
- let ( val, _, _) = monomorphize:: monomorphic_fn ( ccx, did, substs, None ) ;
340
-
341
- val
342
- } else if did. is_local ( ) {
343
- get_item_val ( ccx, did. node )
344
- } else {
345
- let tcx = ccx. tcx ( ) ;
346
- let name = csearch:: get_symbol ( & ccx. sess ( ) . cstore , did) ;
347
- let class_ty = tcx. lookup_item_type ( parent_id) . ty . subst ( tcx, substs) ;
348
- let llty = type_of_dtor ( ccx, class_ty) ;
349
- foreign:: get_extern_fn ( ccx, & mut * ccx. externs ( ) . borrow_mut ( ) , & name[ ..] , llvm:: CCallConv ,
350
- llty, ccx. tcx ( ) . mk_nil ( ) )
351
- }
352
- }
353
-
354
318
fn trans_struct_drop < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
355
319
t : Ty < ' tcx > ,
356
- v0 : ValueRef ,
357
- dtor_did : DefId ,
358
- class_did : DefId ,
359
- substs : & subst:: Substs < ' tcx > )
320
+ v0 : ValueRef )
360
321
-> Block < ' blk , ' tcx >
361
322
{
362
323
debug ! ( "trans_struct_drop t: {}" , t) ;
324
+ let tcx = bcx. tcx ( ) ;
325
+ let mut bcx = bcx;
363
326
364
- // Find and call the actual destructor
365
- let dtor_addr = get_res_dtor ( bcx. ccx ( ) , dtor_did, class_did, substs) ;
366
-
367
- // Class dtors have no explicit args, so the params should
368
- // just consist of the environment (self).
369
- let params = unsafe {
370
- let ty = Type :: from_ref ( llvm:: LLVMTypeOf ( dtor_addr) ) ;
371
- ty. element_type ( ) . func_params ( )
372
- } ;
373
- assert_eq ! ( params. len( ) , if type_is_sized( bcx. tcx( ) , t) { 1 } else { 2 } ) ;
327
+ let def = t. ty_adt_def ( ) . unwrap ( ) ;
374
328
375
329
// Be sure to put the contents into a scope so we can use an invoke
376
330
// instruction to call the user destructor but still call the field
@@ -384,15 +338,37 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
384
338
// discriminant (if any) in case of variant swap in drop code.
385
339
bcx. fcx . schedule_drop_adt_contents ( cleanup:: CustomScope ( contents_scope) , v0, t) ;
386
340
387
- let glue_type = get_drop_glue_type ( bcx . ccx ( ) , t ) ;
388
- let dtor_ty = bcx . tcx ( ) . mk_ctor_fn ( class_did , & [ glue_type ] , bcx . tcx ( ) . mk_nil ( ) ) ;
389
- let ( _ , bcx ) = if type_is_sized ( bcx . tcx ( ) , t ) {
390
- invoke ( bcx , dtor_addr , & [ v0 ] , dtor_ty , DebugLoc :: None )
341
+ let ( sized_args , unsized_args ) ;
342
+ let args : & [ ValueRef ] = if type_is_sized ( tcx , t ) {
343
+ sized_args = [ v0 ] ;
344
+ & sized_args
391
345
} else {
392
- let args = [ Load ( bcx, expr:: get_dataptr ( bcx, v0) ) , Load ( bcx, expr:: get_meta ( bcx, v0) ) ] ;
393
- invoke ( bcx , dtor_addr , & args , dtor_ty , DebugLoc :: None )
346
+ unsized_args = [ Load ( bcx, expr:: get_dataptr ( bcx, v0) ) , Load ( bcx, expr:: get_meta ( bcx, v0) ) ] ;
347
+ & unsized_args
394
348
} ;
395
349
350
+ bcx = callee:: trans_call_inner ( bcx, DebugLoc :: None , |bcx, _| {
351
+ let trait_ref = ty:: Binder ( ty:: TraitRef {
352
+ def_id : tcx. lang_items . drop_trait ( ) . unwrap ( ) ,
353
+ substs : tcx. mk_substs ( Substs :: trans_empty ( ) . with_self_ty ( t) )
354
+ } ) ;
355
+ let vtbl = match fulfill_obligation ( bcx. ccx ( ) , DUMMY_SP , trait_ref) {
356
+ traits:: VtableImpl ( data) => data,
357
+ _ => tcx. sess . bug ( & format ! ( "dtor for {:?} is not an impl???" , t) )
358
+ } ;
359
+ let dtor_did = tcx. destructor_for_type . borrow ( ) [ & def. did ] ;
360
+ let datum = callee:: trans_fn_ref_with_substs ( bcx. ccx ( ) ,
361
+ dtor_did,
362
+ ExprId ( 0 ) ,
363
+ bcx. fcx . param_substs ,
364
+ vtbl. substs ) ;
365
+ callee:: Callee {
366
+ bcx : bcx,
367
+ data : callee:: Fn ( datum. val ) ,
368
+ ty : datum. ty
369
+ }
370
+ } , callee:: ArgVals ( args) , Some ( expr:: Ignore ) ) . bcx ;
371
+
396
372
bcx. fcx . pop_and_trans_custom_cleanup_scope ( bcx, contents_scope)
397
373
}
398
374
@@ -557,27 +533,27 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
557
533
} )
558
534
}
559
535
}
560
- ty:: TyStruct ( def, substs ) | ty:: TyEnum ( def, substs ) => {
536
+ ty:: TyStruct ( def, _ ) | ty:: TyEnum ( def, _ ) => {
561
537
let tcx = bcx. tcx ( ) ;
562
538
match ( tcx. ty_dtor ( def. did ) , skip_dtor) {
563
- ( ty:: TraitDtor ( dtor , true ) , false ) => {
539
+ ( ty:: TraitDtor ( _ , true ) , false ) => {
564
540
// FIXME(16758) Since the struct is unsized, it is hard to
565
541
// find the drop flag (which is at the end of the struct).
566
542
// Lets just ignore the flag and pretend everything will be
567
543
// OK.
568
544
if type_is_sized ( bcx. tcx ( ) , t) {
569
- trans_struct_drop_flag ( bcx, t, v0, dtor , def . did , substs )
545
+ trans_struct_drop_flag ( bcx, t, v0)
570
546
} else {
571
547
// Give the user a heads up that we are doing something
572
548
// stupid and dangerous.
573
549
bcx. sess ( ) . warn ( & format ! ( "Ignoring drop flag in destructor for {}\
574
550
because the struct is unsized. See issue\
575
551
#16758", t) ) ;
576
- trans_struct_drop ( bcx, t, v0, dtor , def . did , substs )
552
+ trans_struct_drop ( bcx, t, v0)
577
553
}
578
554
}
579
- ( ty:: TraitDtor ( dtor , false ) , false ) => {
580
- trans_struct_drop ( bcx, t, v0, dtor , def . did , substs )
555
+ ( ty:: TraitDtor ( _ , false ) , false ) => {
556
+ trans_struct_drop ( bcx, t, v0)
581
557
}
582
558
( ty:: NoDtor , _) | ( _, true ) => {
583
559
// No dtor? Just the default case
0 commit comments