@@ -38,6 +38,7 @@ use trans::cleanup::CleanupMethods;
38
38
use trans:: closure;
39
39
use trans:: common;
40
40
use trans:: common:: * ;
41
+ use trans:: consts;
41
42
use trans:: datum:: * ;
42
43
use trans:: expr;
43
44
use trans:: glue;
@@ -152,7 +153,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
152
153
_ => false
153
154
}
154
155
} => {
155
- let substs = node_id_substs ( bcx, ExprId ( ref_expr. id ) ) ;
156
+ let substs = node_id_substs ( bcx. ccx ( ) , ExprId ( ref_expr. id ) ,
157
+ bcx. fcx . param_substs ) ;
156
158
Callee {
157
159
bcx : bcx,
158
160
data : NamedTupleConstructor ( substs, 0 )
@@ -162,23 +164,28 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
162
164
ty:: ty_bare_fn( _, ref f) => f. abi == synabi:: RustIntrinsic ,
163
165
_ => false
164
166
} => {
165
- let substs = node_id_substs ( bcx, ExprId ( ref_expr. id ) ) ;
167
+ let substs = node_id_substs ( bcx. ccx ( ) , ExprId ( ref_expr. id ) ,
168
+ bcx. fcx . param_substs ) ;
166
169
let def_id = inline:: maybe_instantiate_inline ( bcx. ccx ( ) , did) ;
167
170
Callee { bcx : bcx, data : Intrinsic ( def_id. node , substs) }
168
171
}
169
172
def:: DefFn ( did, _) | def:: DefMethod ( did, _, def:: FromImpl ( _) ) |
170
173
def:: DefStaticMethod ( did, def:: FromImpl ( _) ) => {
171
- fn_callee ( bcx, trans_fn_ref ( bcx, did, ExprId ( ref_expr. id ) ) )
174
+ fn_callee ( bcx, trans_fn_ref ( bcx. ccx ( ) , did, ExprId ( ref_expr. id ) ,
175
+ bcx. fcx . param_substs ) . val )
172
176
}
173
177
def:: DefStaticMethod ( meth_did, def:: FromTrait ( trait_did) ) |
174
178
def:: DefMethod ( meth_did, _, def:: FromTrait ( trait_did) ) => {
175
- fn_callee ( bcx, meth:: trans_static_method_callee ( bcx, meth_did,
179
+ fn_callee ( bcx, meth:: trans_static_method_callee ( bcx. ccx ( ) ,
180
+ meth_did,
176
181
trait_did,
177
- ref_expr. id ) )
182
+ ref_expr. id ,
183
+ bcx. fcx . param_substs ) . val )
178
184
}
179
185
def:: DefVariant ( tid, vid, _) => {
180
186
let vinfo = ty:: enum_variant_with_id ( bcx. tcx ( ) , tid, vid) ;
181
- let substs = node_id_substs ( bcx, ExprId ( ref_expr. id ) ) ;
187
+ let substs = node_id_substs ( bcx. ccx ( ) , ExprId ( ref_expr. id ) ,
188
+ bcx. fcx . param_substs ) ;
182
189
183
190
// Nullary variants are not callable
184
191
assert ! ( vinfo. args. len( ) > 0 u) ;
@@ -189,7 +196,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
189
196
}
190
197
}
191
198
def:: DefStruct ( _) => {
192
- let substs = node_id_substs ( bcx, ExprId ( ref_expr. id ) ) ;
199
+ let substs = node_id_substs ( bcx. ccx ( ) , ExprId ( ref_expr. id ) ,
200
+ bcx. fcx . param_substs ) ;
193
201
Callee {
194
202
bcx : bcx,
195
203
data : NamedTupleConstructor ( substs, 0 )
@@ -217,15 +225,19 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
217
225
218
226
/// Translates a reference (with id `ref_id`) to the fn/method with id `def_id` into a function
219
227
/// pointer. This may require monomorphization or inlining.
220
- pub fn trans_fn_ref ( bcx : Block , def_id : ast:: DefId , node : ExprOrMethodCall ) -> ValueRef {
228
+ pub fn trans_fn_ref < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ,
229
+ def_id : ast:: DefId ,
230
+ node : ExprOrMethodCall ,
231
+ param_substs : & subst:: Substs < ' tcx > )
232
+ -> Datum < ' tcx , Rvalue > {
221
233
let _icx = push_ctxt ( "trans_fn_ref" ) ;
222
234
223
- let substs = node_id_substs ( bcx , node) ;
235
+ let substs = node_id_substs ( ccx , node, param_substs ) ;
224
236
debug ! ( "trans_fn_ref(def_id={}, node={}, substs={})" ,
225
- def_id. repr( bcx . tcx( ) ) ,
237
+ def_id. repr( ccx . tcx( ) ) ,
226
238
node,
227
- substs. repr( bcx . tcx( ) ) ) ;
228
- trans_fn_ref_with_substs ( bcx , def_id, node, substs)
239
+ substs. repr( ccx . tcx( ) ) ) ;
240
+ trans_fn_ref_with_substs ( ccx , def_id, node, param_substs , substs)
229
241
}
230
242
231
243
fn trans_fn_ref_with_substs_to_callee < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
@@ -235,10 +247,11 @@ fn trans_fn_ref_with_substs_to_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
235
247
-> Callee < ' blk , ' tcx > {
236
248
Callee {
237
249
bcx : bcx,
238
- data : Fn ( trans_fn_ref_with_substs ( bcx,
250
+ data : Fn ( trans_fn_ref_with_substs ( bcx. ccx ( ) ,
239
251
def_id,
240
252
ExprId ( ref_id) ,
241
- substs) ) ,
253
+ bcx. fcx . param_substs ,
254
+ substs) . val ) ,
242
255
}
243
256
}
244
257
@@ -364,28 +377,30 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
364
377
///
365
378
/// # Parameters
366
379
///
367
- /// - `bcx `: the current block where the reference to the fn occurs
380
+ /// - `ccx `: the crate context
368
381
/// - `def_id`: def id of the fn or method item being referenced
369
382
/// - `node`: node id of the reference to the fn/method, if applicable.
370
383
/// This parameter may be zero; but, if so, the resulting value may not
371
384
/// have the right type, so it must be cast before being used.
385
+ /// - `param_substs`: if the `node` is in a polymorphic function, these
386
+ /// are the substitutions required to monomorphize its type
372
387
/// - `substs`: values for each of the fn/method's parameters
373
- pub fn trans_fn_ref_with_substs < ' blk , ' tcx > (
374
- bcx : Block < ' blk , ' tcx > , //
375
- def_id : ast:: DefId , // def id of fn
376
- node : ExprOrMethodCall , // node id of use of fn; may be zero if N/A
377
- substs : subst:: Substs < ' tcx > ) // vtables for the call
378
- -> ValueRef
388
+ pub fn trans_fn_ref_with_substs < ' a , ' tcx > (
389
+ ccx : & CrateContext < ' a , ' tcx > ,
390
+ def_id : ast:: DefId ,
391
+ node : ExprOrMethodCall ,
392
+ param_substs : & subst:: Substs < ' tcx > ,
393
+ substs : subst:: Substs < ' tcx > )
394
+ -> Datum < ' tcx , Rvalue >
379
395
{
380
396
let _icx = push_ctxt ( "trans_fn_ref_with_substs" ) ;
381
- let ccx = bcx. ccx ( ) ;
382
- let tcx = bcx. tcx ( ) ;
397
+ let tcx = ccx. tcx ( ) ;
383
398
384
- debug ! ( "trans_fn_ref_with_substs(bcx={}, def_id={}, node={}, \
385
- substs={})",
386
- bcx. to_str( ) ,
399
+ debug ! ( "trans_fn_ref_with_substs(def_id={}, node={}, \
400
+ param_substs={}, substs={})",
387
401
def_id. repr( tcx) ,
388
402
node,
403
+ param_substs. repr( tcx) ,
389
404
substs. repr( tcx) ) ;
390
405
391
406
assert ! ( substs. types. all( |t| !ty:: type_needs_infer( * t) ) ) ;
@@ -443,15 +458,15 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
443
458
( true , source_id, new_substs)
444
459
}
445
460
ty:: TypeTraitItem ( _) => {
446
- bcx . tcx ( ) . sess . bug ( "trans_fn_ref_with_vtables() tried \
447
- to translate an associated type?!")
461
+ tcx. sess . bug ( "trans_fn_ref_with_vtables() tried \
462
+ to translate an associated type?!")
448
463
}
449
464
}
450
465
}
451
466
} ;
452
467
453
468
// If this is an unboxed closure, redirect to it.
454
- match closure:: get_or_create_declaration_if_unboxed_closure ( bcx ,
469
+ match closure:: get_or_create_declaration_if_unboxed_closure ( ccx ,
455
470
def_id,
456
471
& substs) {
457
472
None => { }
@@ -494,24 +509,27 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
494
509
MethodCallKey ( _) => None ,
495
510
} ;
496
511
497
- let ( val, must_cast) =
512
+ let ( val, fn_ty , must_cast) =
498
513
monomorphize:: monomorphic_fn ( ccx, def_id, & substs, opt_ref_id) ;
499
- let mut val = val;
500
514
if must_cast && node != ExprId ( 0 ) {
501
515
// Monotype of the REFERENCE to the function (type params
502
516
// are subst'd)
503
517
let ref_ty = match node {
504
- ExprId ( id) => node_id_type ( bcx , id) ,
518
+ ExprId ( id) => ty :: node_id_to_type ( tcx , id) ,
505
519
MethodCallKey ( method_call) => {
506
- let t = ( * bcx. tcx ( ) . method_map . borrow ( ) ) [ method_call] . ty ;
507
- monomorphize_type ( bcx, t)
520
+ ( * tcx. method_map . borrow ( ) ) [ method_call] . ty
508
521
}
509
522
} ;
510
-
511
- val = PointerCast (
512
- bcx, val, type_of:: type_of_fn_from_ty ( ccx, ref_ty) . ptr_to ( ) ) ;
523
+ let ref_ty = monomorphize:: apply_param_substs ( tcx,
524
+ param_substs,
525
+ & ref_ty) ;
526
+ let llptrty = type_of:: type_of_fn_from_ty ( ccx, ref_ty) . ptr_to ( ) ;
527
+ if llptrty != val_ty ( val) {
528
+ let val = consts:: ptrcast ( val, llptrty) ;
529
+ return Datum :: new ( val, ref_ty, Rvalue :: new ( ByValue ) ) ;
530
+ }
513
531
}
514
- return val;
532
+ return Datum :: new ( val, fn_ty , Rvalue :: new ( ByValue ) ) ;
515
533
}
516
534
517
535
// Type scheme of the function item (may have type params)
@@ -556,12 +574,12 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
556
574
let llptrty = llty. ptr_to ( ) ;
557
575
if val_ty ( val) != llptrty {
558
576
debug ! ( "trans_fn_ref_with_vtables(): casting pointer!" ) ;
559
- val = BitCast ( bcx , val, llptrty) ;
577
+ val = consts :: ptrcast ( val, llptrty) ;
560
578
} else {
561
579
debug ! ( "trans_fn_ref_with_vtables(): not casting pointer!" ) ;
562
580
}
563
581
564
- val
582
+ Datum :: new ( val, fn_type , Rvalue :: new ( ByValue ) )
565
583
}
566
584
567
585
// ______________________________________________________________________
0 commit comments