@@ -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- , 
386-            bcx. to_str( ) , 
399+     debug ! ( "trans_fn_ref_with_substs(def_id={}, node={}, \  
400+ , 
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+ ) 
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