Skip to content

Commit 864ff47

Browse files
committed
rustc: Map region names to their functions. Also speed up region checking by 17x.
1 parent db79f3c commit 864ff47

File tree

3 files changed

+65
-42
lines changed

3 files changed

+65
-42
lines changed

src/rustc/middle/region.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import driver::session::session;
77
import middle::ty;
88
import syntax::{ast, visit};
9+
import util::common::new_def_hash;
10+
911
import std::map;
1012
import std::map::hashmap;
1113

@@ -27,6 +29,8 @@ type region_map = {
2729
ast_type_to_region: hashmap<ast::node_id,ty::region>,
2830
/* Mapping from a local variable to its containing block. */
2931
local_blocks: hashmap<ast::node_id,ast::node_id>,
32+
/* Mapping from a region name to its function. */
33+
region_name_to_fn: hashmap<ast::def_id,ast::node_id>,
3034
};
3135

3236
type ctxt = {
@@ -105,9 +109,15 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
105109
alt cx.names_in_scope.find(ident) {
106110
some(def_id) { region = ty::re_named(def_id); }
107111
none {
112+
let def_id = {crate: ast::local_crate,
113+
node: region_id};
114+
cx.names_in_scope.insert(ident, def_id);
115+
region = ty::re_named(def_id);
116+
108117
alt cx.parent {
109-
pa_item(_) | pa_nested_fn(_) {
110-
/* ok; fall through */
118+
pa_item(fn_id) | pa_nested_fn(fn_id) {
119+
let rf = cx.region_map.region_name_to_fn;
120+
rf.insert(def_id, fn_id);
111121
}
112122
pa_block(_) {
113123
cx.sess.span_err(ty.span,
@@ -120,11 +130,6 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
120130
"level?!");
121131
}
122132
}
123-
124-
let def_id = {crate: ast::local_crate,
125-
node: region_id};
126-
cx.names_in_scope.insert(ident, def_id);
127-
region = ty::re_named(def_id);
128133
}
129134
}
130135
}
@@ -256,7 +261,8 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
256261
def_map: def_map,
257262
region_map: @{parents: map::new_int_hash(),
258263
ast_type_to_region: map::new_int_hash(),
259-
local_blocks: map::new_int_hash()},
264+
local_blocks: map::new_int_hash(),
265+
region_name_to_fn: new_def_hash()},
260266
names_in_scope: map::new_str_hash(),
261267
mut queued_locals: [],
262268
parent: pa_crate,

src/rustc/middle/regionck.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,37 @@ type ctxt = {
2222
};
2323

2424
fn check_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
25-
ty::walk_ty(cx.tcx, ty::expr_ty(cx.tcx, expr)) { |t|
26-
alt ty::get(t).struct {
27-
ty::ty_rptr(region, _) {
28-
alt region {
29-
ty::re_named(_) | ty::re_caller(_) { /* ok */ }
30-
ty::re_block(rbi) {
31-
let referent_block_id = rbi;
32-
let enclosing_block_id = alt cx.enclosing_block {
33-
none {
34-
cx.tcx.sess.span_bug(expr.span, "block " +
35-
"region type outside " +
36-
"a block?!");
37-
}
38-
some(eb) { eb }
39-
};
25+
let t = ty::expr_ty(cx.tcx, expr);
26+
if ty::type_has_rptrs(t) {
27+
ty::walk_ty(cx.tcx, t) { |t|
28+
alt ty::get(t).struct {
29+
ty::ty_rptr(region, _) {
30+
alt region {
31+
ty::re_named(_) | ty::re_caller(_) { /* ok */ }
32+
ty::re_block(rbi) {
33+
let referent_block_id = rbi;
34+
let enclosing_block_id = alt cx.enclosing_block {
35+
none {
36+
cx.tcx.sess.span_bug(expr.span,
37+
"block region " +
38+
"type outside a " +
39+
"block?!");
40+
}
41+
some(eb) { eb }
42+
};
4043

41-
if !region::scope_contains(cx.tcx.region_map,
42-
referent_block_id,
43-
enclosing_block_id) {
44+
if !region::scope_contains(cx.tcx.region_map,
45+
referent_block_id,
46+
enclosing_block_id) {
4447

45-
cx.tcx.sess.span_err(expr.span, "reference " +
46-
"escapes its block");
48+
cx.tcx.sess.span_err(expr.span, "reference " +
49+
"escapes its block");
50+
}
4751
}
4852
}
4953
}
54+
_ { /* no-op */ }
5055
}
51-
_ { /* no-op */ }
5256
}
5357
}
5458

src/rustc/middle/ty.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
8989
export ty_var, mk_var;
9090
export ty_self, mk_self;
9191
export region, re_named, re_caller, re_block;
92-
export get, type_has_params, type_has_vars, type_id;
92+
export get, type_has_params, type_has_vars, type_has_rptrs, type_id;
9393
export same_type;
9494
export ty_var_id;
9595
export ty_fn_args;
@@ -187,6 +187,7 @@ type t_box = @{struct: sty,
187187
id: uint,
188188
has_params: bool,
189189
has_vars: bool,
190+
has_rptrs: bool,
190191
o_def_id: option<ast::def_id>};
191192

192193
// To reduce refcounting cost, we're representing types as unsafe pointers
@@ -206,6 +207,7 @@ pure fn get(t: t) -> t_box unsafe {
206207

207208
fn type_has_params(t: t) -> bool { get(t).has_params }
208209
fn type_has_vars(t: t) -> bool { get(t).has_vars }
210+
fn type_has_rptrs(t: t) -> bool { get(t).has_rptrs }
209211
fn type_def_id(t: t) -> option<ast::def_id> { get(t).o_def_id }
210212
fn type_id(t: t) -> uint { get(t).id }
211213

@@ -368,11 +370,13 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
368370
some(t) { unsafe { ret unsafe::reinterpret_cast(t); } }
369371
_ {}
370372
}
371-
let has_params = false, has_vars = false;
372-
fn derive_flags(&has_params: bool, &has_vars: bool, tt: t) {
373+
let has_params = false, has_vars = false, has_rptrs = false;
374+
fn derive_flags(&has_params: bool, &has_vars: bool, &has_rptrs: bool,
375+
tt: t) {
373376
let t = get(tt);
374377
has_params |= t.has_params;
375378
has_vars |= t.has_vars;
379+
has_rptrs |= t.has_rptrs;
376380
}
377381
alt st {
378382
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
@@ -381,33 +385,42 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
381385
ty_param(_, _) { has_params = true; }
382386
ty_var(_) | ty_self(_) { has_vars = true; }
383387
ty_enum(_, tys) | ty_iface(_, tys) | ty_class(_, tys) {
384-
for tt in tys { derive_flags(has_params, has_vars, tt); }
388+
for tt in tys { derive_flags(has_params, has_vars, has_rptrs, tt); }
385389
}
386-
ty_box(m) | ty_uniq(m) | ty_vec(m) | ty_ptr(m) | ty_rptr(_, m) {
387-
derive_flags(has_params, has_vars, m.ty);
390+
ty_box(m) | ty_uniq(m) | ty_vec(m) | ty_ptr(m) {
391+
derive_flags(has_params, has_vars, has_rptrs, m.ty);
392+
}
393+
ty_rptr(_, m) {
394+
has_rptrs = true;
395+
derive_flags(has_params, has_vars, has_rptrs, m.ty);
388396
}
389397
ty_rec(flds) {
390-
for f in flds { derive_flags(has_params, has_vars, f.mt.ty); }
398+
for f in flds {
399+
derive_flags(has_params, has_vars, has_rptrs, f.mt.ty);
400+
}
391401
}
392402
ty_tup(ts) {
393-
for tt in ts { derive_flags(has_params, has_vars, tt); }
403+
for tt in ts { derive_flags(has_params, has_vars, has_rptrs, tt); }
394404
}
395405
ty_fn(f) {
396-
for a in f.inputs { derive_flags(has_params, has_vars, a.ty); }
397-
derive_flags(has_params, has_vars, f.output);
406+
for a in f.inputs {
407+
derive_flags(has_params, has_vars, has_rptrs, a.ty);
408+
}
409+
derive_flags(has_params, has_vars, has_rptrs, f.output);
398410
}
399411
ty_res(_, tt, tps) {
400-
derive_flags(has_params, has_vars, tt);
401-
for tt in tps { derive_flags(has_params, has_vars, tt); }
412+
derive_flags(has_params, has_vars, has_rptrs, tt);
413+
for tt in tps { derive_flags(has_params, has_vars, has_rptrs, tt); }
402414
}
403415
ty_constr(tt, _) {
404-
derive_flags(has_params, has_vars, tt);
416+
derive_flags(has_params, has_vars, has_rptrs, tt);
405417
}
406418
}
407419
let t = @{struct: st,
408420
id: cx.next_id,
409421
has_params: has_params,
410422
has_vars: has_vars,
423+
has_rptrs: has_rptrs,
411424
o_def_id: o_def_id};
412425
cx.interner.insert(key, t);
413426
cx.next_id += 1u;

0 commit comments

Comments
 (0)