Skip to content

Commit 24cd846

Browse files
committed
---
yaml --- r: 11733 b: refs/heads/master c: 4ffcb95 h: refs/heads/master i: 11731: 5e8fca4 v: v3
1 parent 95958a9 commit 24cd846

File tree

5 files changed

+155
-3
lines changed

5 files changed

+155
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 7f55e7d0870756712c0926f5b3621147dc9a82a4
2+
refs/heads/master: 4ffcb959744194413ca20223274d2c351ad7686c
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/rustc/driver/driver.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
140140
let freevars =
141141
time(time_passes, "freevar finding",
142142
bind freevars::annotate_freevars(def_map, crate));
143-
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars);
143+
let region_map =
144+
time(time_passes, "region resolution",
145+
bind middle::region::resolve_crate(sess, crate));
146+
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, region_map);
144147
let (method_map, dict_map) =
145148
time(time_passes, "typechecking",
146149
bind typeck::check_crate(ty_cx, impl_map, crate));

trunk/src/rustc/middle/region.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Region resolution. This pass runs before typechecking and resolves region
3+
* names to the appropriate block.
4+
*/
5+
6+
import driver::session::session;
7+
import middle::ty;
8+
import syntax::{ast, visit};
9+
import std::map;
10+
import std::map::hashmap;
11+
12+
type region_map = {
13+
parent_blocks: hashmap<ast::node_id,ast::node_id>,
14+
ast_type_to_region: hashmap<ast::node_id,ty::region>
15+
};
16+
17+
enum parent {
18+
pa_item(ast::node_id),
19+
pa_block(ast::node_id),
20+
pa_crate
21+
}
22+
23+
type ctxt = {
24+
sess: session,
25+
region_map: @region_map,
26+
names_in_scope: hashmap<str,ast::def_id>,
27+
parent: parent
28+
};
29+
30+
fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
31+
alt ty.node {
32+
ast::ty_rptr({id: region_id, node: node}, _) {
33+
let region;
34+
alt node {
35+
ast::re_inferred {
36+
// We infer to the caller region if we're at item scope
37+
// and to the block region if we're at block scope.
38+
alt cx.parent {
39+
pa_item(item_id) {
40+
let def_id = {crate: ast::local_crate,
41+
node: item_id};
42+
region = ty::re_caller(def_id);
43+
}
44+
pa_block(block_id) {
45+
region = ty::re_block(block_id);
46+
}
47+
pa_crate {
48+
cx.sess.span_bug(ty.span,
49+
"region type outside item");
50+
}
51+
}
52+
}
53+
54+
ast::re_named(ident) {
55+
// If at item scope, introduce or reuse a binding. If at
56+
// block scope, require that the binding be introduced.
57+
alt cx.names_in_scope.find(ident) {
58+
some(def_id) { region = ty::re_named(def_id); }
59+
none {
60+
alt cx.parent {
61+
pa_item(_) { /* ok; fall through */ }
62+
pa_block(_) {
63+
cx.sess.span_err(ty.span,
64+
"unknown region `" +
65+
ident + "`");
66+
}
67+
pa_crate {
68+
cx.sess.span_bug(ty.span,
69+
"named region at " +
70+
"crate scope?!");
71+
}
72+
}
73+
74+
let def_id = {crate: ast::local_crate,
75+
node: region_id};
76+
cx.names_in_scope.insert(ident, def_id);
77+
region = ty::re_named(def_id);
78+
}
79+
}
80+
}
81+
82+
ast::re_self {
83+
// For blocks, "self" means "the current block".
84+
alt cx.parent {
85+
pa_item(_) {
86+
cx.sess.span_unimpl(ty.span,
87+
"'self' region for items");
88+
}
89+
pa_block(block_id) {
90+
region = ty::re_block(block_id);
91+
}
92+
pa_crate {
93+
cx.sess.span_bug(ty.span,
94+
"region type outside item");
95+
}
96+
}
97+
}
98+
99+
}
100+
101+
cx.region_map.ast_type_to_region.insert(region_id, region);
102+
}
103+
_ { /* nothing to do */ }
104+
}
105+
106+
visit::visit_ty(ty, cx, visitor);
107+
}
108+
109+
fn resolve_block(blk: ast::blk, cx: ctxt, visitor: visit::vt<ctxt>) {
110+
alt cx.parent {
111+
pa_item(_) { /* no-op */ }
112+
pa_block(parent_block_id) {
113+
cx.region_map.parent_blocks.insert(blk.node.id, parent_block_id);
114+
}
115+
pa_crate { cx.sess.span_bug(blk.span, "block outside item?!"); }
116+
}
117+
118+
let new_cx: ctxt = {parent: pa_block(blk.node.id) with cx};
119+
visit::visit_block(blk, new_cx, visitor);
120+
}
121+
122+
fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt<ctxt>) {
123+
// Items create a new outer block scope as far as we're concerned.
124+
let new_cx: ctxt = {names_in_scope: map::new_str_hash(),
125+
parent: pa_item(item.id)
126+
with cx};
127+
visit::visit_item(item, new_cx, visitor);
128+
}
129+
130+
fn resolve_crate(sess: session, crate: @ast::crate) -> @region_map {
131+
let cx: ctxt = {sess: sess,
132+
region_map: @{parent_blocks: map::new_int_hash(),
133+
ast_type_to_region: map::new_int_hash()},
134+
names_in_scope: map::new_str_hash(),
135+
parent: pa_crate};
136+
let visitor = visit::mk_vt(@{
137+
visit_block: resolve_block,
138+
visit_item: resolve_item,
139+
visit_ty: resolve_ty
140+
with *visit::default_visitor()
141+
});
142+
visit::visit_crate(*crate, cx, visitor);
143+
ret cx.region_map;
144+
}
145+

trunk/src/rustc/middle/ty.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ type ctxt =
167167
mutable next_id: uint,
168168
sess: session::session,
169169
def_map: resolve::def_map,
170+
region_map: @middle::region::region_map,
170171
node_types: node_type_table,
171172
node_type_substs: hashmap<node_id, [t]>,
172173
items: ast_map::map,
@@ -327,7 +328,8 @@ fn new_ty_hash<V: copy>() -> map::hashmap<t, V> {
327328
}
328329

329330
fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
330-
freevars: freevars::freevar_map) -> ctxt {
331+
freevars: freevars::freevar_map,
332+
region_map: @middle::region::region_map) -> ctxt {
331333
let interner = map::mk_hashmap({|&&k: intern_key|
332334
hash_type_structure(k.struct) +
333335
option::maybe(0u, k.o_def_id, ast_util::hash_def_id)
@@ -336,6 +338,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
336338
mutable next_id: 0u,
337339
sess: s,
338340
def_map: dm,
341+
region_map: region_map,
339342
node_types: @smallintmap::mk(),
340343
node_type_substs: map::new_int_hash(),
341344
items: amap,

trunk/src/rustc/rustc.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ mod middle {
4444
mod freevars;
4545
mod capture;
4646
mod pat_util;
47+
mod region;
4748

4849
mod tstate {
4950
mod ck;

0 commit comments

Comments
 (0)