rustc: Don't error out early when constructing a boxed trait.
This improves error messages a bit and helps pave the way for "@int as @Trait" (as opposed to "int as @Trait").
This commit is contained in:
parent
f78cdcb636
commit
5e7ff924b5
@ -51,8 +51,13 @@ fn lookup_vtables(fcx: @fn_ctxt,
|
||||
match *bound {
|
||||
ty::bound_trait(i_ty) => {
|
||||
let i_ty = ty::subst(tcx, substs, i_ty);
|
||||
result.push(lookup_vtable(fcx, expr, *ty, i_ty,
|
||||
allow_unsafe, is_early));
|
||||
match lookup_vtable(fcx, expr, *ty, i_ty, allow_unsafe,
|
||||
is_early) {
|
||||
None => {}
|
||||
Some(vtable) => {
|
||||
result.push(vtable);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
@ -91,7 +96,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
||||
trait_ty: ty::t,
|
||||
allow_unsafe: bool,
|
||||
is_early: bool)
|
||||
-> vtable_origin
|
||||
-> Option<vtable_origin>
|
||||
{
|
||||
|
||||
debug!("lookup_vtable(ty=%s, trait_ty=%s)",
|
||||
@ -113,7 +118,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
||||
// 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 vtable_param(0, 0);
|
||||
return Some(vtable_param(0, 0));
|
||||
}
|
||||
};
|
||||
|
||||
@ -135,7 +140,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
||||
idid);
|
||||
relate_trait_tys(fcx, expr,
|
||||
trait_ty, ity);
|
||||
return vtable_param(n, n_bound);
|
||||
return Some(vtable_param(n, n_bound));
|
||||
}
|
||||
}
|
||||
_ => tcx.sess.impossible_case(
|
||||
@ -170,7 +175,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
||||
}
|
||||
}
|
||||
}
|
||||
return vtable_trait(did, substs.tps);
|
||||
return Some(vtable_trait(did, substs.tps));
|
||||
}
|
||||
|
||||
_ => {
|
||||
@ -303,7 +308,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
||||
None => {
|
||||
assert is_early;
|
||||
// Bail out with a bogus answer
|
||||
return vtable_param(0, 0);
|
||||
return Some(vtable_param(0, 0));
|
||||
}
|
||||
};
|
||||
|
||||
@ -341,23 +346,20 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
||||
|
||||
match found.len() {
|
||||
0 => { /* fallthrough */ }
|
||||
1 => { return found[0]; }
|
||||
1 => { return Some(found[0]); }
|
||||
_ => {
|
||||
if !is_early {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
expr.span,
|
||||
~"multiple applicable methods in scope");
|
||||
}
|
||||
return found[0];
|
||||
return Some(found[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tcx.sess.span_fatal(
|
||||
expr.span,
|
||||
fmt!("failed to find an implementation of trait %s for %s",
|
||||
ty_to_str(tcx, trait_ty), ty_to_str(tcx, ty)));
|
||||
return None;
|
||||
}
|
||||
|
||||
fn fixup_ty(fcx: @fn_ctxt,
|
||||
@ -459,13 +461,26 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
|
||||
Look up vtables for the type we're casting to,
|
||||
passing in the source and target type
|
||||
*/
|
||||
let vtable = lookup_vtable(fcx, ex, fcx.expr_ty(src),
|
||||
target_ty, true, is_early);
|
||||
/*
|
||||
Map this expression to that vtable (that is: "ex has
|
||||
vtable <vtable>")
|
||||
*/
|
||||
if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); }
|
||||
let ty = fcx.expr_ty(src);
|
||||
let vtable_opt = lookup_vtable(fcx, ex, ty, target_ty, true,
|
||||
is_early);
|
||||
match vtable_opt {
|
||||
None => {
|
||||
fcx.tcx().sess.span_err(
|
||||
ex.span,
|
||||
fmt!("failed to find an implementation of trait %s \
|
||||
for %s",
|
||||
ty_to_str(fcx.tcx(), target_ty),
|
||||
ty_to_str(fcx.tcx(), ty)));
|
||||
}
|
||||
Some(vtable) => {
|
||||
/*
|
||||
Map this expression to that vtable (that is: "ex has
|
||||
vtable <vtable>")
|
||||
*/
|
||||
if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); }
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user