mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-01 19:23:50 +00:00
rustc: Perform region inference
This commit is contained in:
parent
7f55e7d087
commit
4ffcb95974
@ -140,7 +140,10 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
let freevars =
|
||||
time(time_passes, "freevar finding",
|
||||
bind freevars::annotate_freevars(def_map, crate));
|
||||
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars);
|
||||
let region_map =
|
||||
time(time_passes, "region resolution",
|
||||
bind middle::region::resolve_crate(sess, crate));
|
||||
let ty_cx = ty::mk_ctxt(sess, def_map, ast_map, freevars, region_map);
|
||||
let (method_map, dict_map) =
|
||||
time(time_passes, "typechecking",
|
||||
bind typeck::check_crate(ty_cx, impl_map, crate));
|
||||
|
145
src/rustc/middle/region.rs
Normal file
145
src/rustc/middle/region.rs
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Region resolution. This pass runs before typechecking and resolves region
|
||||
* names to the appropriate block.
|
||||
*/
|
||||
|
||||
import driver::session::session;
|
||||
import middle::ty;
|
||||
import syntax::{ast, visit};
|
||||
import std::map;
|
||||
import std::map::hashmap;
|
||||
|
||||
type region_map = {
|
||||
parent_blocks: hashmap<ast::node_id,ast::node_id>,
|
||||
ast_type_to_region: hashmap<ast::node_id,ty::region>
|
||||
};
|
||||
|
||||
enum parent {
|
||||
pa_item(ast::node_id),
|
||||
pa_block(ast::node_id),
|
||||
pa_crate
|
||||
}
|
||||
|
||||
type ctxt = {
|
||||
sess: session,
|
||||
region_map: @region_map,
|
||||
names_in_scope: hashmap<str,ast::def_id>,
|
||||
parent: parent
|
||||
};
|
||||
|
||||
fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
alt ty.node {
|
||||
ast::ty_rptr({id: region_id, node: node}, _) {
|
||||
let region;
|
||||
alt node {
|
||||
ast::re_inferred {
|
||||
// We infer to the caller region if we're at item scope
|
||||
// and to the block region if we're at block scope.
|
||||
alt cx.parent {
|
||||
pa_item(item_id) {
|
||||
let def_id = {crate: ast::local_crate,
|
||||
node: item_id};
|
||||
region = ty::re_caller(def_id);
|
||||
}
|
||||
pa_block(block_id) {
|
||||
region = ty::re_block(block_id);
|
||||
}
|
||||
pa_crate {
|
||||
cx.sess.span_bug(ty.span,
|
||||
"region type outside item");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::re_named(ident) {
|
||||
// If at item scope, introduce or reuse a binding. If at
|
||||
// block scope, require that the binding be introduced.
|
||||
alt cx.names_in_scope.find(ident) {
|
||||
some(def_id) { region = ty::re_named(def_id); }
|
||||
none {
|
||||
alt cx.parent {
|
||||
pa_item(_) { /* ok; fall through */ }
|
||||
pa_block(_) {
|
||||
cx.sess.span_err(ty.span,
|
||||
"unknown region `" +
|
||||
ident + "`");
|
||||
}
|
||||
pa_crate {
|
||||
cx.sess.span_bug(ty.span,
|
||||
"named region at " +
|
||||
"crate scope?!");
|
||||
}
|
||||
}
|
||||
|
||||
let def_id = {crate: ast::local_crate,
|
||||
node: region_id};
|
||||
cx.names_in_scope.insert(ident, def_id);
|
||||
region = ty::re_named(def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::re_self {
|
||||
// For blocks, "self" means "the current block".
|
||||
alt cx.parent {
|
||||
pa_item(_) {
|
||||
cx.sess.span_unimpl(ty.span,
|
||||
"'self' region for items");
|
||||
}
|
||||
pa_block(block_id) {
|
||||
region = ty::re_block(block_id);
|
||||
}
|
||||
pa_crate {
|
||||
cx.sess.span_bug(ty.span,
|
||||
"region type outside item");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cx.region_map.ast_type_to_region.insert(region_id, region);
|
||||
}
|
||||
_ { /* nothing to do */ }
|
||||
}
|
||||
|
||||
visit::visit_ty(ty, cx, visitor);
|
||||
}
|
||||
|
||||
fn resolve_block(blk: ast::blk, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
alt cx.parent {
|
||||
pa_item(_) { /* no-op */ }
|
||||
pa_block(parent_block_id) {
|
||||
cx.region_map.parent_blocks.insert(blk.node.id, parent_block_id);
|
||||
}
|
||||
pa_crate { cx.sess.span_bug(blk.span, "block outside item?!"); }
|
||||
}
|
||||
|
||||
let new_cx: ctxt = {parent: pa_block(blk.node.id) with cx};
|
||||
visit::visit_block(blk, new_cx, visitor);
|
||||
}
|
||||
|
||||
fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
// Items create a new outer block scope as far as we're concerned.
|
||||
let new_cx: ctxt = {names_in_scope: map::new_str_hash(),
|
||||
parent: pa_item(item.id)
|
||||
with cx};
|
||||
visit::visit_item(item, new_cx, visitor);
|
||||
}
|
||||
|
||||
fn resolve_crate(sess: session, crate: @ast::crate) -> @region_map {
|
||||
let cx: ctxt = {sess: sess,
|
||||
region_map: @{parent_blocks: map::new_int_hash(),
|
||||
ast_type_to_region: map::new_int_hash()},
|
||||
names_in_scope: map::new_str_hash(),
|
||||
parent: pa_crate};
|
||||
let visitor = visit::mk_vt(@{
|
||||
visit_block: resolve_block,
|
||||
visit_item: resolve_item,
|
||||
visit_ty: resolve_ty
|
||||
with *visit::default_visitor()
|
||||
});
|
||||
visit::visit_crate(*crate, cx, visitor);
|
||||
ret cx.region_map;
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ type ctxt =
|
||||
mutable next_id: uint,
|
||||
sess: session::session,
|
||||
def_map: resolve::def_map,
|
||||
region_map: @middle::region::region_map,
|
||||
node_types: node_type_table,
|
||||
node_type_substs: hashmap<node_id, [t]>,
|
||||
items: ast_map::map,
|
||||
@ -327,7 +328,8 @@ fn new_ty_hash<V: copy>() -> map::hashmap<t, V> {
|
||||
}
|
||||
|
||||
fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
|
||||
freevars: freevars::freevar_map) -> ctxt {
|
||||
freevars: freevars::freevar_map,
|
||||
region_map: @middle::region::region_map) -> ctxt {
|
||||
let interner = map::mk_hashmap({|&&k: intern_key|
|
||||
hash_type_structure(k.struct) +
|
||||
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,
|
||||
mutable next_id: 0u,
|
||||
sess: s,
|
||||
def_map: dm,
|
||||
region_map: region_map,
|
||||
node_types: @smallintmap::mk(),
|
||||
node_type_substs: map::new_int_hash(),
|
||||
items: amap,
|
||||
|
@ -44,6 +44,7 @@ mod middle {
|
||||
mod freevars;
|
||||
mod capture;
|
||||
mod pat_util;
|
||||
mod region;
|
||||
|
||||
mod tstate {
|
||||
mod ck;
|
||||
|
Loading…
Reference in New Issue
Block a user