about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/rustc/middle/trans/base.rs10
-rw-r--r--src/rustc/middle/trans/impl.rs11
-rw-r--r--src/rustc/middle/typeck.rs37
3 files changed, 39 insertions, 19 deletions
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 23fc3f69e96..c2cb142b46e 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -2668,12 +2668,12 @@ fn invoke_(bcx: block, llfn: ValueRef, llargs: [ValueRef],
     // cleanups to run
     if bcx.unreachable { ret bcx; }
     let normal_bcx = sub_block(bcx, "normal return");
-    /*std::io::println("fn: " + lib::llvm::type_to_str(bcx.ccx().tn,
-                     val_ty(llfn)));
+    /*io::println("fn: " + lib::llvm::type_to_str(bcx.ccx().tn,
+                                                val_ty(llfn)));
     for a in llargs {
-        std::io::println(" a: " + lib::llvm::type_to_str(bcx.ccx().tn,
-                         val_ty(a)));
-    }*/
+        io::println(" a: " + lib::llvm::type_to_str(bcx.ccx().tn,
+                                                    val_ty(a)));
+    }// */
     invoker(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
     ret normal_bcx;
 }
diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs
index f706c0b0471..f4620677701 100644
--- a/src/rustc/middle/trans/impl.rs
+++ b/src/rustc/middle/trans/impl.rs
@@ -115,9 +115,12 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
         let ty_substs = impl_substs +
             vec::tailn(node_substs, node_substs.len() - n_m_tps);
         let {bcx, val} = trans_self_arg(bcx, base);
-        {env: self_env(val, node_id_type(bcx, base.id), none)
-         with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
-                                   some(sub_origins))}
+        let lval = lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
+                                        some(sub_origins));
+        {env: self_env(val, node_id_type(bcx, base.id), none),
+         val: PointerCast(bcx, lval.val, T_ptr(type_of_fn_from_ty(
+             ccx, node_id_type(bcx, callee_id))))
+         with lval}
       }
       typeck::vtable_iface(iid, tps) {
         trans_iface_callee(bcx, base, callee_id, n_method)
@@ -236,7 +239,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t],
         let fty = ty::substitute_type_params(tcx, substs,
                                              ty::mk_fn(tcx, im.fty));
         if (*im.tps).len() > 0u || ty::type_has_vars(fty) {
-            C_null(type_of_fn_from_ty(ccx, fty))
+            C_null(T_ptr(T_nil()))
         } else {
             let m_id = method_with_name(ccx, impl_id, im.ident);
             if has_tps {
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index e518704b1b3..ff38e998461 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -1782,7 +1782,7 @@ fn lookup_method(fcx: @fn_ctxt, expr: @ast::expr, node_id: ast::node_id,
       some({method_ty: fty, n_tps: method_n_tps, substs, origin, self_sub}) {
         let tcx = fcx.ccx.tcx;
         let substs = substs, n_tps = vec::len(substs), n_tys = vec::len(tps);
-        let has_self = ty::type_has_params(fty);
+        let has_self = ty::type_has_vars(fty);
         if method_n_tps + n_tps > 0u {
             if n_tys == 0u || n_tys != method_n_tps {
                 if n_tys != 0u {
@@ -3335,15 +3335,16 @@ mod vtable {
     }
 
     fn lookup_vtables(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
-                    bounds: @[ty::param_bounds], tys: [ty::t])
-        -> vtable_res {
+                      bounds: @[ty::param_bounds], tys: [ty::t],
+                      allow_unsafe: bool) -> vtable_res {
         let tcx = fcx.ccx.tcx, result = [], i = 0u;
         for ty in tys {
             for bound in *bounds[i] {
                 alt bound {
                   ty::bound_iface(i_ty) {
                     let i_ty = ty::substitute_type_params(tcx, tys, i_ty);
-                    result += [lookup_vtable(fcx, isc, sp, ty, i_ty)];
+                    result += [lookup_vtable(fcx, isc, sp, ty, i_ty,
+                                             allow_unsafe)];
                   }
                   _ {}
                 }
@@ -3354,7 +3355,8 @@ mod vtable {
     }
 
     fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
-                   ty: ty::t, iface_ty: ty::t) -> vtable_origin {
+                     ty: ty::t, iface_ty: ty::t, allow_unsafe: bool)
+        -> vtable_origin {
         let tcx = fcx.ccx.tcx;
         let (iface_id, iface_tps) = alt check ty::get(iface_ty).struct {
             ty::ty_iface(did, tps) { (did, tps) }
@@ -3378,6 +3380,20 @@ mod vtable {
             }
           }
           ty::ty_iface(did, tps) if iface_id == did {
+            if !allow_unsafe {
+                for m in *ty::iface_methods(tcx, did) {
+                    if ty::type_has_vars(ty::mk_fn(tcx, m.fty)) {
+                        tcx.sess.span_err(
+                            sp, "a boxed iface with self types may not be \
+                                 passed as a bounded type");
+                    } else if (*m.tps).len() > 0u {
+                        tcx.sess.span_err(
+                            sp, "a boxed iface with generic methods may not \
+                                 be passed as a bounded type");
+
+                    }
+                }
+            }
             ret vtable_iface(did, tps);
           }
           _ {
@@ -3410,8 +3426,8 @@ mod vtable {
                                                   im.did);
                                 let params = vec::map(vars, {|t|
                                     fixup_ty(fcx, sp, t)});
-                                let subres = lookup_vtables(fcx, isc, sp,
-                                                            im_bs, params);
+                                let subres = lookup_vtables(
+                                    fcx, isc, sp, im_bs, params, false);
                                 found = some(vtable_static(im.did, params,
                                                            subres));
                             }
@@ -3469,7 +3485,7 @@ mod vtable {
                 if has_iface_bounds(*item_ty.bounds) {
                     let impls = cx.impl_map.get(ex.id);
                     cx.vtable_map.insert(ex.id, lookup_vtables(
-                        fcx, impls, ex.span, item_ty.bounds, ts));
+                        fcx, impls, ex.span, item_ty.bounds, ts, false));
                 }
               }
               _ {}
@@ -3490,7 +3506,7 @@ mod vtable {
                     let ts = ty::node_id_to_type_params(cx.tcx, callee_id);
                     let iscs = cx.impl_map.get(ex.id);
                     cx.vtable_map.insert(callee_id, lookup_vtables(
-                        fcx, iscs, ex.span, bounds, ts));
+                        fcx, iscs, ex.span, bounds, ts, false));
                 }
               }
               _ {}
@@ -3502,7 +3518,8 @@ mod vtable {
               ty::ty_iface(_, _) {
                 let impls = cx.impl_map.get(ex.id);
                 let vtable = lookup_vtable(fcx, impls, ex.span,
-                                       expr_ty(cx.tcx, src), target_ty);
+                                           expr_ty(cx.tcx, src), target_ty,
+                                           true);
                 cx.vtable_map.insert(ex.id, @[vtable]);
               }
               _ {}