@@ -40,6 +40,7 @@ use middle::trans::expr;
40
40
use middle:: trans:: glue;
41
41
use middle:: trans:: inline;
42
42
use middle:: trans:: foreign;
43
+ use middle:: trans:: intrinsic;
43
44
use middle:: trans:: meth;
44
45
use middle:: trans:: monomorphize;
45
46
use middle:: trans:: type_:: Type ;
@@ -68,6 +69,8 @@ pub enum CalleeData {
68
69
// value (which is a pair).
69
70
Fn ( /* llfn */ ValueRef ) ,
70
71
72
+ Intrinsic ( ast:: NodeId , subst:: Substs ) ,
73
+
71
74
TraitMethod ( MethodData )
72
75
}
73
76
@@ -119,7 +122,21 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
119
122
120
123
fn trans_def < ' a > ( bcx : & ' a Block < ' a > , def : def:: Def , ref_expr : & ast:: Expr )
121
124
-> 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 ) ;
122
127
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
+ }
123
140
def:: DefFn ( did, _) |
124
141
def:: DefStaticMethod ( did, def:: FromImpl ( _) , _) => {
125
142
fn_callee ( bcx, trans_fn_ref ( bcx, did, ExprId ( ref_expr. id ) ) )
@@ -662,6 +679,12 @@ pub fn trans_call_inner<'a>(
662
679
let callee = get_callee ( bcx, cleanup:: CustomScope ( arg_cleanup_scope) ) ;
663
680
let mut bcx = callee. bcx ;
664
681
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
+
665
688
let ( llfn, llenv, llself) = match callee. data {
666
689
Fn ( llfn) => {
667
690
( llfn, None , None )
@@ -679,14 +702,15 @@ pub fn trans_call_inner<'a>(
679
702
let llenv = Load ( bcx, llenv) ;
680
703
( llfn, Some ( llenv) , None )
681
704
}
682
- } ;
705
+ Intrinsic ( node, substs) => {
706
+ assert ! ( abi == synabi:: RustIntrinsic ) ;
707
+ assert ! ( dest. is_some( ) ) ;
683
708
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
+ }
688
713
} ;
689
- let is_rust_fn = abi == synabi:: Rust || abi == synabi:: RustIntrinsic ;
690
714
691
715
// Generate a location to store the result. If the user does
692
716
// not care about the result, just make a stack slot.
@@ -716,7 +740,7 @@ pub fn trans_call_inner<'a>(
716
740
// and done, either the return value of the function will have been
717
741
// written in opt_llretslot (if it is Some) or `llresult` will be
718
742
// set appropriately (otherwise).
719
- if is_rust_fn {
743
+ if abi == synabi :: Rust {
720
744
let mut llargs = Vec :: new ( ) ;
721
745
722
746
// Push the out-pointer if we use an out-pointer for this
@@ -816,13 +840,13 @@ pub enum CallArgs<'a> {
816
840
ArgOverloadedOp ( Datum < Expr > , Option < ( Datum < Expr > , ast:: NodeId ) > ) ,
817
841
}
818
842
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 > {
826
850
let _icx = push_ctxt ( "trans_args" ) ;
827
851
let arg_tys = ty:: ty_fn_args ( fn_ty) ;
828
852
let variadic = ty:: fn_is_variadic ( fn_ty) ;
0 commit comments