rustc: Print out a real error message on unresolved types. Puts out burning tinderbox.

This commit is contained in:
Patrick Walton 2011-06-07 23:03:41 -07:00
parent ddec6b5f47
commit 0857d22c04
3 changed files with 37 additions and 27 deletions

View File

@ -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); }
}
}
}

View File

@ -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 */ }
}

View File

@ -1,6 +1,6 @@
// xfail-stage0
// error-pattern:Ambiguous type
// error-pattern:cannot determine a type
fn main() -> () {
auto foo = [];
}