@@ -3,7 +3,8 @@ import middle::ty;
3
3
import middle:: ty:: { arg, canon_mode} ;
4
4
import middle:: ty:: { bound_region, br_anon, br_named, br_self, br_cap_avoid} ;
5
5
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} ;
7
8
import middle:: ty:: { ty_bool, ty_bot, ty_box, ty_class, ty_enum} ;
8
9
import middle:: ty:: { ty_estr, ty_evec, ty_float, ty_fn, ty_trait, ty_int} ;
9
10
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};
12
13
import middle:: ty:: { ty_unboxed_vec, vid} ;
13
14
import metadata:: encoder;
14
15
import syntax:: codemap;
16
+ import syntax:: codemap:: span;
15
17
import syntax:: print:: pprust;
16
18
import syntax:: print:: pprust:: { path_to_str, proto_to_str,
17
19
mode_to_str, purity_to_str} ;
18
20
import syntax:: { ast, ast_util} ;
19
21
import syntax:: ast_map;
20
22
import driver:: session:: session;
21
23
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
+
22
78
fn bound_region_to_str(cx: ctxt, br: bound_region) -> ~str {
23
79
alt br {
24
80
br_anon => { ~" & " }
@@ -79,8 +135,16 @@ fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> ~str {
79
135
80
136
fn region_to_str(cx: ctxt, region: region) -> ~str {
81
137
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
+ }
84
148
re_free(id, br) {
85
149
if cx.sess.ppregions() {
86
150
// For debugging, this version is sometimes helpful:
0 commit comments