提交 0a0525e3 编写于 作者: N Niko Matsakis

Pass around a pointer to the ty::method rather than the individual bits of info

上级 56959657
......@@ -238,8 +238,7 @@ pub fn trans_fn_ref_with_vtables(
// Modify the def_id if this is a default method; we want to be
// monomorphizing the trait's code.
let (def_id, opt_impl_did) =
match tcx.provided_method_sources.find(&def_id) {
let (def_id, opt_impl_did) = match tcx.provided_method_sources.find(&def_id) {
None => (def_id, None),
Some(source) => (source.method_id, Some(source.impl_id))
};
......
......@@ -376,7 +376,8 @@ pub fn method_with_name(ccx: @CrateContext, impl_id: ast::def_id,
}
}
pub fn method_with_name_or_default(ccx: @CrateContext, impl_id: ast::def_id,
pub fn method_with_name_or_default(ccx: @CrateContext,
impl_id: ast::def_id,
name: ast::ident) -> ast::def_id {
if impl_id.crate == ast::local_crate {
match *ccx.tcx.items.get(&impl_id.node) {
......
......@@ -176,13 +176,7 @@ pub struct LookupContext<'self> {
pub struct Candidate {
rcvr_ty: ty::t,
rcvr_substs: ty::substs,
explicit_self: ast::self_ty_,
// FIXME #3446---these two fields should be easily derived from
// origin, yet are not
num_method_tps: uint,
self_mode: ast::rmode,
method_ty: @ty::method,
origin: method_origin,
}
......@@ -474,7 +468,7 @@ fn push_inherent_candidates_from_param(&self,
}
}
};
let method = &trait_methods[pos];
let method = trait_methods[pos];
let (rcvr_ty, rcvr_substs) =
self.create_rcvr_ty_and_substs_for_method(
......@@ -486,9 +480,7 @@ fn push_inherent_candidates_from_param(&self,
let cand = Candidate {
rcvr_ty: rcvr_ty,
rcvr_substs: rcvr_substs,
explicit_self: method.self_ty,
num_method_tps: method.tps.len(),
self_mode: get_mode_from_self_type(method.self_ty),
method_ty: method,
origin: method_param(
method_param {
trait_id: init_trait_id,
......@@ -520,7 +512,7 @@ fn push_inherent_candidates_from_trait(&self,
Some(i) => i,
None => { return; } // no method with the right name
};
let method = &ms[index];
let method = ms[index];
/* FIXME(#3157) we should transform the vstore in accordance
with the self type
......@@ -554,9 +546,7 @@ fn push_inherent_candidates_from_trait(&self,
self.inherent_candidates.push(Candidate {
rcvr_ty: rcvr_ty,
rcvr_substs: rcvr_substs,
explicit_self: method.self_ty,
num_method_tps: method.tps.len(),
self_mode: get_mode_from_self_type(method.self_ty),
method_ty: method,
origin: method_trait(did, index, store)
});
}
......@@ -565,63 +555,65 @@ fn push_inherent_candidates_from_self(&self,
self_ty: ty::t,
did: def_id,
substs: &ty::substs) {
struct MethodInfo {
method_ty: @ty::method,
trait_def_id: ast::def_id,
index: uint
}
let tcx = self.tcx();
// First, try self methods
let mut method = None;
let mut method_info: Option<MethodInfo> = None;
let methods = ty::trait_methods(tcx, did);
let mut index = None;
let mut trait_did = None;
match vec::position(*methods, |m| m.ident == self.m_name) {
Some(i) => {
index = Some(i);
trait_did = Some(did);
method = Some((methods[i].self_ty, methods[i].tps.len()));
method_info = Some(MethodInfo {
method_ty: methods[i],
index: i,
trait_def_id: did
});
}
None => ()
}
// No method found yet? Check each supertrait
if method.is_none() {
if method_info.is_none() {
for ty::trait_supertraits(tcx, did).each() |trait_ref| {
let supertrait_methods =
ty::trait_methods(tcx, trait_ref.def_id);
match vec::position(*supertrait_methods,
|m| m.ident == self.m_name) {
Some(i) => {
index = Some(i);
trait_did = Some(trait_ref.def_id);
method = Some((supertrait_methods[i].self_ty,
supertrait_methods[i].tps.len()));
method_info = Some(MethodInfo {
method_ty: supertrait_methods[i],
index: i,
trait_def_id: trait_ref.def_id
});
break;
}
None => ()
}
}
}
match (method, index, trait_did) {
(Some((method_self_ty, method_num_tps)),
Some(index), Some(trait_did)) => {
match method_info {
Some(ref info) => {
// We've found a method -- return it
let rcvr_substs = substs { self_ty: Some(self_ty),
let rcvr_substs = substs {self_ty: Some(self_ty),
..copy *substs };
let (rcvr_ty, rcvr_substs) =
self.create_rcvr_ty_and_substs_for_method(
method_self_ty,
info.method_ty.self_ty,
self_ty,
rcvr_substs,
TransformTypeNormally);
let origin = if trait_did == did {
method_self(trait_did, index)
}
else {
method_super(trait_did, index)
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: rcvr_ty,
rcvr_substs: rcvr_substs,
explicit_self: method_self_ty,
num_method_tps: method_num_tps,
self_mode: get_mode_from_self_type(method_self_ty),
method_ty: info.method_ty,
origin: origin
});
}
......@@ -653,7 +645,7 @@ fn push_candidates_from_impl(&self, candidates: &mut ~[Candidate],
}
};
let method = &impl_info.methods[idx];
let method = ty::method(self.tcx(), impl_info.methods[idx].did);
// determine the `self` of the impl with fresh
// variables for each parameter:
......@@ -669,7 +661,7 @@ fn push_candidates_from_impl(&self, candidates: &mut ~[Candidate],
let (impl_ty, impl_substs) =
self.create_rcvr_ty_and_substs_for_method(
method.self_type,
method.self_ty,
impl_ty,
impl_substs,
TransformTypeNormally);
......@@ -677,10 +669,8 @@ fn push_candidates_from_impl(&self, candidates: &mut ~[Candidate],
candidates.push(Candidate {
rcvr_ty: impl_ty,
rcvr_substs: impl_substs,
explicit_self: method.self_type,
num_method_tps: method.n_tps,
self_mode: get_mode_from_self_type(method.self_type),
origin: method_static(method.did)
method_ty: method,
origin: method_static(method.def_id)
});
}
......@@ -701,6 +691,9 @@ fn push_candidates_from_provided_methods(
debug!("(pushing candidates from provided methods) adding \
candidate");
let method = ty::method(self.tcx(),
provided_method_info.method_info.did);
// XXX: Needs to support generics.
let dummy_substs = substs {
self_r: None,
......@@ -709,7 +702,7 @@ fn push_candidates_from_provided_methods(
};
let (impl_ty, impl_substs) =
self.create_rcvr_ty_and_substs_for_method(
provided_method_info.method_info.self_type,
method.self_ty,
self_ty,
dummy_substs,
TransformTypeNormally);
......@@ -717,10 +710,7 @@ fn push_candidates_from_provided_methods(
candidates.push(Candidate {
rcvr_ty: impl_ty,
rcvr_substs: impl_substs,
explicit_self: provided_method_info.method_info.self_type,
num_method_tps: provided_method_info.method_info.n_tps,
self_mode: get_mode_from_self_type(
provided_method_info.method_info.self_type),
method_ty: method,
origin: method_static(provided_method_info.method_info.did)
});
}
......@@ -1126,20 +1116,21 @@ fn confirm_candidate(&self,
// If they were not explicitly supplied, just construct fresh
// type variables.
let num_supplied_tps = self.supplied_tps.len();
let num_method_tps = candidate.method_ty.tps.len();
let m_substs = {
if num_supplied_tps == 0u {
self.fcx.infcx().next_ty_vars(candidate.num_method_tps)
} else if candidate.num_method_tps == 0u {
self.fcx.infcx().next_ty_vars(num_method_tps)
} else if num_method_tps == 0u {
tcx.sess.span_err(
self.expr.span,
~"this method does not take type parameters");
self.fcx.infcx().next_ty_vars(candidate.num_method_tps)
} else if num_supplied_tps != candidate.num_method_tps {
self.fcx.infcx().next_ty_vars(num_method_tps)
} else if num_supplied_tps != num_method_tps {
tcx.sess.span_err(
self.expr.span,
~"incorrect number of type \
parameters given for this method");
self.fcx.infcx().next_ty_vars(candidate.num_method_tps)
self.fcx.infcx().next_ty_vars(num_method_tps)
} else {
self.supplied_tps.to_vec()
}
......@@ -1178,14 +1169,16 @@ fn confirm_candidate(&self,
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty});
debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty));
let self_mode = get_mode_from_self_type(candidate.method_ty.self_ty);
self.fcx.write_ty(self.callee_id, fty);
self.fcx.write_substs(self.callee_id, all_substs);
method_map_entry {
self_arg: arg {
mode: ast::expl(candidate.self_mode),
mode: ast::expl(self_mode),
ty: candidate.rcvr_ty,
},
explicit_self: candidate.explicit_self,
explicit_self: candidate.method_ty.self_ty,
origin: candidate.origin,
}
}
......@@ -1217,7 +1210,7 @@ fn enforce_trait_instance_limitations(&self,
self-type through a boxed trait");
}
if candidate.num_method_tps > 0 {
if candidate.method_ty.tps.len() > 0 {
self.tcx().sess.span_err(
self.expr.span,
~"cannot call a generic method through a boxed trait");
......@@ -1334,10 +1327,9 @@ fn ty_to_str(&self, t: ty::t) -> ~str {
}
fn cand_to_str(&self, cand: &Candidate) -> ~str {
fmt!("Candidate(rcvr_ty=%s, rcvr_substs=%s, self_mode=%?, origin=%?)",
fmt!("Candidate(rcvr_ty=%s, rcvr_substs=%s, origin=%?)",
self.ty_to_str(cand.rcvr_ty),
ty::substs_to_str(self.tcx(), &cand.rcvr_substs),
cand.self_mode,
cand.origin)
}
......
......@@ -2125,7 +2125,7 @@ fn check_loop_body(fcx: @mut FnCtxt,
match expr.node {
ast::expr_vstore(ev, vst) => {
let typ = match ev.node {
ast::expr_lit(@codemap::spanned { node: ast::lit_str(s), _ }) => {
ast::expr_lit(@codemap::spanned { node: ast::lit_str(_), _ }) => {
let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
ty::mk_estr(tcx, tt)
}
......@@ -2162,7 +2162,7 @@ fn check_loop_body(fcx: @mut FnCtxt,
}
}
ast::expr_repeat(element, count_expr, mutbl) => {
let count = ty::eval_repeat_count(tcx, count_expr);
let _ = ty::eval_repeat_count(tcx, count_expr);
check_expr_with_hint(fcx, count_expr, ty::mk_uint(tcx));
let tt = ast_expr_vstore_to_vstore(fcx, ev, vst);
let mutability = match vst {
......
......@@ -333,10 +333,16 @@ fn instantiate_default_methods(&self, impl_id: ast::node_id,
let new_id = parse::next_node_id(tcx.sess.parse_sess);
let new_did = local_def(new_id);
let new_method_ty = @ty::method {
def_id: new_did,
..copy *trait_method
};
// XXX: Perform substitutions.
let new_polytype = ty::lookup_item_type(tcx,
trait_method.def_id);
tcx.tcache.insert(new_did, new_polytype);
tcx.methods.insert(new_did, new_method_ty);
// Pair the new synthesized ID up with the
// ID of the method.
......@@ -498,7 +504,7 @@ fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) {
fn each_provided_trait_method(&self,
trait_did: ast::def_id,
f: &fn(x: &ty::method) -> bool) {
f: &fn(x: @ty::method) -> bool) {
// Make a list of all the names of the provided methods.
// XXX: This is horrible.
let mut provided_method_idents = HashSet::new();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册