rustc: Add a new method_self method call origin. Part of default methods.
This commit is contained in:
parent
02c33f8d31
commit
b80b0688d5
@ -493,6 +493,9 @@ impl method_origin: tr {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private};
|
||||
use syntax::ast::{provided, required};
|
||||
use syntax::ast_map::{node_item, node_method};
|
||||
use ty::ty_class;
|
||||
use typeck::{method_map, method_origin, method_param, method_static};
|
||||
use typeck::{method_trait};
|
||||
use typeck::{method_map, method_origin, method_param, method_self};
|
||||
use typeck::{method_static, method_trait};
|
||||
|
||||
use core::util::ignore;
|
||||
use dvec::DVec;
|
||||
@ -81,7 +81,8 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
|
||||
}
|
||||
}
|
||||
method_param({trait_id: trait_id, method_num: method_num, _}) |
|
||||
method_trait(trait_id, method_num, _) => {
|
||||
method_trait(trait_id, method_num, _) |
|
||||
method_self(trait_id, method_num) => {
|
||||
if trait_id.crate == local_crate {
|
||||
match tcx.items.find(trait_id.node) {
|
||||
Some(node_item(item, _)) => {
|
||||
|
@ -1847,7 +1847,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::item_impl(tps, trait_refs, _, ms) => {
|
||||
ast::item_impl(tps, trait_refs, self_ast_ty, ms) => {
|
||||
meth::trans_impl(ccx, *path, item.ident, ms, tps, None);
|
||||
|
||||
// Translate any methods that have provided implementations.
|
||||
@ -1860,13 +1860,22 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
loop;
|
||||
}
|
||||
|
||||
// Get the self type.
|
||||
let self_ty;
|
||||
match ccx.tcx.ast_ty_to_ty_cache.get(self_ast_ty) {
|
||||
ty::atttce_resolved(self_type) => self_ty = self_type,
|
||||
ty::atttce_unresolved => {
|
||||
ccx.tcx.sess.impossible_case(item.span,
|
||||
~"didn't cache self ast ty");
|
||||
}
|
||||
}
|
||||
|
||||
match ccx.tcx.items.get(trait_id.node) {
|
||||
ast_map::node_item(trait_item, _) => {
|
||||
match trait_item.node {
|
||||
ast::item_trait(tps, _, trait_methods) => {
|
||||
// XXX: ty_self is wrong here. Get the real type.
|
||||
trans_trait(ccx, tps, trait_methods, path,
|
||||
item.ident, ty::mk_self(ccx.tcx));
|
||||
item.ident, self_ty);
|
||||
}
|
||||
_ => {
|
||||
ccx.tcx.sess.impossible_case(item.span,
|
||||
|
@ -154,6 +154,9 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
|
||||
typeck::method_trait(_, off, vstore) => {
|
||||
trans_trait_callee(bcx, callee_id, off, self, vstore)
|
||||
}
|
||||
typeck::method_self(_, off) => {
|
||||
bcx.tcx().sess.span_bug(self.span, ~"self method call");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
|
||||
typeck::method_param({param_num: param, _}) => {
|
||||
cx.uses[param] |= use_tydesc;
|
||||
}
|
||||
typeck::method_trait(*) => (),
|
||||
typeck::method_trait(*) | typeck::method_self(*) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2826,7 +2826,8 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
|
||||
}
|
||||
typeck::method_param({trait_id:trt_id,
|
||||
method_num:n_mth, _}) |
|
||||
typeck::method_trait(trt_id, n_mth, _) => {
|
||||
typeck::method_trait(trt_id, n_mth, _) |
|
||||
typeck::method_self(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.
|
||||
|
@ -73,7 +73,7 @@ export deserialize_method_map_entry;
|
||||
export vtable_map;
|
||||
export vtable_res;
|
||||
export vtable_origin;
|
||||
export method_static, method_param, method_trait;
|
||||
export method_static, method_param, method_trait, method_self;
|
||||
export vtable_static, vtable_param, vtable_trait;
|
||||
export provided_methods_map;
|
||||
|
||||
@ -87,6 +87,9 @@ enum method_origin {
|
||||
|
||||
// method invoked on a trait instance
|
||||
method_trait(ast::def_id, uint, ty::vstore),
|
||||
|
||||
// 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
|
||||
|
@ -232,9 +232,8 @@ impl LookupContext {
|
||||
let self_did = self.fcx.self_impl_def_id.expect(
|
||||
~"unexpected `none` for self_impl_def_id");
|
||||
let substs = {self_r: None, self_ty: None, tps: ~[]};
|
||||
self.push_inherent_candidates_from_trait(
|
||||
self_ty, self_did, &substs,
|
||||
ty::vstore_slice(ty::re_static)); // XXX: Wrong!
|
||||
self.push_inherent_candidates_from_self(
|
||||
self_ty, self_did, &substs);
|
||||
}
|
||||
ty_enum(did, _) | ty_class(did, _) => {
|
||||
self.push_inherent_impl_candidates_for_type(did);
|
||||
@ -397,6 +396,33 @@ impl LookupContext {
|
||||
});
|
||||
}
|
||||
|
||||
fn push_inherent_candidates_from_self(&self,
|
||||
self_ty: ty::t,
|
||||
did: def_id,
|
||||
substs: &ty::substs) {
|
||||
let tcx = self.tcx();
|
||||
let methods = ty::trait_methods(tcx, did); // XXX: Inherited methods.
|
||||
let index;
|
||||
match vec::position(*methods, |m| m.ident == self.m_name) {
|
||||
Some(i) => index = i,
|
||||
None => return
|
||||
}
|
||||
let method = &methods[index];
|
||||
|
||||
let rcvr_substs = { self_ty: Some(self_ty), ..*substs };
|
||||
let (rcvr_ty, rcvr_substs) =
|
||||
self.create_rcvr_ty_and_substs_for_method(
|
||||
method.self_ty, self_ty, move rcvr_substs);
|
||||
|
||||
self.inherent_candidates.push(Candidate {
|
||||
rcvr_ty: rcvr_ty,
|
||||
rcvr_substs: move rcvr_substs,
|
||||
num_method_tps: method.tps.len(),
|
||||
self_mode: get_mode_from_self_type(method.self_ty),
|
||||
origin: method_self(did, index)
|
||||
});
|
||||
}
|
||||
|
||||
fn push_inherent_impl_candidates_for_type(did: def_id)
|
||||
{
|
||||
let opt_impl_infos =
|
||||
@ -737,7 +763,7 @@ impl LookupContext {
|
||||
* vtable and hence cannot be monomorphized. */
|
||||
|
||||
match candidate.origin {
|
||||
method_static(*) | method_param(*) => {
|
||||
method_static(*) | method_param(*) | method_self(*) => {
|
||||
return; // not a call to a trait instance
|
||||
}
|
||||
method_trait(*) => {}
|
||||
@ -772,7 +798,7 @@ impl LookupContext {
|
||||
method_param(ref mp) => {
|
||||
type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
|
||||
}
|
||||
method_trait(did, idx, _) => {
|
||||
method_trait(did, idx, _) | method_self(did, idx) => {
|
||||
type_of_trait_method(self.tcx(), did, idx)
|
||||
}
|
||||
};
|
||||
@ -793,7 +819,7 @@ impl LookupContext {
|
||||
method_param(mp) => {
|
||||
self.report_param_candidate(idx, mp.trait_id)
|
||||
}
|
||||
method_trait(trait_did, _, _) => {
|
||||
method_trait(trait_did, _, _) | method_self(trait_did, _) => {
|
||||
self.report_param_candidate(idx, trait_did)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user