Skip to content

Commit 5e7ff92

Browse files
committed
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").
1 parent f78cdcb commit 5e7ff92

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed

src/rustc/middle/typeck/check/vtable.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,13 @@ fn lookup_vtables(fcx: @fn_ctxt,
5151
match *bound {
5252
ty::bound_trait(i_ty) => {
5353
let i_ty = ty::subst(tcx, substs, i_ty);
54-
result.push(lookup_vtable(fcx, expr, *ty, i_ty,
55-
allow_unsafe, is_early));
54+
match lookup_vtable(fcx, expr, *ty, i_ty, allow_unsafe,
55+
is_early) {
56+
None => {}
57+
Some(vtable) => {
58+
result.push(vtable);
59+
}
60+
}
5661
}
5762
_ => ()
5863
}
@@ -91,7 +96,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
9196
trait_ty: ty::t,
9297
allow_unsafe: bool,
9398
is_early: bool)
94-
-> vtable_origin
99+
-> Option<vtable_origin>
95100
{
96101

97102
debug!("lookup_vtable(ty=%s, trait_ty=%s)",
@@ -113,7 +118,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
113118
// The type has unconstrained type variables in it, so we can't
114119
// do early resolution on it. Return some completely bogus vtable
115120
// information: we aren't storing it anyways.
116-
return vtable_param(0, 0);
121+
return Some(vtable_param(0, 0));
117122
}
118123
};
119124

@@ -135,7 +140,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
135140
idid);
136141
relate_trait_tys(fcx, expr,
137142
trait_ty, ity);
138-
return vtable_param(n, n_bound);
143+
return Some(vtable_param(n, n_bound));
139144
}
140145
}
141146
_ => tcx.sess.impossible_case(
@@ -170,7 +175,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
170175
}
171176
}
172177
}
173-
return vtable_trait(did, substs.tps);
178+
return Some(vtable_trait(did, substs.tps));
174179
}
175180

176181
_ => {
@@ -303,7 +308,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
303308
None => {
304309
assert is_early;
305310
// Bail out with a bogus answer
306-
return vtable_param(0, 0);
311+
return Some(vtable_param(0, 0));
307312
}
308313
};
309314

@@ -341,23 +346,20 @@ fn lookup_vtable(fcx: @fn_ctxt,
341346

342347
match found.len() {
343348
0 => { /* fallthrough */ }
344-
1 => { return found[0]; }
349+
1 => { return Some(found[0]); }
345350
_ => {
346351
if !is_early {
347352
fcx.ccx.tcx.sess.span_err(
348353
expr.span,
349354
~"multiple applicable methods in scope");
350355
}
351-
return found[0];
356+
return Some(found[0]);
352357
}
353358
}
354359
}
355360
}
356361

357-
tcx.sess.span_fatal(
358-
expr.span,
359-
fmt!("failed to find an implementation of trait %s for %s",
360-
ty_to_str(tcx, trait_ty), ty_to_str(tcx, ty)));
362+
return None;
361363
}
362364

363365
fn fixup_ty(fcx: @fn_ctxt,
@@ -459,13 +461,26 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
459461
Look up vtables for the type we're casting to,
460462
passing in the source and target type
461463
*/
462-
let vtable = lookup_vtable(fcx, ex, fcx.expr_ty(src),
463-
target_ty, true, is_early);
464-
/*
465-
Map this expression to that vtable (that is: "ex has
466-
vtable <vtable>")
467-
*/
468-
if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); }
464+
let ty = fcx.expr_ty(src);
465+
let vtable_opt = lookup_vtable(fcx, ex, ty, target_ty, true,
466+
is_early);
467+
match vtable_opt {
468+
None => {
469+
fcx.tcx().sess.span_err(
470+
ex.span,
471+
fmt!("failed to find an implementation of trait %s \
472+
for %s",
473+
ty_to_str(fcx.tcx(), target_ty),
474+
ty_to_str(fcx.tcx(), ty)));
475+
}
476+
Some(vtable) => {
477+
/*
478+
Map this expression to that vtable (that is: "ex has
479+
vtable <vtable>")
480+
*/
481+
if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); }
482+
}
483+
}
469484
}
470485
_ => ()
471486
}

0 commit comments

Comments
 (0)