diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 53b3c8fce077..3d0c612a085c 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2537,17 +2537,24 @@ mod unify { // Fixups and substitutions fn fixup_vars(ty_ctxt tcx, @var_bindings vb, t typ) -> fixup_result { - fn subst_vars(ty_ctxt tcx, @var_bindings vb, t typ) -> t { + fn subst_vars(ty_ctxt tcx, @var_bindings vb, + @mutable option::t[int] unresolved, t typ) -> t { alt (struct(tcx, typ)) { case (ty::ty_var(?vid)) { + if ((vid as uint) >= ufind::set_count(vb.sets)) { + *unresolved = some[int](vid); + ret typ; + } + auto root_id = ufind::find(vb.sets, vid as uint); alt (smallintmap::find[t](vb.types, root_id)) { case (none[t]) { - log_err "unresolved type variable"; - fail; + *unresolved = some[int](vid); + ret typ; } case (some[t](?rt)) { - ret fold_ty(tcx, bind subst_vars(tcx, vb, _), rt); + ret fold_ty(tcx, + bind subst_vars(tcx, vb, unresolved, _), rt); } } } @@ -2555,24 +2562,22 @@ mod unify { } } - // FIXME: Report errors better. - ret fix_ok(fold_ty(tcx, bind subst_vars(tcx, vb, _), typ)); + auto unresolved = @mutable none[int]; + auto rty = fold_ty(tcx, bind subst_vars(tcx, vb, unresolved, _), typ); + + auto ur = *unresolved; + alt (ur) { + case (none[int]) { ret fix_ok(rty); } + case (some[int](?var_id)) { ret fix_err(var_id); } + } } - fn resolve_type_var(&ty_ctxt tcx, &@var_bindings vb, int vid) -> t { + fn resolve_type_var(&ty_ctxt tcx, &@var_bindings vb, int vid) + -> fixup_result { auto root_id = ufind::find(vb.sets, vid as uint); alt (smallintmap::find[t](vb.types, root_id)) { - case (none[t]) { ret mk_var(tcx, vid); } - case (some[t](?rt)) { - alt (fixup_vars(tcx, vb, rt)) { - case (fix_ok(?rty)) { ret rty; } - case (fix_err(_)) { - // TODO: antisocial - log_err "failed to resolve type var"; - fail; - } - } - } + case (none[t]) { ret fix_ok(mk_var(tcx, vid)); } + case (some[t](?rt)) { ret fixup_vars(tcx, vb, rt); } } } } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index d604ad9a3906..db3f3ede0c70 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1387,11 +1387,8 @@ mod writeback { alt (ty::unify::fixup_vars(fcx.ccx.tcx, fcx.var_bindings, typ)) { case (fix_ok(?new_type)) { ret new_type; } case (fix_err(?vid)) { - // TODO: We should try to do a variable ID -> local lookup if - // we can and display this in terms of the local that had an - // incomplete type. - fcx.ccx.tcx.sess.span_err(sp, #fmt( - "cannot determine type of variable ID `%d`", vid)); + fcx.ccx.tcx.sess.span_err(sp, + "cannot determine a type for this expression"); } } } @@ -1434,11 +1431,19 @@ mod writeback { fn visit_decl_pre(@fn_ctxt fcx, &@ast::decl d) { alt (d.node) { case (ast::decl_local(?l)) { - // FIXME: Report errors better. auto var_id = fcx.locals.get(l.id); - auto lty = ty::unify::resolve_type_var(fcx.ccx.tcx, + auto fix_rslt = ty::unify::resolve_type_var(fcx.ccx.tcx, fcx.var_bindings, var_id); - write::ty_only(fcx.ccx.tcx, l.ann.id, lty); + alt (fix_rslt) { + case (fix_ok(?lty)) { + write::ty_only(fcx.ccx.tcx, l.ann.id, lty); + } + case (fix_err(_)) { + fcx.ccx.tcx.sess.span_err(d.span, + "cannot determine a type for this local " + + "variable"); + } + } } case (_) { /* no-op */ } } diff --git a/src/test/compile-fail/vector-no-ann.rs b/src/test/compile-fail/vector-no-ann.rs index 912fb0a388ac..b492f103c203 100644 --- a/src/test/compile-fail/vector-no-ann.rs +++ b/src/test/compile-fail/vector-no-ann.rs @@ -1,6 +1,6 @@ // xfail-stage0 -// error-pattern:Ambiguous type +// error-pattern:cannot determine a type fn main() -> () { auto foo = []; }