Major rework of how calls to self and super methods work.
Eliminates method_super, method_self, and vtable_self, merging all of them into the param cases. Cloes #4396. Closes #7301.
This commit is contained in:
parent
79f8a7fee5
commit
ffc879c2e4
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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")
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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, _)) => {
|
||||
|
@ -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: ¶m_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()
|
||||
}
|
||||
|
||||
|
@ -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 = ~[];
|
||||
@ -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)
|
||||
}
|
||||
@ -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,
|
||||
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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(*) => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
@ -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)
|
||||
|
@ -90,7 +90,8 @@ use middle::typeck::check::vtable;
|
||||
use middle::typeck::check;
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::{method_map_entry, method_origin, method_param};
|
||||
use middle::typeck::{method_self, method_static, method_trait, method_super};
|
||||
use middle::typeck::{method_static, method_trait};
|
||||
use middle::typeck::{param_numbered, param_self, param_index};
|
||||
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
|
||||
use util::common::indenter;
|
||||
|
||||
@ -342,64 +343,6 @@ impl<'self> LookupContext<'self> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_inherent_candidates_from_param(&self,
|
||||
rcvr_ty: ty::t,
|
||||
param_ty: param_ty) {
|
||||
debug!("push_inherent_candidates_from_param(param_ty=%?)",
|
||||
param_ty);
|
||||
let _indenter = indenter();
|
||||
|
||||
let tcx = self.tcx();
|
||||
let mut next_bound_idx = 0; // count only trait bounds
|
||||
let type_param_def = match tcx.ty_param_defs.find(¶m_ty.def_id.node) {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
tcx.sess.span_bug(
|
||||
self.expr.span,
|
||||
fmt!("No param def for %?", param_ty));
|
||||
}
|
||||
};
|
||||
|
||||
for ty::each_bound_trait_and_supertraits(tcx, type_param_def.bounds)
|
||||
|bound_trait_ref|
|
||||
{
|
||||
let this_bound_idx = next_bound_idx;
|
||||
next_bound_idx += 1;
|
||||
|
||||
let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
|
||||
let pos = {
|
||||
match trait_methods.iter().position(|m| {
|
||||
m.explicit_self != ast::sty_static &&
|
||||
m.ident == self.m_name })
|
||||
{
|
||||
Some(pos) => pos,
|
||||
None => {
|
||||
debug!("trait doesn't contain method: %?",
|
||||
bound_trait_ref.def_id);
|
||||
loop; // check next trait or bound
|
||||
}
|
||||
}
|
||||
};
|
||||
let method = trait_methods[pos];
|
||||
|
||||
let cand = Candidate {
|
||||
rcvr_ty: rcvr_ty,
|
||||
rcvr_substs: bound_trait_ref.substs.clone(),
|
||||
method_ty: method,
|
||||
origin: method_param(
|
||||
method_param {
|
||||
trait_id: bound_trait_ref.def_id,
|
||||
method_num: pos,
|
||||
param_num: param_ty.idx,
|
||||
bound_num: this_bound_idx,
|
||||
})
|
||||
};
|
||||
|
||||
debug!("pushing inherent candidate for param: %?", cand);
|
||||
self.inherent_candidates.push(cand);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_inherent_candidates_from_trait(&self,
|
||||
self_ty: ty::t,
|
||||
did: def_id,
|
||||
@ -452,69 +395,91 @@ impl<'self> LookupContext<'self> {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn push_inherent_candidates_from_param(&self,
|
||||
rcvr_ty: ty::t,
|
||||
param_ty: param_ty) {
|
||||
debug!("push_inherent_candidates_from_param(param_ty=%?)",
|
||||
param_ty);
|
||||
let _indenter = indenter();
|
||||
|
||||
let tcx = self.tcx();
|
||||
let type_param_def = match tcx.ty_param_defs.find(¶m_ty.def_id.node) {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
tcx.sess.span_bug(
|
||||
self.expr.span,
|
||||
fmt!("No param def for %?", param_ty));
|
||||
}
|
||||
};
|
||||
|
||||
self.push_inherent_candidates_from_bounds(
|
||||
rcvr_ty, &*type_param_def.bounds, param_numbered(param_ty.idx));
|
||||
}
|
||||
|
||||
|
||||
pub fn push_inherent_candidates_from_self(&self,
|
||||
self_ty: ty::t,
|
||||
did: def_id) {
|
||||
struct MethodInfo {
|
||||
method_ty: @ty::Method,
|
||||
trait_def_id: ast::def_id,
|
||||
index: uint,
|
||||
trait_ref: @ty::TraitRef
|
||||
}
|
||||
|
||||
let tcx = self.tcx();
|
||||
// First, try self methods
|
||||
let mut method_info: Option<MethodInfo> = None;
|
||||
let methods = ty::trait_methods(tcx, did);
|
||||
match methods.iter().position(|m| m.ident == self.m_name) {
|
||||
Some(i) => {
|
||||
method_info = Some(MethodInfo {
|
||||
method_ty: methods[i],
|
||||
index: i,
|
||||
trait_def_id: did,
|
||||
trait_ref: ty::lookup_trait_def(tcx, did).trait_ref
|
||||
});
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
// No method found yet? Check each supertrait
|
||||
if method_info.is_none() {
|
||||
for ty::trait_supertraits(tcx, did).iter().advance |trait_ref| {
|
||||
let supertrait_methods =
|
||||
ty::trait_methods(tcx, trait_ref.def_id);
|
||||
match supertrait_methods.iter().position(|m| m.ident == self.m_name) {
|
||||
Some(i) => {
|
||||
method_info = Some(MethodInfo {
|
||||
method_ty: supertrait_methods[i],
|
||||
index: i,
|
||||
trait_def_id: trait_ref.def_id,
|
||||
trait_ref: *trait_ref
|
||||
});
|
||||
break;
|
||||
|
||||
let trait_ref = ty::lookup_trait_def(tcx, did).trait_ref;
|
||||
let bounds = ParamBounds {
|
||||
builtin_bounds: EmptyBuiltinBounds(),
|
||||
trait_bounds: ~[trait_ref]
|
||||
};
|
||||
|
||||
self.push_inherent_candidates_from_bounds(
|
||||
self_ty, &bounds, param_self);
|
||||
}
|
||||
|
||||
pub fn push_inherent_candidates_from_bounds(&self,
|
||||
self_ty: ty::t,
|
||||
bounds: &ParamBounds,
|
||||
param: param_index) {
|
||||
let tcx = self.tcx();
|
||||
let mut next_bound_idx = 0; // count only trait bounds
|
||||
|
||||
for ty::each_bound_trait_and_supertraits(tcx, bounds)
|
||||
|bound_trait_ref|
|
||||
{
|
||||
let this_bound_idx = next_bound_idx;
|
||||
next_bound_idx += 1;
|
||||
|
||||
let trait_methods = ty::trait_methods(tcx, bound_trait_ref.def_id);
|
||||
let pos = {
|
||||
match trait_methods.iter().position(|m| {
|
||||
m.explicit_self != ast::sty_static &&
|
||||
m.ident == self.m_name })
|
||||
{
|
||||
Some(pos) => pos,
|
||||
None => {
|
||||
debug!("trait doesn't contain method: %?",
|
||||
bound_trait_ref.def_id);
|
||||
loop; // check next trait or bound
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
match method_info {
|
||||
Some(ref info) => {
|
||||
// We've found a method -- return it
|
||||
let origin = if did == info.trait_def_id {
|
||||
method_self(info.trait_def_id, info.index)
|
||||
} else {
|
||||
method_super(info.trait_def_id, info.index)
|
||||
};
|
||||
self.inherent_candidates.push(Candidate {
|
||||
rcvr_ty: self_ty,
|
||||
rcvr_substs: info.trait_ref.substs.clone(),
|
||||
method_ty: info.method_ty,
|
||||
origin: origin
|
||||
});
|
||||
}
|
||||
_ => return
|
||||
};
|
||||
let method = trait_methods[pos];
|
||||
|
||||
let cand = Candidate {
|
||||
rcvr_ty: self_ty,
|
||||
rcvr_substs: bound_trait_ref.substs.clone(),
|
||||
method_ty: method,
|
||||
origin: method_param(
|
||||
method_param {
|
||||
trait_id: bound_trait_ref.def_id,
|
||||
method_num: pos,
|
||||
param_num: param,
|
||||
bound_num: this_bound_idx,
|
||||
})
|
||||
};
|
||||
|
||||
debug!("pushing inherent candidate for param: %?", cand);
|
||||
self.inherent_candidates.push(cand);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn push_inherent_impl_candidates_for_type(&self, did: def_id) {
|
||||
let opt_impl_infos = self.tcx().inherent_impls.find(&did);
|
||||
for opt_impl_infos.iter().advance |impl_infos| {
|
||||
@ -1019,14 +984,13 @@ impl<'self> LookupContext<'self> {
|
||||
/*!
|
||||
*
|
||||
* There are some limitations to calling functions through a
|
||||
* traint instance, because (a) the self type is not known
|
||||
* trait instance, because (a) the self type is not known
|
||||
* (that's the whole point of a trait instance, after all, to
|
||||
* obscure the self type) and (b) the call must go through a
|
||||
* vtable and hence cannot be monomorphized. */
|
||||
|
||||
match candidate.origin {
|
||||
method_static(*) | method_param(*) |
|
||||
method_self(*) | method_super(*) => {
|
||||
method_static(*) | method_param(*) => {
|
||||
return; // not a call to a trait instance
|
||||
}
|
||||
method_trait(*) => {}
|
||||
@ -1050,10 +1014,11 @@ impl<'self> LookupContext<'self> {
|
||||
// No code can call the finalize method explicitly.
|
||||
let bad;
|
||||
match candidate.origin {
|
||||
method_static(method_id) | method_self(method_id, _)
|
||||
| method_super(method_id, _) => {
|
||||
method_static(method_id) => {
|
||||
bad = self.tcx().destructors.contains(&method_id);
|
||||
}
|
||||
// XXX: does this properly enforce this on everything now
|
||||
// that self has been merged in? -sully
|
||||
method_param(method_param { trait_id: trait_id, _ }) |
|
||||
method_trait(trait_id, _, _) => {
|
||||
bad = self.tcx().destructor_for_type.contains_key(&trait_id);
|
||||
@ -1172,8 +1137,7 @@ impl<'self> LookupContext<'self> {
|
||||
method_param(ref mp) => {
|
||||
type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
|
||||
}
|
||||
method_trait(did, idx, _) | method_self(did, idx) |
|
||||
method_super(did, idx) => {
|
||||
method_trait(did, idx, _) => {
|
||||
type_of_trait_method(self.tcx(), did, idx)
|
||||
}
|
||||
};
|
||||
@ -1194,8 +1158,7 @@ impl<'self> LookupContext<'self> {
|
||||
method_param(ref mp) => {
|
||||
self.report_param_candidate(idx, (*mp).trait_id)
|
||||
}
|
||||
method_trait(trait_did, _, _) | method_self(trait_did, _)
|
||||
| method_super(trait_did, _) => {
|
||||
method_trait(trait_did, _, _) => {
|
||||
self.report_trait_candidate(idx, trait_did)
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ use middle::typeck::infer::fixup_err_to_str;
|
||||
use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::{CrateCtxt, vtable_origin, vtable_res, vtable_param_res};
|
||||
use middle::typeck::{vtable_static, vtable_param, vtable_self, impl_res};
|
||||
use middle::typeck::{vtable_static, vtable_param, impl_res};
|
||||
use middle::typeck::{param_numbered, param_self};
|
||||
use middle::subst::Subst;
|
||||
use util::common::indenter;
|
||||
use util::ppaux;
|
||||
@ -239,7 +240,7 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||
// The type has unconstrained type variables in it, so we can't
|
||||
// do early resolution on it. Return some completely bogus vtable
|
||||
// information: we aren't storing it anyways.
|
||||
return Some(vtable_param(0, 0));
|
||||
return Some(vtable_param(param_self, 0));
|
||||
}
|
||||
};
|
||||
|
||||
@ -257,7 +258,7 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||
location_info,
|
||||
bound_trait_ref,
|
||||
trait_ref);
|
||||
let vtable = vtable_param(n, n_bound);
|
||||
let vtable = vtable_param(param_numbered(n), n_bound);
|
||||
debug!("found param vtable: %?",
|
||||
vtable);
|
||||
return Some(vtable);
|
||||
@ -272,7 +273,7 @@ fn lookup_vtable(vcx: &VtableContext,
|
||||
trait_ref.def_id, trait_id);
|
||||
|
||||
if trait_id == trait_ref.def_id {
|
||||
let vtable = vtable_self(trait_id);
|
||||
let vtable = vtable_param(param_self, 0);
|
||||
debug!("found self vtable: %?", vtable);
|
||||
return Some(vtable);
|
||||
}
|
||||
@ -403,7 +404,7 @@ fn search_for_vtable(vcx: &VtableContext,
|
||||
None => {
|
||||
assert!(is_early);
|
||||
// Bail out with a bogus answer
|
||||
return Some(vtable_param(0, 0));
|
||||
return Some(vtable_param(param_self, 0));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@ use middle::typeck::infer::{force_all, resolve_all, resolve_region};
|
||||
use middle::typeck::infer::resolve_type;
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::{vtable_res, vtable_origin};
|
||||
use middle::typeck::{vtable_static, vtable_param, vtable_self};
|
||||
use middle::typeck::{vtable_static, vtable_param};
|
||||
use middle::typeck::method_map_entry;
|
||||
use middle::typeck::write_substs_to_tcx;
|
||||
use middle::typeck::write_ty_to_tcx;
|
||||
@ -109,9 +109,6 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) {
|
||||
&vtable_param(n, b) => {
|
||||
vtable_param(n, b)
|
||||
}
|
||||
&vtable_self(def_id) => {
|
||||
vtable_self(def_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,14 +75,14 @@ pub mod infer;
|
||||
pub mod collect;
|
||||
pub mod coherence;
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable, Eq, Ord)]
|
||||
pub enum param_index {
|
||||
param_numbered(uint),
|
||||
param_self
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub enum method_origin {
|
||||
// supertrait method invoked on "self" inside a default method
|
||||
// first field is supertrait ID;
|
||||
// second field is method index (relative to the *supertrait*
|
||||
// method list)
|
||||
method_super(ast::def_id, uint),
|
||||
|
||||
// fully statically resolved method
|
||||
method_static(ast::def_id),
|
||||
|
||||
@ -92,9 +92,6 @@ pub enum method_origin {
|
||||
// method invoked on a trait instance
|
||||
method_trait(ast::def_id, uint, ty::TraitStore),
|
||||
|
||||
// method invoked on "self" inside a default method
|
||||
method_self(ast::def_id, uint)
|
||||
|
||||
}
|
||||
|
||||
// details for a method invoked with a receiver whose type is a type parameter
|
||||
@ -109,7 +106,7 @@ pub struct method_param {
|
||||
|
||||
// index of the type parameter (from those that are in scope) that is
|
||||
// the type of the receiver
|
||||
param_num: uint,
|
||||
param_num: param_index,
|
||||
|
||||
// index of the bound for this type parameter which specifies the trait
|
||||
bound_num: uint,
|
||||
@ -153,15 +150,10 @@ pub enum vtable_origin {
|
||||
fn foo<T:quux,baz,bar>(a: T) -- a's vtable would have a
|
||||
vtable_param origin
|
||||
|
||||
The first uint is the param number (identifying T in the example),
|
||||
The first argument is the param index (identifying T in the example),
|
||||
and the second is the bound number (identifying baz)
|
||||
*/
|
||||
vtable_param(uint, uint),
|
||||
|
||||
/*
|
||||
Dynamic vtable, comes from self.
|
||||
*/
|
||||
vtable_self(ast::def_id)
|
||||
vtable_param(param_index, uint),
|
||||
}
|
||||
|
||||
impl Repr for vtable_origin {
|
||||
@ -178,9 +170,6 @@ impl Repr for vtable_origin {
|
||||
vtable_param(x, y) => {
|
||||
fmt!("vtable_param(%?, %?)", x, y)
|
||||
}
|
||||
vtable_self(def_id) => {
|
||||
fmt!("vtable_self(%?)", def_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -715,10 +715,6 @@ impl Repr for typeck::method_map_entry {
|
||||
impl Repr for typeck::method_origin {
|
||||
fn repr(&self, tcx: ctxt) -> ~str {
|
||||
match self {
|
||||
&typeck::method_super(def_id, n) => {
|
||||
fmt!("method_super(%s, %?)",
|
||||
def_id.repr(tcx), n)
|
||||
}
|
||||
&typeck::method_static(def_id) => {
|
||||
fmt!("method_static(%s)", def_id.repr(tcx))
|
||||
}
|
||||
@ -729,9 +725,6 @@ impl Repr for typeck::method_origin {
|
||||
fmt!("method_trait(%s, %?, %s)", def_id.repr(tcx), n,
|
||||
st.repr(tcx))
|
||||
}
|
||||
&typeck::method_self(def_id, n) => {
|
||||
fmt!("method_self(%s, %?)", def_id.repr(tcx), n)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user