about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2012-01-02 12:00:40 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2012-01-02 15:15:27 +0100
commit270b4273e79aac33f424673caf455f839da2bb40 (patch)
treea2f896c6c28ee2fa1e6eb6adf6413a5b593de099 /src/comp
parent664a0443ade2ecc969d39d5ca3f18387b94af5b4 (diff)
downloadrust-270b4273e79aac33f424673caf455f839da2bb40.tar.gz
rust-270b4273e79aac33f424673caf455f839da2bb40.zip
Pass bounds to trans::type_of_fn
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs63
-rw-r--r--src/comp/middle/trans_closure.rs23
-rw-r--r--src/comp/middle/trans_common.rs4
-rw-r--r--src/comp/middle/trans_objects.rs8
-rw-r--r--src/comp/middle/ty.rs12
-rw-r--r--src/comp/middle/typeck.rs5
6 files changed, 65 insertions, 50 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index c843f6e524d..9e85d02a648 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -83,7 +83,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
 //  - trans_args
 fn type_of_fn(cx: @crate_ctxt, sp: span,
               is_method: bool, inputs: [ty::arg],
-              output: ty::t, ty_param_count: uint)
+              output: ty::t, params: [ty::param_bounds])
    : non_ty_var(cx, output) -> TypeRef {
     let atys: [TypeRef] = [];
 
@@ -100,8 +100,10 @@ fn type_of_fn(cx: @crate_ctxt, sp: span,
 
     // Args >2: ty params, if not acquired via capture...
     if !is_method {
-        let i = 0u;
-        while i < ty_param_count { atys += [T_ptr(cx.tydesc_type)]; i += 1u; }
+        // FIXME[impl] Also add args for the dicts
+        for _param in params {
+            atys += [T_ptr(cx.tydesc_type)];
+        }
     }
     // ... then explicit args.
     atys += type_of_explicit_args(cx, sp, inputs);
@@ -110,7 +112,7 @@ fn type_of_fn(cx: @crate_ctxt, sp: span,
 
 // Given a function type and a count of ty params, construct an llvm type
 fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
-                      ty_param_count: uint)
+                      param_bounds: [ty::param_bounds])
     : returns_non_ty_var(cx, fty) -> TypeRef {
     // FIXME: Check should be unnecessary, b/c it's implied
     // by returns_non_ty_var(t). Make that a postcondition
@@ -118,7 +120,7 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
     let ret_ty = ty::ty_fn_ret(cx.tcx, fty);
     check non_ty_var(cx, ret_ty);
     ret type_of_fn(cx, sp, false, ty::ty_fn_args(cx.tcx, fty),
-                   ret_ty, ty_param_count);
+                   ret_ty, param_bounds);
 }
 
 fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
@@ -171,10 +173,10 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
       ty::ty_fn(_) {
         // FIXME: could be a constraint on ty_fn
         check returns_non_ty_var(cx, t);
-        T_fn_pair(cx, type_of_fn_from_ty(cx, sp, t, 0u))
+        T_fn_pair(cx, type_of_fn_from_ty(cx, sp, t, []))
       }
       ty::ty_native_fn(args, out) {
-        let nft = native_fn_wrapper_type(cx, sp, 0u, t);
+        let nft = native_fn_wrapper_type(cx, sp, [], t);
         T_fn_pair(cx, nft)
       }
       ty::ty_obj(meths) { cx.rust_object_type }
@@ -234,7 +236,7 @@ fn type_of_ty_param_bounds_and_ty(lcx: @local_ctxt, sp: span,
     alt ty::struct(cx.tcx, t) {
       ty::ty_fn(_) | ty::ty_native_fn(_, _) {
         check returns_non_ty_var(cx, t);
-        ret type_of_fn_from_ty(cx, sp, t, vec::len(tpt.bounds));
+        ret type_of_fn_from_ty(cx, sp, t, tpt.bounds);
       }
       _ {
         // fall through
@@ -2562,7 +2564,8 @@ fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
 type generic_info =
     {item_type: ty::t,
      static_tis: [option::t<@tydesc_info>],
-     tydescs: [ValueRef]};
+     tydescs: [ValueRef],
+     param_bounds: [ty::param_bounds]};
 
 tag lval_kind {
     temporary; //< Temporary value passed by value if of immediate type
@@ -2608,18 +2611,19 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
 
 fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
     -> lval_maybe_callee {
-    let tpt = ty::lookup_item_type(bcx_tcx(bcx), fn_id);
+    let ccx = bcx_ccx(bcx);
+    let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
     let val = if fn_id.crate == ast::local_crate {
         // Internal reference.
-        assert (bcx_ccx(bcx).item_ids.contains_key(fn_id.node));
-        bcx_ccx(bcx).item_ids.get(fn_id.node)
+        assert (ccx.item_ids.contains_key(fn_id.node));
+        ccx.item_ids.get(fn_id.node)
     } else {
         // External reference.
         trans_external_path(bcx, fn_id, tpt)
     };
-    let tys = ty::node_id_to_type_params(bcx_tcx(bcx), id);
+    let tys = ty::node_id_to_type_params(ccx.tcx, id);
     let gen = none, bcx = bcx;
-    if vec::len::<ty::t>(tys) != 0u {
+    if vec::len(tys) != 0u {
         let tydescs = [], tis = [];
         for t in tys {
             // TODO: Doesn't always escape.
@@ -2629,7 +2633,11 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
             bcx = td.bcx;
             tydescs += [td.val];
         }
-        gen = some({item_type: tpt.ty, static_tis: tis, tydescs: tydescs});
+        let bounds = ty::lookup_item_type(ccx.tcx, fn_id).bounds;
+        gen = some({item_type: tpt.ty,
+                    static_tis: tis,
+                    tydescs: tydescs,
+                    param_bounds: bounds});
     }
     ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen};
 }
@@ -2767,7 +2775,7 @@ fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef,
     check non_ty_var(ccx, ret_ty);
 
     let ll_fn_ty = type_of_fn(ccx, bcx.sp, true,
-                              ty::ty_fn_args(tcx, fn_ty), ret_ty, 0u);
+                              ty::ty_fn_args(tcx, fn_ty), ret_ty, []);
     v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty))));
     ret {bcx: bcx, mthptr: v, objptr: o};
 }
@@ -5084,13 +5092,17 @@ fn register_fn(ccx: @crate_ctxt, sp: span, path: [str], flav: str,
     register_fn_full(ccx, sp, path, flav, ty_params, node_id, t);
 }
 
+fn param_bounds(ccx: @crate_ctxt, tp: ast::ty_param) -> ty::param_bounds {
+    ccx.tcx.ty_param_bounds.get(ast_util::local_def(tp.id))
+}
+
 fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
-                    ty_params: [ast::ty_param], node_id: ast::node_id,
+                    tps: [ast::ty_param], node_id: ast::node_id,
                     node_type: ty::t)
     : returns_non_ty_var(ccx, node_type) {
     let path = path;
-    let llfty =
-        type_of_fn_from_ty(ccx, sp, node_type, vec::len(ty_params));
+    let llfty = type_of_fn_from_ty(ccx, sp, node_type,
+                                   vec::map(tps, {|p| param_bounds(ccx, p)}));
     let ps: str = mangle_exported_name(ccx, path, node_type);
     let llfn: ValueRef = decl_cdecl_fn(ccx.llmod, ps, llfty);
     ccx.item_ids.insert(node_id, llfn);
@@ -5128,7 +5140,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
         let nt = ty::mk_nil(ccx.tcx);
         check non_ty_var(ccx, nt);
 
-        let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, 0u);
+        let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, []);
         let llfdecl = decl_fn(ccx.llmod, "_rust_main",
                               lib::llvm::LLVMCCallConv, llfty);
 
@@ -5221,12 +5233,13 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
     ret count;
 }
 
-fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
+fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span,
+                          param_bounds: [ty::param_bounds],
                           x: ty::t) -> TypeRef {
     alt ty::struct(cx.tcx, x) {
       ty::ty_native_fn(args, out) {
         check non_ty_var(cx, out);
-        ret type_of_fn(cx, sp, false, args, out, ty_param_count);
+        ret type_of_fn(cx, sp, false, args, out, param_bounds);
       }
     }
 }
@@ -5273,10 +5286,10 @@ fn collect_native_item(ccx: @crate_ctxt,
               ast::native_abi_rust_intrinsic. {
                 // For intrinsics: link the function directly to the intrinsic
                 // function itself.
-                let num_ty_param = vec::len(tps);
                 check returns_non_ty_var(ccx, node_type);
-                let fn_type = type_of_fn_from_ty(ccx, sp, node_type,
-                                                 num_ty_param);
+                let fn_type = type_of_fn_from_ty(
+                    ccx, sp, node_type,
+                    vec::map(tps, {|p| param_bounds(ccx, p)}));
                 let ri_name = "rust_intrinsic_" + link_name(i);
                 let llnativefn = get_extern_fn(
                     ccx.externs, ccx.llmod, ri_name,
diff --git a/src/comp/middle/trans_closure.rs b/src/comp/middle/trans_closure.rs
index 7205dd27c1c..18552e84237 100644
--- a/src/comp/middle/trans_closure.rs
+++ b/src/comp/middle/trans_closure.rs
@@ -383,7 +383,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
     let ccx = bcx_ccx(bcx), bcx = bcx;
     let fty = node_id_type(ccx, id);
     check returns_non_ty_var(ccx, fty);
-    let llfnty = type_of_fn_from_ty(ccx, sp, fty, 0u);
+    let llfnty = type_of_fn_from_ty(ccx, sp, fty, []);
     let sub_cx = extend_path(bcx.fcx.lcx, ccx.names.next("anon"));
     let s = mangle_internal_name_by_path(ccx, sub_cx.path);
     let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
@@ -436,16 +436,13 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
     }
 
     // Figure out which tydescs we need to pass, if any.
-    let outgoing_fty_real; // the type with typarams still in it
-    let lltydescs: [ValueRef];
-    alt f_res.generic {
-      none. { outgoing_fty_real = outgoing_fty; lltydescs = []; }
+    let (outgoing_fty_real, lltydescs, param_bounds) = alt f_res.generic {
+      none. { (outgoing_fty, [], []) }
       some(ginfo) {
         lazily_emit_all_generic_info_tydesc_glues(cx, ginfo);
-        outgoing_fty_real = ginfo.item_type;
-        lltydescs = ginfo.tydescs;
+        (ginfo.item_type, ginfo.tydescs, ginfo.param_bounds)
       }
-    }
+    };
 
     let ty_param_count = vec::len(lltydescs);
     if vec::len(bound) == 0u && ty_param_count == 0u {
@@ -487,7 +484,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
     // Make thunk
     let llthunk =
         trans_bind_thunk(cx.fcx.lcx, cx.sp, pair_ty, outgoing_fty_real, args,
-                         box_ty, ty_param_count, target_res);
+                         box_ty, param_bounds, target_res);
 
     // Fill the function pair
     fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox);
@@ -558,7 +555,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
                     outgoing_fty: ty::t,
                     args: [option::t<@ast::expr>],
                     boxed_closure_ty: ty::t,
-                    ty_param_count: uint,
+                    param_bounds: [ty::param_bounds],
                     target_fn: option::t<ValueRef>)
     -> {val: ValueRef, ty: TypeRef} {
     // If we supported constraints on record fields, we could make the
@@ -667,7 +664,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
     let llargs: [ValueRef] = [llretptr, lltargetenv];
 
     // Copy in the type parameters.
-    let i: uint = 0u;
+    // FIXME[impl] This will also have to copy the dicts
+    let i = 0u, ty_param_count = vec::len(param_bounds);
     while i < ty_param_count {
         // Silly check
         check type_is_tup_like(load_env_bcx, boxed_closure_ty);
@@ -739,11 +737,10 @@ fn trans_bind_thunk(cx: @local_ctxt,
 
     check returns_non_ty_var(ccx, outgoing_fty);
     let lltargetty =
-        type_of_fn_from_ty(ccx, sp, outgoing_fty, ty_param_count);
+        type_of_fn_from_ty(ccx, sp, outgoing_fty, param_bounds);
     lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));
     Call(bcx, lltargetfn, llargs);
     build_return(bcx);
     finish_fn(fcx, lltop);
     ret {val: llthunk, ty: llthunk_ty};
 }
-
diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs
index 9d0f14e6bd1..c8f56185987 100644
--- a/src/comp/middle/trans_common.rs
+++ b/src/comp/middle/trans_common.rs
@@ -320,13 +320,13 @@ fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t)
         }
     }
 
-    let params = csearch::get_type_param_count(ccx.sess.get_cstore(), did);
+    let param_bounds = ty::lookup_item_type(ccx.tcx, did).bounds;
     let nil_res = ty::mk_nil(ccx.tcx);
     // FIXME: Silly check -- mk_nil should have a postcondition
     check non_ty_var(ccx, nil_res);
     let f_t = type_of_fn(ccx, sp, false,
                          [{mode: ast::by_ref, ty: inner_t}],
-                         nil_res, params);
+                         nil_res, param_bounds);
     ret trans::get_extern_const(ccx.externs, ccx.llmod,
                                 csearch::get_symbol(ccx.sess.get_cstore(),
                                                     did), f_t);
diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs
index db50c28b85a..8b8a4b018d4 100644
--- a/src/comp/middle/trans_objects.rs
+++ b/src/comp/middle/trans_objects.rs
@@ -880,8 +880,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
       ty::ty_fn(f) {
         let out = f.output;
         check non_ty_var(ccx, out);
-        llfnty = type_of_fn(ccx, m.span, true, f.inputs, out,
-                            vec::len(ty_params));
+        llfnty = type_of_fn(
+            ccx, m.span, true, f.inputs, out,
+            vec::map(ty_params, {|p| param_bounds(ccx, p)}));
       }
     }
     let mcx: @local_ctxt =
@@ -933,7 +934,8 @@ fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method,
                 tps: [ast::ty_param]) -> TypeRef {
     let out_ty = m.fty.output;
     check non_ty_var(ccx, out_ty);
-    type_of_fn(ccx, sp, true, m.fty.inputs, out_ty, vec::len(tps))
+    type_of_fn(ccx, sp, true, m.fty.inputs, out_ty,
+               vec::map(tps, {|p| param_bounds(ccx, p)}))
 }
 
 //
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index dad0a1609f4..c6e68c7777e 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -185,7 +185,7 @@ export closure_kind;
 export closure_block;
 export closure_shared;
 export closure_send;
-export param_bound, bound_copy, bound_send, bound_iface;
+export param_bound, param_bounds, bound_copy, bound_send, bound_iface;
 export param_bounds_to_kind;
 
 // Data types
@@ -194,7 +194,9 @@ type arg = {mode: mode, ty: t};
 
 type field = {ident: ast::ident, mt: mt};
 
-type method = {ident: ast::ident, tps: [@[param_bound]], fty: fn_ty};
+type param_bounds = @[param_bound];
+
+type method = {ident: ast::ident, tps: [param_bounds], fty: fn_ty};
 
 type constr_table = hashmap<ast::node_id, [constr]>;
 
@@ -220,7 +222,7 @@ type ctxt =
       ast_ty_to_ty_cache: hashmap<@ast::ty, option::t<t>>,
       tag_var_cache: hashmap<def_id, @[variant_info]>,
       iface_method_cache: hashmap<def_id, @[method]>,
-      ty_param_bounds: hashmap<def_id, @[param_bound]>};
+      ty_param_bounds: hashmap<def_id, param_bounds>};
 
 type ty_ctxt = ctxt;
 
@@ -308,7 +310,7 @@ tag param_bound {
     bound_iface(t);
 }
 
-fn param_bounds_to_kind(bounds: @[param_bound]) -> kind {
+fn param_bounds_to_kind(bounds: param_bounds) -> kind {
     let kind = kind_noncopyable;
     for bound in *bounds {
         alt bound {
@@ -322,7 +324,7 @@ fn param_bounds_to_kind(bounds: @[param_bound]) -> kind {
     kind
 }
 
-type ty_param_bounds_and_ty = @{bounds: [@[param_bound]], ty: t};
+type ty_param_bounds_and_ty = @{bounds: [param_bounds], ty: t};
 
 type type_cache = hashmap<ast::def_id, ty_param_bounds_and_ty>;
 
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index a86a29d9f1a..3901c808bcf 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -504,7 +504,7 @@ fn ty_of_native_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
     ret tpt;
 }
 fn ty_param_bounds(tcx: ty::ctxt, mode: mode, params: [ast::ty_param])
-    -> [@[ty::param_bound]] {
+    -> [ty::param_bounds] {
     let result = [];
     for param in params {
         result += [alt tcx.ty_param_bounds.find(local_def(param.id)) {
@@ -626,7 +626,7 @@ mod write {
 }
 
 fn mk_ty_params(tcx: ty::ctxt, atps: [ast::ty_param])
-    -> {bounds: [@[ty::param_bound]], params: [ty::t]} {
+    -> {bounds: [ty::param_bounds], params: [ty::t]} {
     let i = 0u, bounds = ty_param_bounds(tcx, m_collect, atps);
     {bounds: bounds,
      params: vec::map(atps, {|atp|
@@ -2896,6 +2896,7 @@ fn resolve_vtables(tcx: ty::ctxt, impl_map: resolve::impl_map,
             ty::ty_iface(did, _) { did }
             _ { ret; }
         };
+        // FIXME check against bounded param types
         let found = false;
         std::list::iter(isc) {|impls|
             if found { ret; }