From 5e7ff924b5931bb90f381d2bf5936616224d4e85 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 2 Oct 2012 15:29:16 -0700 Subject: [PATCH] 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"). --- src/rustc/middle/typeck/check/vtable.rs | 55 ++++++++++++++++--------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/rustc/middle/typeck/check/vtable.rs b/src/rustc/middle/typeck/check/vtable.rs index 0c9440f3ec2..550c32d0fa1 100644 --- a/src/rustc/middle/typeck/check/vtable.rs +++ b/src/rustc/middle/typeck/check/vtable.rs @@ -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 { 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 ") - */ - 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 ") + */ + if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); } + } + } } _ => () }