about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2011-07-27 15:43:56 -0700
committerMichael Sullivan <sully@msully.net>2011-07-27 18:46:46 -0700
commit63fa765e0eaa8d07a8b4e60b5f618cfdb1341e7f (patch)
tree2627497c1f95601020ba4ec2c64353da335e45be /src/comp
parent63f74f3771c20fceea294d2dc759ccde8a59a6cd (diff)
downloadrust-63fa765e0eaa8d07a8b4e60b5f618cfdb1341e7f.tar.gz
rust-63fa765e0eaa8d07a8b4e60b5f618cfdb1341e7f.zip
Fix binding a bare fn argument with type parameters.
Closes #642.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs21
1 files changed, 10 insertions, 11 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 1475887ae4d..e64b0d94b7c 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -4458,7 +4458,6 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
     }
 
     let a: uint = 3u; // retptr, task ptr, env come first
-
     let b: int = 1;
     let outgoing_arg_index: uint = 0u;
     let llout_arg_tys: TypeRef[] =
@@ -4466,8 +4465,8 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
     for arg: option::t[@ast::expr]  in args {
         let out_arg = outgoing_args.(outgoing_arg_index);
         let llout_arg_ty = llout_arg_tys.(outgoing_arg_index);
+        let is_val = out_arg.mode == ty::mo_val;
         alt arg {
-
           // Arg provided at binding time; thunk copies it from
           // closure.
           some(e) {
@@ -4478,7 +4477,14 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
                                abi::closure_elt_bindings, b]);
             bcx = bound_arg.bcx;
             let val = bound_arg.val;
-            if out_arg.mode == ty::mo_val {
+            // If the type is parameterized, then we need to cast the
+            // type we actually have to the parameterized out type.
+            if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) {
+                let ty = if is_val
+                         { T_ptr(llout_arg_ty) } else { llout_arg_ty };
+                val = bcx.build.PointerCast(val, ty);
+            }
+            if is_val {
                 if type_is_immediate(cx.ccx, e_ty) {
                     val = bcx.build.Load(val);
                     bcx = copy_ty(bcx, val, e_ty).bcx;
@@ -4487,13 +4493,6 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
                     val = bcx.build.Load(val);
                 }
             }
-            // If the type is parameterized, then we need to cast the
-            // type we actually have to the parameterized out type.
-            if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) {
-                // FIXME: (#642) This works for boxes and alias params
-                // but does not work for bare functions.
-                val = bcx.build.PointerCast(val, llout_arg_ty);
-            }
             llargs += ~[val];
             b += 1;
           }
@@ -4502,7 +4501,7 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
           none. {
             let passed_arg: ValueRef = llvm::LLVMGetParam(llthunk, a);
             if ty::type_contains_params(cx.ccx.tcx, out_arg.ty) {
-                assert (out_arg.mode != ty::mo_val);
+                assert (!is_val);
                 passed_arg = bcx.build.PointerCast(passed_arg, llout_arg_ty);
             }
             llargs += ~[passed_arg];