Skip to content

Commit 22e7491

Browse files
committed
---
yaml --- r: 14784 b: refs/heads/try c: e968672 h: refs/heads/master v: v3
1 parent 5ff19c0 commit 22e7491

File tree

3 files changed

+86
-9
lines changed

3 files changed

+86
-9
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: d3035a1b205caef6279c91b276e672c54318838c
5+
refs/heads/try: e968672ac7b4fe840b2b1561585f7ca7d4fd892d
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/rustc/driver/driver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
142142
bind freevars::annotate_freevars(def_map, crate));
143143
let region_map =
144144
time(time_passes, "region resolution",
145-
bind middle::region::resolve_crate(sess, crate));
145+
bind middle::region::resolve_crate(sess, def_map, crate));
146146
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, region_map);
147147
let (method_map, dict_map) =
148148
time(time_passes, "typechecking",

branches/try/src/rustc/middle/region.rs

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,36 @@ import std::map;
1010
import std::map::hashmap;
1111

1212
type region_map = {
13+
/* Mapping from a block to its parent block, if there is one. */
1314
parent_blocks: hashmap<ast::node_id,ast::node_id>,
14-
ast_type_to_region: hashmap<ast::node_id,ty::region>
15+
/* Mapping from a region type in the AST to its resolved region. */
16+
ast_type_to_region: hashmap<ast::node_id,ty::region>,
17+
/* Mapping from a local variable to its containing block. */
18+
local_blocks: hashmap<ast::node_id,ast::node_id>
1519
};
1620

21+
/* Represents the type of the most immediate parent node. */
1722
enum parent {
1823
pa_item(ast::node_id),
1924
pa_block(ast::node_id),
25+
pa_alt,
2026
pa_crate
2127
}
2228

2329
type ctxt = {
2430
sess: session,
31+
def_map: resolve::def_map,
2532
region_map: @region_map,
2633
names_in_scope: hashmap<str,ast::def_id>,
34+
35+
/*
36+
* A list of local IDs that will be parented to the next block we traverse.
37+
* This is used when resolving `alt` statements. Since we see the pattern
38+
* before the associated block, upon seeing a pattern we must parent all the
39+
* bindings in that pattern to the next block we see.
40+
*/
41+
mut queued_locals: [ast::node_id],
42+
2743
parent: parent
2844
};
2945

@@ -44,6 +60,12 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
4460
pa_block(block_id) {
4561
region = ty::re_block(block_id);
4662
}
63+
pa_alt {
64+
// FIXME: Need a design decision here.
65+
cx.sess.span_bug(ty.span,
66+
"what does & in an alt " +
67+
"resolve to?");
68+
}
4769
pa_crate {
4870
cx.sess.span_bug(ty.span,
4971
"region type outside item");
@@ -59,7 +81,7 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
5981
none {
6082
alt cx.parent {
6183
pa_item(_) { /* ok; fall through */ }
62-
pa_block(_) {
84+
pa_block(_) | pa_alt {
6385
cx.sess.span_err(ty.span,
6486
"unknown region `" +
6587
ident + "`");
@@ -89,6 +111,12 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
89111
pa_block(block_id) {
90112
region = ty::re_block(block_id);
91113
}
114+
pa_alt {
115+
// FIXME: Need a design decision here.
116+
cx.sess.span_bug(ty.span,
117+
"what does &self. in an alt " +
118+
"resolve to?");
119+
}
92120
pa_crate {
93121
cx.sess.span_bug(ty.span,
94122
"region type outside item");
@@ -108,17 +136,60 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
108136

109137
fn resolve_block(blk: ast::blk, cx: ctxt, visitor: visit::vt<ctxt>) {
110138
alt cx.parent {
111-
pa_item(_) { /* no-op */ }
139+
pa_item(_) | pa_alt { /* no-op */ }
112140
pa_block(parent_block_id) {
113141
cx.region_map.parent_blocks.insert(blk.node.id, parent_block_id);
114142
}
115143
pa_crate { cx.sess.span_bug(blk.span, "block outside item?!"); }
116144
}
117145

118-
let new_cx: ctxt = {parent: pa_block(blk.node.id) with cx};
146+
// Resolve queued locals to this block.
147+
for local_id in cx.queued_locals {
148+
cx.region_map.local_blocks.insert(local_id, blk.node.id);
149+
}
150+
151+
let new_cx: ctxt = {parent: pa_block(blk.node.id),
152+
mut queued_locals: [] with cx};
119153
visit::visit_block(blk, new_cx, visitor);
120154
}
121155

156+
fn resolve_arm(arm: ast::arm, cx: ctxt, visitor: visit::vt<ctxt>) {
157+
let new_cx: ctxt = {parent: pa_alt,
158+
mut queued_locals: [] with cx};
159+
visit::visit_arm(arm, new_cx, visitor);
160+
}
161+
162+
fn resolve_pat(pat: @ast::pat, cx: ctxt, visitor: visit::vt<ctxt>) {
163+
alt pat.node {
164+
ast::pat_ident(path, _) {
165+
let defn_opt = cx.def_map.find(pat.id);
166+
alt defn_opt {
167+
some(ast::def_variant(_,_)) {
168+
/* Nothing to do; this names a variant. */
169+
}
170+
_ {
171+
/*
172+
* This names a local. Enqueue it or bind it to the containing
173+
* block, depending on whether we're in an alt or not.
174+
*/
175+
alt cx.parent {
176+
pa_block(block_id) {
177+
cx.region_map.local_blocks.insert(pat.id, block_id);
178+
}
179+
pa_alt {
180+
vec::push(cx.queued_locals, pat.id);
181+
}
182+
_ { cx.sess.span_bug(pat.span, "unexpected parent"); }
183+
}
184+
}
185+
}
186+
}
187+
_ { /* no-op */ }
188+
}
189+
190+
visit::visit_pat(pat, cx, visitor);
191+
}
192+
122193
fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt<ctxt>) {
123194
// Items create a new outer block scope as far as we're concerned.
124195
let new_cx: ctxt = {names_in_scope: map::new_str_hash(),
@@ -127,16 +198,22 @@ fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt<ctxt>) {
127198
visit::visit_item(item, new_cx, visitor);
128199
}
129200

130-
fn resolve_crate(sess: session, crate: @ast::crate) -> @region_map {
201+
fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
202+
-> @region_map {
131203
let cx: ctxt = {sess: sess,
204+
def_map: def_map,
132205
region_map: @{parent_blocks: map::new_int_hash(),
133-
ast_type_to_region: map::new_int_hash()},
206+
ast_type_to_region: map::new_int_hash(),
207+
local_blocks: map::new_int_hash()},
134208
names_in_scope: map::new_str_hash(),
209+
mut queued_locals: [],
135210
parent: pa_crate};
136211
let visitor = visit::mk_vt(@{
137212
visit_block: resolve_block,
138213
visit_item: resolve_item,
139-
visit_ty: resolve_ty
214+
visit_ty: resolve_ty,
215+
visit_arm: resolve_arm,
216+
visit_pat: resolve_pat
140217
with *visit::default_visitor()
141218
});
142219
visit::visit_crate(*crate, cx, visitor);

0 commit comments

Comments
 (0)