@@ -38,6 +38,7 @@ use trans::cleanup::CleanupMethods;
3838use trans:: closure;
3939use trans:: common;
4040use trans:: common:: * ;
41+ use trans:: consts;
4142use trans:: datum:: * ;
4243use trans:: expr;
4344use trans:: glue;
@@ -152,7 +153,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
152153 _ => false
153154 }
154155 } => {
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 ) ;
156158 Callee {
157159 bcx : bcx,
158160 data : NamedTupleConstructor ( substs, 0 )
@@ -162,23 +164,28 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
162164 ty:: ty_bare_fn( _, ref f) => f. abi == synabi:: RustIntrinsic ,
163165 _ => false
164166 } => {
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 ) ;
166169 let def_id = inline:: maybe_instantiate_inline ( bcx. ccx ( ) , did) ;
167170 Callee { bcx : bcx, data : Intrinsic ( def_id. node , substs) }
168171 }
169172 def:: DefFn ( did, _) | def:: DefMethod ( did, _, def:: FromImpl ( _) ) |
170173 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 )
172176 }
173177 def:: DefStaticMethod ( meth_did, def:: FromTrait ( trait_did) ) |
174178 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,
176181 trait_did,
177- ref_expr. id ) )
182+ ref_expr. id ,
183+ bcx. fcx . param_substs ) . val )
178184 }
179185 def:: DefVariant ( tid, vid, _) => {
180186 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 ) ;
182189
183190 // Nullary variants are not callable
184191 assert ! ( vinfo. args. len( ) > 0 u) ;
@@ -189,7 +196,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
189196 }
190197 }
191198 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 ) ;
193201 Callee {
194202 bcx : bcx,
195203 data : NamedTupleConstructor ( substs, 0 )
@@ -217,15 +225,19 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
217225
218226/// Translates a reference (with id `ref_id`) to the fn/method with id `def_id` into a function
219227/// 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 > {
221233 let _icx = push_ctxt ( "trans_fn_ref" ) ;
222234
223- let substs = node_id_substs ( bcx , node) ;
235+ let substs = node_id_substs ( ccx , node, param_substs ) ;
224236 debug ! ( "trans_fn_ref(def_id={}, node={}, substs={})" ,
225- def_id. repr( bcx . tcx( ) ) ,
237+ def_id. repr( ccx . tcx( ) ) ,
226238 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)
229241}
230242
231243fn 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>,
235247 -> Callee < ' blk , ' tcx > {
236248 Callee {
237249 bcx : bcx,
238- data : Fn ( trans_fn_ref_with_substs ( bcx,
250+ data : Fn ( trans_fn_ref_with_substs ( bcx. ccx ( ) ,
239251 def_id,
240252 ExprId ( ref_id) ,
241- substs) ) ,
253+ bcx. fcx . param_substs ,
254+ substs) . val ) ,
242255 }
243256}
244257
@@ -364,28 +377,30 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
364377///
365378/// # Parameters
366379///
367- /// - `bcx `: the current block where the reference to the fn occurs
380+ /// - `ccx `: the crate context
368381/// - `def_id`: def id of the fn or method item being referenced
369382/// - `node`: node id of the reference to the fn/method, if applicable.
370383/// This parameter may be zero; but, if so, the resulting value may not
371384/// 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
372387/// - `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 >
379395{
380396 let _icx = push_ctxt ( "trans_fn_ref_with_substs" ) ;
381- let ccx = bcx. ccx ( ) ;
382- let tcx = bcx. tcx ( ) ;
397+ let tcx = ccx. tcx ( ) ;
383398
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={})",
387401 def_id. repr( tcx) ,
388402 node,
403+ param_substs. repr( tcx) ,
389404 substs. repr( tcx) ) ;
390405
391406 assert ! ( substs. types. all( |t| !ty:: type_needs_infer( * t) ) ) ;
@@ -443,15 +458,15 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
443458 ( true , source_id, new_substs)
444459 }
445460 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?!")
448463 }
449464 }
450465 }
451466 } ;
452467
453468 // 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 ,
455470 def_id,
456471 & substs) {
457472 None => { }
@@ -494,24 +509,27 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
494509 MethodCallKey ( _) => None ,
495510 } ;
496511
497- let ( val, must_cast) =
512+ let ( val, fn_ty , must_cast) =
498513 monomorphize:: monomorphic_fn ( ccx, def_id, & substs, opt_ref_id) ;
499- let mut val = val;
500514 if must_cast && node != ExprId ( 0 ) {
501515 // Monotype of the REFERENCE to the function (type params
502516 // are subst'd)
503517 let ref_ty = match node {
504- ExprId ( id) => node_id_type ( bcx , id) ,
518+ ExprId ( id) => ty :: node_id_to_type ( tcx , id) ,
505519 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
508521 }
509522 } ;
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+ }
513531 }
514- return val;
532+ return Datum :: new ( val, fn_ty , Rvalue :: new ( ByValue ) ) ;
515533 }
516534
517535 // Type scheme of the function item (may have type params)
@@ -556,12 +574,12 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
556574 let llptrty = llty. ptr_to ( ) ;
557575 if val_ty ( val) != llptrty {
558576 debug ! ( "trans_fn_ref_with_vtables(): casting pointer!" ) ;
559- val = BitCast ( bcx , val, llptrty) ;
577+ val = consts :: ptrcast ( val, llptrty) ;
560578 } else {
561579 debug ! ( "trans_fn_ref_with_vtables(): not casting pointer!" ) ;
562580 }
563581
564- val
582+ Datum :: new ( val, fn_type , Rvalue :: new ( ByValue ) )
565583}
566584
567585// ______________________________________________________________________
0 commit comments