Skip to content

Commit a334deb

Browse files
committed
change how we print and explain region types
1 parent c5437c0 commit a334deb

File tree

4 files changed

+75
-13
lines changed

4 files changed

+75
-13
lines changed

src/rustc/middle/ty.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import syntax::ast_util::{is_local, local_def, split_class_items,
99
new_def_hash};
1010
import syntax::codemap::span;
1111
import metadata::csearch;
12-
import util::ppaux::region_to_str;
13-
import util::ppaux::vstore_to_str;
12+
import util::ppaux::{region_to_str, explain_region, vstore_to_str};
1413
import middle::lint;
1514
import middle::lint::{get_lint_level, allow};
1615
import syntax::ast::*;
@@ -2590,10 +2589,9 @@ fn type_err_to_str(cx: ctxt, err: type_err) -> ~str {
25902589
~" but found " + mode_to_str(a_mode);
25912590
}
25922591
terr_regions_differ(subregion, superregion) {
2593-
ret fmt!{"references with lifetime %s do not necessarily \
2594-
outlive references with lifetime %s",
2595-
region_to_str(cx, subregion),
2596-
region_to_str(cx, superregion)};
2592+
ret fmt!{"%s does not necessarily outlive %s",
2593+
explain_region(cx, subregion),
2594+
explain_region(cx, superregion)};
25972595
}
25982596
terr_vstores_differ(k, e_vs, a_vs) {
25992597
ret fmt!{"%s storage differs: expected %s but found %s",

src/rustc/util/ppaux.rs

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import middle::ty;
33
import middle::ty::{arg, canon_mode};
44
import middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid};
55
import middle::ty::{ck_block, ck_box, ck_uniq, ctxt, field, method};
6-
import middle::ty::{mt, re_bound, re_free, re_scope, re_var, region, t};
6+
import middle::ty::{mt, t};
7+
import middle::ty::{re_bound, re_free, re_scope, re_var, re_static, region};
78
import middle::ty::{ty_bool, ty_bot, ty_box, ty_class, ty_enum};
89
import middle::ty::{ty_estr, ty_evec, ty_float, ty_fn, ty_trait, ty_int};
910
import middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
@@ -12,13 +13,68 @@ import middle::ty::{ty_type, ty_uniq, ty_uint, ty_var, ty_var_integral};
1213
import middle::ty::{ty_unboxed_vec, vid};
1314
import metadata::encoder;
1415
import syntax::codemap;
16+
import syntax::codemap::span;
1517
import syntax::print::pprust;
1618
import syntax::print::pprust::{path_to_str, proto_to_str,
1719
mode_to_str, purity_to_str};
1820
import syntax::{ast, ast_util};
1921
import syntax::ast_map;
2022
import driver::session::session;
2123

24+
/// Returns a string like "reference valid for the block at 27:31 in foo.rs"
25+
/// that attempts to explain a lifetime in a way it might plausibly be
26+
/// understood.
27+
fn explain_region(cx: ctxt, region: ty::region) -> ~str {
28+
ret alt region {
29+
re_scope(node_id) => {
30+
let scope_str = alt cx.items.find(node_id) {
31+
some(ast_map::node_block(blk)) => {
32+
explain_span(cx, ~"block", blk.span)
33+
}
34+
some(ast_map::node_expr(expr)) => {
35+
alt expr.node {
36+
ast::expr_call(*) => { explain_span(cx, ~"call", expr.span) }
37+
ast::expr_alt(*) => { explain_span(cx, ~"alt", expr.span) }
38+
_ => { explain_span(cx, ~"expression", expr.span) }
39+
}
40+
}
41+
some(_) | none => {
42+
// this really should not happen
43+
fmt!{"unknown scope: %d. Please report a bug.", node_id}
44+
}
45+
};
46+
fmt!{"reference valid for the %s", scope_str}
47+
}
48+
49+
re_free(id, br) => {
50+
alt cx.items.find(id) {
51+
some(ast_map::node_block(blk)) => {
52+
fmt!{"reference with lifetime %s as defined on %s",
53+
bound_region_to_str(cx, br),
54+
explain_span(cx, ~"the block", blk.span)}
55+
}
56+
some(_) | none => {
57+
// this really should not happen
58+
fmt!{"reference with lifetime %s as defined on node %d",
59+
bound_region_to_str(cx, br), id}
60+
}
61+
}
62+
}
63+
64+
re_static => { ~"reference to static data" }
65+
66+
// I believe these cases should not occur.
67+
re_var(_) | re_bound(_) => {
68+
fmt!{"reference with lifetime %?", region}
69+
}
70+
};
71+
72+
fn explain_span(cx: ctxt, heading: ~str, span: span) -> ~str {
73+
let lo = codemap::lookup_char_pos_adj(cx.sess.codemap, span.lo);
74+
fmt!{"%s at %u:%u", heading, lo.line, lo.col}
75+
}
76+
}
77+
2278
fn bound_region_to_str(cx: ctxt, br: bound_region) -> ~str {
2379
alt br {
2480
br_anon => { ~"&" }
@@ -79,8 +135,16 @@ fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> ~str {
79135
80136
fn region_to_str(cx: ctxt, region: region) -> ~str {
81137
alt region {
82-
re_scope(node_id) { fmt!{"&%s", re_scope_id_to_str(cx, node_id)} }
83-
re_bound(br) { bound_region_to_str(cx, br) }
138+
re_scope(node_id) {
139+
if cx.sess.ppregions() {
140+
fmt!{"&%s", re_scope_id_to_str(cx, node_id)}
141+
} else {
142+
~"&"
143+
}
144+
}
145+
re_bound(br) {
146+
bound_region_to_str(cx, br)
147+
}
84148
re_free(id, br) {
85149
if cx.sess.ppregions() {
86150
// For debugging, this version is sometimes helpful:

src/test/compile-fail/regions-nested-fns.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ fn nested(x: &x/int) {
77
ignore(fn&(z: &z/int) {
88
ay = x;
99
ay = &y;
10-
ay = z; //~ ERROR references with lifetime
10+
ay = z; //~ ERROR mismatched types
1111
});
1212

1313
ignore(fn&(z: &z/int) -> &z/int {
14-
if false { ret x; } //~ ERROR references with lifetime
15-
if false { ret ay; } //~ ERROR references with lifetime
14+
if false { ret x; } //~ ERROR mismatched types
15+
if false { ret ay; } //~ ERROR mismatched types
1616
ret z;
1717
});
1818
}

src/test/compile-fail/regions-scoping.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn nested(x: &x/int) { // (1)
4141
// let f: &x/int = foo(&z, &z, |_x, _y, z| z ); // ERROR mismatched types: expected `&x/int` but found
4242

4343
foo(x, &z, |x, _y, _z| x ); //~ ERROR mismatched types: expected `&z/int` but found `&x/int`
44-
foo(x, &z, |_x, y, _z| y ); //~ ERROR mismatched types: expected `&z/int` but found `&<expression at
44+
foo(x, &z, |_x, y, _z| y ); //~ ERROR mismatched types: expected `&z/int` but found `&
4545
}
4646
}
4747

0 commit comments

Comments
 (0)