Change method lookup infrastructure to use the trait methods. Instead
of tracking individual candidates per impl, we just track one candidate for the extension trait itself, and let the trait resolution handle walking the individual impls and so forth. Also change the interface to report back a richer notion of error.
This commit is contained in:
parent
1562d8cbd8
commit
dad2db7c83
@ -120,6 +120,13 @@ impl ImplOrTraitItem {
|
||||
TypeTraitItem(ref associated_type) => associated_type.container,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_opt_method(&self) -> Option<Rc<Method>> {
|
||||
match *self {
|
||||
MethodTraitItem(ref m) => Some((*m).clone()),
|
||||
TypeTraitItem(_) => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
@ -1240,6 +1247,10 @@ impl Generics {
|
||||
}
|
||||
|
||||
impl TraitRef {
|
||||
pub fn new(def_id: ast::DefId, substs: Substs) -> TraitRef {
|
||||
TraitRef { def_id: def_id, substs: substs }
|
||||
}
|
||||
|
||||
pub fn self_ty(&self) -> ty::t {
|
||||
self.substs.self_ty().unwrap()
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -77,6 +77,7 @@ type parameter).
|
||||
*/
|
||||
|
||||
|
||||
use driver::session::Session;
|
||||
use middle::const_eval;
|
||||
use middle::def;
|
||||
use middle::lang_items::IteratorItem;
|
||||
@ -2924,46 +2925,24 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
fcx.expr_ty(&*rcvr));
|
||||
|
||||
let tps = tps.iter().map(|ast_ty| fcx.to_ty(&**ast_ty)).collect::<Vec<_>>();
|
||||
let fn_ty = match method::lookup(fcx, expr, &*rcvr,
|
||||
let fn_ty = match method::lookup(fcx,
|
||||
expr,
|
||||
&*rcvr,
|
||||
method_name.node.name,
|
||||
expr_t, tps.as_slice(),
|
||||
expr_t,
|
||||
tps.as_slice(),
|
||||
DontDerefArgs,
|
||||
CheckTraitsAndInherentMethods,
|
||||
AutoderefReceiver, IgnoreStaticMethods) {
|
||||
Some(method) => {
|
||||
AutoderefReceiver) {
|
||||
Ok(method) => {
|
||||
let method_ty = method.ty;
|
||||
let method_call = MethodCall::expr(expr.id);
|
||||
fcx.inh.method_map.borrow_mut().insert(method_call, method);
|
||||
method_ty
|
||||
}
|
||||
None => {
|
||||
debug!("(checking method call) failing expr is {}", expr.id);
|
||||
|
||||
fcx.type_error_message(method_name.span,
|
||||
|actual| {
|
||||
format!("type `{}` does not implement any \
|
||||
method in scope named `{}`",
|
||||
actual,
|
||||
token::get_ident(method_name.node))
|
||||
},
|
||||
expr_t,
|
||||
None);
|
||||
|
||||
// Add error type for the result
|
||||
Err(error) => {
|
||||
method::report_error(fcx, method_name.span, expr_t, method_name.node.name, error);
|
||||
fcx.write_error(expr.id);
|
||||
|
||||
// Check for potential static matches (missing self parameters)
|
||||
method::lookup(fcx,
|
||||
expr,
|
||||
&*rcvr,
|
||||
method_name.node.name,
|
||||
expr_t,
|
||||
tps.as_slice(),
|
||||
DontDerefArgs,
|
||||
CheckTraitsAndInherentMethods,
|
||||
DontAutoderefReceiver,
|
||||
ReportStaticMethods);
|
||||
|
||||
ty::mk_err()
|
||||
}
|
||||
};
|
||||
@ -3466,9 +3445,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
tps.as_slice(),
|
||||
DontDerefArgs,
|
||||
CheckTraitsAndInherentMethods,
|
||||
AutoderefReceiver,
|
||||
IgnoreStaticMethods) {
|
||||
Some(_) => {
|
||||
AutoderefReceiver) {
|
||||
Ok(_) => {
|
||||
fcx.type_error_message(
|
||||
field.span,
|
||||
|actual| {
|
||||
@ -3481,7 +3459,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
"maybe a missing `()` to call it? If not, try an anonymous function.");
|
||||
}
|
||||
|
||||
None => {
|
||||
Err(_) => {
|
||||
fcx.type_error_message(
|
||||
expr.span,
|
||||
|actual| {
|
||||
|
@ -536,6 +536,14 @@ impl<'ast> Map<'ast> {
|
||||
.unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
|
||||
}
|
||||
|
||||
pub fn def_id_span(&self, def_id: DefId, fallback: Span) -> Span {
|
||||
if def_id.krate == LOCAL_CRATE {
|
||||
self.span(def_id.node)
|
||||
} else {
|
||||
fallback
|
||||
}
|
||||
}
|
||||
|
||||
pub fn node_to_string(&self, id: NodeId) -> String {
|
||||
node_id_to_string(self, id)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user