rustc: Describe why regions failed to unify as part of the type error message

This commit is contained in:
Patrick Walton 2012-03-15 19:19:32 -07:00
parent 4ea3b0b89c
commit e464e2ba56
3 changed files with 26 additions and 16 deletions

View File

@ -8,6 +8,7 @@ import syntax::ast_util;
import syntax::codemap::span; import syntax::codemap::span;
import metadata::csearch; import metadata::csearch;
import util::common::*; import util::common::*;
import util::ppaux::region_to_str;
import util::ppaux::ty_to_str; import util::ppaux::ty_to_str;
import util::ppaux::ty_constr_to_str; import util::ppaux::ty_constr_to_str;
import syntax::print::pprust::*; import syntax::print::pprust::*;
@ -295,7 +296,7 @@ enum type_err {
terr_mode_mismatch(mode, mode), terr_mode_mismatch(mode, mode),
terr_constr_len(uint, uint), terr_constr_len(uint, uint),
terr_constr_mismatch(@type_constr, @type_constr), terr_constr_mismatch(@type_constr, @type_constr),
terr_regions_differ, terr_regions_differ(bool /* variance */, region, region),
} }
enum param_bound { enum param_bound {
@ -1916,7 +1917,7 @@ mod unify {
ret if e_region == a_region { ret if e_region == a_region {
nxt(e_region) nxt(e_region)
} else { } else {
err(terr_regions_differ) err(terr_regions_differ(true, e_region, a_region))
}; };
} }
} }
@ -1925,7 +1926,7 @@ mod unify {
ret if sub == super { ret if sub == super {
nxt(super) nxt(super)
} else { } else {
err(terr_regions_differ) err(terr_regions_differ(true, super, sub))
}; };
} }
@ -1936,7 +1937,7 @@ mod unify {
if region::scope_contains(cx.tcx.region_map, subscope, superscope) { if region::scope_contains(cx.tcx.region_map, subscope, superscope) {
ret nxt(super); ret nxt(super);
} }
ret err(terr_regions_differ); ret err(terr_regions_differ(false, sub, super));
} }
fn unify_field<T:copy>( fn unify_field<T:copy>(
@ -2160,7 +2161,7 @@ fn same_type(cx: ctxt, a: t, b: t) -> bool {
} }
} }
fn type_err_to_str(err: type_err) -> str { fn type_err_to_str(cx: ctxt, err: type_err) -> str {
alt err { alt err {
terr_mismatch { ret "types differ"; } terr_mismatch { ret "types differ"; }
terr_ret_style_mismatch(expect, actual) { terr_ret_style_mismatch(expect, actual) {
@ -2212,8 +2213,15 @@ fn type_err_to_str(err: type_err) -> str {
" but found one with constraint " + " but found one with constraint " +
ty_constr_to_str(a_constr); ty_constr_to_str(a_constr);
} }
terr_regions_differ { terr_regions_differ(true, region_a, region_b) {
ret "inconsistent pointer lifetimes" ret #fmt("reference lifetime %s does not match reference lifetime %s",
region_to_str(cx, region_a), region_to_str(cx, region_b));
}
terr_regions_differ(false, subregion, superregion) {
ret #fmt("references with lifetime %s do not outlive references with \
lifetime %s",
region_to_str(cx, subregion),
region_to_str(cx, superregion));
} }
} }
} }

View File

@ -767,7 +767,7 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span, impl_m: ty::method,
result::err(err) { result::err(err) {
tcx.sess.span_err(sp, "method `" + if_m.ident + tcx.sess.span_err(sp, "method `" + if_m.ident +
"` has an incompatible type: " + "` has an incompatible type: " +
ty::type_err_to_str(err)); ty::type_err_to_str(tcx, err));
impl_fty impl_fty
} }
result::ok(tp) { tp } result::ok(tp) { tp }
@ -1154,7 +1154,9 @@ mod demand {
ty_to_str(fcx.ccx.tcx, e_err) + ty_to_str(fcx.ccx.tcx, e_err) +
"` but found `" + "` but found `" +
ty_to_str(fcx.ccx.tcx, a_err) + ty_to_str(fcx.ccx.tcx, a_err) +
"` (" + ty::type_err_to_str(err) + "` (" +
ty::type_err_to_str(fcx.ccx.tcx,
err) +
")"); ")");
ret mk_result(fcx, expected, ty_param_subst_var_ids); ret mk_result(fcx, expected, ty_param_subst_var_ids);
} }

View File

@ -12,19 +12,19 @@ import driver::session::session;
fn region_to_str(cx: ctxt, region: region) -> str { fn region_to_str(cx: ctxt, region: region) -> str {
alt region { alt region {
re_named(_) { "<name>." } // TODO: include name re_named(_) { "<name>" } // TODO: include name
re_caller(_) { "<caller>." } re_caller(_) { "<caller>" }
re_block(node_id) { re_block(node_id) {
alt cx.items.get(node_id) { alt cx.items.get(node_id) {
ast_map::node_block(blk) { ast_map::node_block(blk) {
#fmt("<block at %s>.", codemap::span_to_str(blk.span, #fmt("<block at %s>", codemap::span_to_str(blk.span,
cx.sess.codemap)) cx.sess.codemap))
} }
_ { cx.sess.bug("re_block refers to non-block") } _ { cx.sess.bug("re_block refers to non-block") }
} }
} }
re_self(_) { "self." } re_self(_) { "self" }
re_inferred { "" } re_inferred { "" }
} }
} }
@ -121,7 +121,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
ty_box(tm) { "@" + mt_to_str(cx, tm) } ty_box(tm) { "@" + mt_to_str(cx, tm) }
ty_uniq(tm) { "~" + mt_to_str(cx, tm) } ty_uniq(tm) { "~" + mt_to_str(cx, tm) }
ty_ptr(tm) { "*" + mt_to_str(cx, tm) } ty_ptr(tm) { "*" + mt_to_str(cx, tm) }
ty_rptr(r, tm) { "&" + region_to_str(cx, r) + mt_to_str(cx, tm) } ty_rptr(r, tm) { "&" + region_to_str(cx, r) + "." + mt_to_str(cx, tm) }
ty_vec(tm) { "[" + mt_to_str(cx, tm) + "]" } ty_vec(tm) { "[" + mt_to_str(cx, tm) + "]" }
ty_type { "type" } ty_type { "type" }
ty_rec(elems) { ty_rec(elems) {