Skip to content

Commit

Permalink
Major rework of how calls to self and super methods work.
Browse files Browse the repository at this point in the history
Eliminates method_super, method_self, and vtable_self, merging all of
them into the param cases.
Cloes rust-lang#4396. Closes rust-lang#7301.
  • Loading branch information
msullivan committed Jul 24, 2013
1 parent 79f8a7f commit ffc879c
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 292 deletions.
24 changes: 2 additions & 22 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,12 +590,6 @@ impl tr for method_origin {
typeck::method_trait(did, m, vstore) => {
typeck::method_trait(did.tr(xcx), m, vstore)
}
typeck::method_self(did, m) => {
typeck::method_self(did.tr(xcx), m)
}
typeck::method_super(trait_did, m) => {
typeck::method_super(trait_did.tr(xcx), m)
}
}
}
}
Expand Down Expand Up @@ -645,20 +639,13 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext,
typeck::vtable_param(pn, bn) => {
do ebml_w.emit_enum_variant("vtable_param", 1u, 2u) |ebml_w| {
do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
ebml_w.emit_uint(pn);
pn.encode(ebml_w);
}
do ebml_w.emit_enum_variant_arg(1u) |ebml_w| {
ebml_w.emit_uint(bn);
}
}
}
typeck::vtable_self(def_id) => {
do ebml_w.emit_enum_variant("vtable_self", 2u, 1u) |ebml_w| {
do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
ebml_w.emit_def_id(def_id)
}
}
}
}
}
}
Expand Down Expand Up @@ -715,20 +702,13 @@ impl vtable_decoder_helpers for reader::Decoder {
1 => {
typeck::vtable_param(
do this.read_enum_variant_arg(0u) |this| {
this.read_uint()
Decodable::decode(this)
},
do this.read_enum_variant_arg(1u) |this| {
this.read_uint()
}
)
}
2 => {
typeck::vtable_self(
do this.read_enum_variant_arg(0u) |this| {
this.read_def_id_noxcx(cdata)
}
)
}
// hard to avoid - user input
_ => fail!("bad enum variant")
}
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
use metadata::csearch;
use middle::ty::{ty_struct, ty_enum};
use middle::ty;
use middle::typeck::{method_map, method_origin, method_param, method_self};
use middle::typeck::{method_super};
use middle::typeck::{method_map, method_origin, method_param};
use middle::typeck::{method_static, method_trait};

use std::util::ignore;
Expand Down Expand Up @@ -291,9 +290,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
method_num: method_num,
_
}) |
method_trait(trait_id, method_num, _) |
method_self(trait_id, method_num) |
method_super(trait_id, method_num) => {
method_trait(trait_id, method_num, _) => {
if trait_id.crate == local_crate {
match tcx.items.find(&trait_id.node) {
Some(&node_item(item, _)) => {
Expand Down
27 changes: 10 additions & 17 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,32 +1096,25 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
}
}
}
typeck::vtable_self(_trait_id) => {
match param_substs {
Some(@param_substs
{self_vtables: Some(self_vtables), _}) => {
self_vtables[0].clone()
}
_ => {
tcx.sess.bug(fmt!(
"resolve_vtable_in_fn_ctxt: asked to lookup but \
no self_vtable in the fn_ctxt!"))
}
}
}
}
}

pub fn find_vtable(tcx: ty::ctxt,
ps: &param_substs,
n_param: uint,
n_param: typeck::param_index,
n_bound: uint)
-> typeck::vtable_origin {
debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)",
debug!("find_vtable(n_param=%?, n_bound=%u, ps=%s)",
n_param, n_bound, ps.repr(tcx));

let tables = ps.vtables.expect("vtables missing where they are needed");
let param_bounds = tables[n_param];
let param_bounds = match n_param {
typeck::param_self => ps.self_vtables.expect("self vtables missing"),
typeck::param_numbered(n) => {
let tables = ps.vtables
.expect("vtables missing where they are needed");
tables[n]
}
};
param_bounds[n_bound].clone()
}

Expand Down
63 changes: 3 additions & 60 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,46 +147,13 @@ pub fn trans_method_callee(bcx: @mut Block,
mentry: typeck::method_map_entry)
-> Callee {
let _icx = push_ctxt("impl::trans_method_callee");
let tcx = bcx.tcx();

debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)",
callee_id,
bcx.expr_to_str(this),
mentry.repr(bcx.tcx()));

// Replace method_self with method_static here.
let mut origin = mentry.origin;
match origin {
typeck::method_super(trait_id, method_index) => {
// <self_ty> is the self type for this method call
let self_ty = node_id_type(bcx, this.id);
// <impl_id> is the ID of the implementation of
// trait <trait_id> for type <self_ty>
let impl_id = ty::bogus_get_impl_id_from_ty(tcx, trait_id, self_ty);
// Get the supertrait's methods
let supertrait_method_def_ids = ty::trait_method_def_ids(tcx, trait_id);
// Make sure to fail with a readable error message if
// there's some internal error here
if !(method_index < supertrait_method_def_ids.len()) {
tcx.sess.bug("trans_method_callee: supertrait method \
index is out of bounds");
}
// Get the method name using the method index in the origin
let method_name =
ty::method(tcx, supertrait_method_def_ids[method_index]).ident;
// Now that we know the impl ID, we can look up the method
// ID from its name
origin = typeck::method_static(
method_with_name(bcx.ccx(), impl_id, method_name));
}
typeck::method_self(*) |
typeck::method_static(*) | typeck::method_param(*) |
typeck::method_trait(*) => {}
}

debug!("origin=%?", origin);

match origin {
match mentry.origin {
typeck::method_static(did) => {
let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
let mut temp_cleanups = ~[];
Expand All @@ -210,7 +177,8 @@ pub fn trans_method_callee(bcx: @mut Block,
}) => {
match bcx.fcx.param_substs {
Some(substs) => {
let vtbl = find_vtable(bcx.tcx(), substs, p, b);
let vtbl = find_vtable(bcx.tcx(), substs,
p, b);
trans_monomorphized_callee(bcx, callee_id, this, mentry,
trait_id, off, vtbl)
}
Expand All @@ -219,25 +187,6 @@ pub fn trans_method_callee(bcx: @mut Block,
}
}

typeck::method_self(trait_id, method_index) => {
match bcx.fcx.param_substs {
Some(@param_substs
{self_vtables: Some(vtbls), _}) => {
let vtbl = vtbls[0].clone();
trans_monomorphized_callee(bcx,
callee_id,
this,
mentry,
trait_id,
method_index,
vtbl)
}
_ => {
fail!("trans_method_callee: missing self_vtable")
}
}
}

typeck::method_trait(_, off, store) => {
trans_trait_callee(bcx,
callee_id,
Expand All @@ -246,9 +195,6 @@ pub fn trans_method_callee(bcx: @mut Block,
store,
mentry.explicit_self)
}
typeck::method_super(*) => {
fail!("method_super should have been handled above")
}
}
}

Expand Down Expand Up @@ -403,9 +349,6 @@ pub fn trans_monomorphized_callee(bcx: @mut Block,
typeck::vtable_param(*) => {
fail!("vtable_param left in monomorphized function's vtable substs");
}
typeck::vtable_self(*) => {
fail!("vtable_self left in monomorphized function's vtable substs");
}
};

}
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/trans/type_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,12 @@ pub fn mark_for_method_call(cx: &Context, e_id: node_id, callee_id: node_id) {
opt_static_did = Some(did);
}
typeck::method_param(typeck::method_param {
param_num: param,
param_num: typeck::param_numbered(param),
_
}) => {
cx.uses[param] |= use_tydesc;
}
typeck::method_trait(*) | typeck::method_self(*)
| typeck::method_super(*) => (),
_ => (),
}
}
}
Expand Down
29 changes: 1 addition & 28 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3065,9 +3065,7 @@ pub fn method_call_type_param_defs(tcx: ctxt,
typeck::method_param(typeck::method_param {
trait_id: trt_id,
method_num: n_mth, _}) |
typeck::method_trait(trt_id, n_mth, _) |
typeck::method_self(trt_id, n_mth) |
typeck::method_super(trt_id, n_mth) => {
typeck::method_trait(trt_id, n_mth, _) => {
// ...trait methods bounds, in contrast, include only the
// method bounds, so we must preprend the tps from the
// trait itself. This ought to be harmonized.
Expand Down Expand Up @@ -4401,31 +4399,6 @@ pub fn count_traits_and_supertraits(tcx: ctxt,
return total;
}

// Given a trait and a type, returns the impl of that type.
// This is broken, of course, by parametric impls. This used to use
// a table specifically for this mapping, but I removed that table.
// This is only used when calling a supertrait method from a default method,
// and should go away once I fix how that works. -sully
pub fn bogus_get_impl_id_from_ty(tcx: ctxt,
trait_id: def_id, self_ty: t) -> def_id {
match tcx.trait_impls.find(&trait_id) {
Some(ty_to_impl) => {
for ty_to_impl.iter().advance |imp| {
let impl_ty = tcx.tcache.get_copy(&imp.did);
if impl_ty.ty == self_ty { return imp.did; }
}
// try autoderef!
match deref(tcx, self_ty, false) {
Some(some_ty) =>
bogus_get_impl_id_from_ty(tcx, trait_id, some_ty.ty),
None => tcx.sess.bug("get_impl_id: no impl of trait for \
this type")
}
},
None => tcx.sess.bug("get_impl_id: trait isn't in trait_impls")
}
}

pub fn get_tydesc_ty(tcx: ctxt) -> Result<t, ~str> {
do tcx.lang_items.require(TyDescStructLangItem).map |tydesc_lang_item| {
tcx.intrinsic_defs.find_copy(tydesc_lang_item)
Expand Down
Loading

0 comments on commit ffc879c

Please sign in to comment.