@@ -40,6 +40,7 @@ use middle::trans::expr;
4040use middle:: trans:: glue;
4141use middle:: trans:: inline;
4242use middle:: trans:: foreign;
43+ use middle:: trans:: intrinsic;
4344use middle:: trans:: meth;
4445use middle:: trans:: monomorphize;
4546use middle:: trans:: type_:: Type ;
@@ -68,6 +69,8 @@ pub enum CalleeData {
6869 // value (which is a pair).
6970 Fn ( /* llfn */ ValueRef ) ,
7071
72+ Intrinsic ( ast:: NodeId , subst:: Substs ) ,
73+
7174 TraitMethod ( MethodData )
7275}
7376
@@ -119,7 +122,21 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
119122
120123 fn trans_def < ' a > ( bcx : & ' a Block < ' a > , def : def:: Def , ref_expr : & ast:: Expr )
121124 -> Callee < ' a > {
125+ debug ! ( "trans_def(def={}, ref_expr={})" , def. repr( bcx. tcx( ) ) , ref_expr. repr( bcx. tcx( ) ) ) ;
126+ let expr_ty = node_id_type ( bcx, ref_expr. id ) ;
122127 match def {
128+ def:: DefFn ( did, _) if match ty:: get ( expr_ty) . sty {
129+ ty:: ty_bare_fn( ref f) => f. abi == synabi:: RustIntrinsic ,
130+ _ => false
131+ } => {
132+ let substs = node_id_substs ( bcx, ExprId ( ref_expr. id ) ) ;
133+ let def_id = if did. krate != ast:: LOCAL_CRATE {
134+ inline:: maybe_instantiate_inline ( bcx. ccx ( ) , did)
135+ } else {
136+ did
137+ } ;
138+ Callee { bcx : bcx, data : Intrinsic ( def_id. node , substs) }
139+ }
123140 def:: DefFn ( did, _) |
124141 def:: DefStaticMethod ( did, def:: FromImpl ( _) , _) => {
125142 fn_callee ( bcx, trans_fn_ref ( bcx, did, ExprId ( ref_expr. id ) ) )
@@ -662,6 +679,12 @@ pub fn trans_call_inner<'a>(
662679 let callee = get_callee ( bcx, cleanup:: CustomScope ( arg_cleanup_scope) ) ;
663680 let mut bcx = callee. bcx ;
664681
682+ let ( abi, ret_ty) = match ty:: get ( callee_ty) . sty {
683+ ty:: ty_bare_fn( ref f) => ( f. abi , f. sig . output ) ,
684+ ty:: ty_closure( ref f) => ( synabi:: Rust , f. sig . output ) ,
685+ _ => fail ! ( "expected bare rust fn or closure in trans_call_inner" )
686+ } ;
687+
665688 let ( llfn, llenv, llself) = match callee. data {
666689 Fn ( llfn) => {
667690 ( llfn, None , None )
@@ -679,14 +702,15 @@ pub fn trans_call_inner<'a>(
679702 let llenv = Load ( bcx, llenv) ;
680703 ( llfn, Some ( llenv) , None )
681704 }
682- } ;
705+ Intrinsic ( node, substs) => {
706+ assert ! ( abi == synabi:: RustIntrinsic ) ;
707+ assert ! ( dest. is_some( ) ) ;
683708
684- let ( abi , ret_ty ) = match ty :: get ( callee_ty ) . sty {
685- ty :: ty_bare_fn ( ref f ) => ( f . abi , f . sig . output ) ,
686- ty :: ty_closure ( ref f ) => ( synabi :: Rust , f . sig . output ) ,
687- _ => fail ! ( "expected bare rust fn or closure in trans_call_inner" )
709+ return intrinsic :: trans_intrinsic_call ( bcx , node , callee_ty ,
710+ arg_cleanup_scope , args ,
711+ dest . unwrap ( ) , substs ) ;
712+ }
688713 } ;
689- let is_rust_fn = abi == synabi:: Rust || abi == synabi:: RustIntrinsic ;
690714
691715 // Generate a location to store the result. If the user does
692716 // not care about the result, just make a stack slot.
@@ -716,7 +740,7 @@ pub fn trans_call_inner<'a>(
716740 // and done, either the return value of the function will have been
717741 // written in opt_llretslot (if it is Some) or `llresult` will be
718742 // set appropriately (otherwise).
719- if is_rust_fn {
743+ if abi == synabi :: Rust {
720744 let mut llargs = Vec :: new ( ) ;
721745
722746 // Push the out-pointer if we use an out-pointer for this
@@ -816,13 +840,13 @@ pub enum CallArgs<'a> {
816840 ArgOverloadedOp ( Datum < Expr > , Option < ( Datum < Expr > , ast:: NodeId ) > ) ,
817841}
818842
819- fn trans_args < ' a > ( cx : & ' a Block < ' a > ,
820- args : CallArgs ,
821- fn_ty : ty:: t ,
822- llargs : & mut Vec < ValueRef > ,
823- arg_cleanup_scope : cleanup:: ScopeId ,
824- ignore_self : bool )
825- -> & ' a Block < ' a > {
843+ pub fn trans_args < ' a > ( cx : & ' a Block < ' a > ,
844+ args : CallArgs ,
845+ fn_ty : ty:: t ,
846+ llargs : & mut Vec < ValueRef > ,
847+ arg_cleanup_scope : cleanup:: ScopeId ,
848+ ignore_self : bool )
849+ -> & ' a Block < ' a > {
826850 let _icx = push_ctxt ( "trans_args" ) ;
827851 let arg_tys = ty:: ty_fn_args ( fn_ty) ;
828852 let variadic = ty:: fn_is_variadic ( fn_ty) ;
0 commit comments