Skip to content

Commit

Permalink
rewrite region resolution so it takes place in typeck
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Apr 17, 2012
1 parent a532ad2 commit 35a93e6
Show file tree
Hide file tree
Showing 15 changed files with 1,026 additions and 895 deletions.
2 changes: 1 addition & 1 deletion doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ are written after the name of the implementation, or if that is not
specified, after the `impl` keyword.

~~~~
# iface seq { }
# iface seq<T> { }
impl <T> of seq<T> for [T] {
/* ... */
Expand Down
2 changes: 1 addition & 1 deletion src/etc/indenter
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w

$ident = 0;
$indent = 0;
while (<>) {
if (/^rust: ">>/) {
$indent += 1;
Expand Down
9 changes: 9 additions & 0 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ impl extensions<T:copy> for option<T> {
#[doc = "Performs an operation on the contained value or does nothing"]
fn iter(f: fn(T)) { iter(self, f) }

#[doc = "Converts `none` to a zero-element list and `some` to a \
one-element list."]
fn to_vec() -> [T] {
alt self {
some(t) { [t] }
none { [] }
}
}

#[doc = "Performs an operation on the contained value or does nothing"]
fn each(f: fn(T) -> bool) {
alt self {
Expand Down
3 changes: 1 addition & 2 deletions src/librustsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,8 @@ type region = {id: node_id, node: region_};

#[auto_serialize]
enum region_ {
re_inferred,
re_anon,
re_named(ident),
re_self,
re_static
}

Expand Down
6 changes: 2 additions & 4 deletions src/librustsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,13 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
fn region_from_name(p: parser, s: option<str>) -> ast::region {
let r = alt s {
some (string) {
if string == "self" {
ast::re_self
} else if string == "static" {
if string == "static" {
ast::re_static
} else {
ast::re_named(string)
}
}
none { ast::re_inferred }
none { ast::re_anon }
};

{id: p.get_id(), node: r}
Expand Down
6 changes: 2 additions & 4 deletions src/librustsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,8 @@ fn print_native_mod(s: ps, nmod: ast::native_mod, attrs: [ast::attribute]) {

fn print_region(s: ps, region: ast::region) {
alt region.node {
ast::re_inferred { /* no-op */ }
ast::re_anon { /* no-op */ }
ast::re_named(name) { word(s.s, name); word(s.s, "."); }
ast::re_self { word(s.s, "self"); word(s.s, "."); }
ast::re_static { word(s.s, "static"); word(s.s, "."); }
}
}
Expand Down Expand Up @@ -826,8 +825,7 @@ fn print_vstore(s: ps, t: ast::vstore) {
ast::vstore_box { word_space(s, "/@"); }
ast::vstore_slice(r) {
alt r.node {
ast::re_inferred { word_space(s, "/&"); }
ast::re_self { word_space(s, "/&self"); }
ast::re_anon { word_space(s, "/&"); }
ast::re_static { word_space(s, "/&static"); }
ast::re_named(name) {
word(s.s, "/&");
Expand Down
7 changes: 1 addition & 6 deletions src/rustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,8 @@ fn enc_bound_region(w: io::writer, br: ty::bound_region) {
alt br {
ty::br_self { w.write_char('s') }
ty::br_anon { w.write_char('a') }
ty::br_param(id, s) {
ty::br_named(s) {
w.write_char('[');
w.write_uint(id);
w.write_char('|');
w.write_str(s);
w.write_char(']')
}
Expand All @@ -132,9 +130,6 @@ fn enc_region(w: io::writer, r: ty::region) {
w.write_int(nid);
w.write_char('|');
}
ty::re_default {
w.write_char('i');
}
ty::re_var(id) {
w.write_char('v');
w.write_uint(id.to_uint());
Expand Down
38 changes: 14 additions & 24 deletions src/rustc/middle/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ impl resolve_methods for infer_ctxt {
self.rb,
{|_t| false },
rid,
{|| err(unresolved_region(rid)) });
{|| ok(ty::re_static) });
}

fn resolve_ty(typ: ty::t) -> fres<ty::t> {
Expand Down Expand Up @@ -1169,7 +1169,10 @@ impl of combine for sub {
}

fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
#debug["regions(%s <= %s)", a.to_str(*self), b.to_str(*self)];
#debug["%s.regions(%s, %s)",
self.tag(),
a.to_str(self.infcx()),
b.to_str(self.infcx())];
indent {||
alt (a, b) {
(ty::re_var(a_id), ty::re_var(b_id)) {
Expand Down Expand Up @@ -1376,8 +1379,7 @@ impl of combine for lub {
{|x, y| self.regions(x, y) })
}

(ty::re_var(v_id), r) |
(r, ty::re_var(v_id)) {
(ty::re_var(v_id), r) | (r, ty::re_var(v_id)) {
lattice_var_t(self, self.infcx().rb,
v_id, r,
{|x, y| self.regions(x, y) })
Expand Down Expand Up @@ -1415,12 +1417,6 @@ impl of combine for lub {
err(ty::terr_regions_differ(b, a))
}
}

(ty::re_default, _) |
(_, ty::re_default) {
// actually a compiler bug, I think.
err(ty::terr_regions_differ(b, a))
}
}
}
}
Expand Down Expand Up @@ -1561,10 +1557,10 @@ impl of combine for glb {
{|x, y| self.regions(x, y) })
}

(ty::re_var(v_id), _) | (_, ty::re_var(v_id)) {
lattice_var_t(self, self.infcx().rb,
v_id, b,
{|x, y| self.regions(x, y) })
(ty::re_var(v_id), r) | (r, ty::re_var(v_id)) {
lattice_var_t(self, self.infcx().rb,
v_id, r,
{|x, y| self.regions(x, y) })
}

(f @ ty::re_free(f_id, f_br), ty::re_scope(s_id)) |
Expand Down Expand Up @@ -1601,12 +1597,6 @@ impl of combine for glb {
err(ty::terr_regions_differ(b, a))
}
}

(ty::re_default, _) |
(_, ty::re_default) {
// actually a compiler bug, I think.
err(ty::terr_regions_differ(b, a))
}
}
}
}
Expand Down Expand Up @@ -1727,7 +1717,7 @@ fn lattice_vars<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
let {root: a_vid, bounds: a_bounds} = self.infcx().get(vb, a_vid);
let {root: b_vid, bounds: b_bounds} = self.infcx().get(vb, b_vid);

#debug["%s.vars(%s=%s <: %s=%s)",
#debug["%s.lattice_vars(%s=%s <: %s=%s)",
self.tag(),
a_vid.to_str(), a_bounds.to_str(self.infcx()),
b_vid.to_str(), b_bounds.to_str(self.infcx())];
Expand Down Expand Up @@ -1758,15 +1748,15 @@ fn lattice_vars<V:copy vid, T:copy to_str st, L:lattice_ops combine>(

fn lattice_var_t<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
self: L, vb: vals_and_bindings<V, T>,
a_vid: V, b: T,
a_id: V, b: T,
c_ts: fn(T, T) -> cres<T>) -> cres<T> {

let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_vid);
let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_id);

// The comments in this function are written for LUB, but they
// apply equally well to GLB if you inverse upper/lower/sub/super/etc.

#debug["%s.var_ty(%s=%s <: %s)",
#debug["%s.lattice_vart(%s=%s <: %s)",
self.tag(),
a_id.to_str(), a_bounds.to_str(self.infcx()),
b.to_str(self.infcx())];
Expand Down
120 changes: 3 additions & 117 deletions src/rustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,9 @@ type binding = {node_id: ast::node_id,
type region_map = {
/* Mapping from a block/function expression to its parent. */
parents: hashmap<ast::node_id,ast::node_id>,
/* Mapping from a region type in the AST to its resolved region. */
ast_type_to_region: hashmap<ast::node_id,ty::region>,

/* Mapping from a local variable to its containing block. */
local_blocks: hashmap<ast::node_id,ast::node_id>,
/* Mapping from an AST type node to the region that `&` resolves to. */
ast_type_to_inferred_region: hashmap<ast::node_id,ty::region>,
local_blocks: hashmap<ast::node_id,ast::node_id>
};

type region_scope = @{
Expand Down Expand Up @@ -198,69 +195,6 @@ impl methods for region_scope {
fn self_subscope(node_id: ast::node_id) -> region_scope {
@{node_id: node_id, kind: rsk_self(self)}
}

fn find(nm: str) -> option<binding> {
alt self.kind {
rsk_root { none }
rsk_body(parent) { parent.find(nm) }
rsk_self(parent) { parent.find(nm) }
rsk_binding(parent, bs) {
alt (*bs).find({|b| b.name == nm }) {
none { parent.find(nm) }
some(b) { some(b) }
}
}
}
}

// fn resolve_anon() -> option<ty::region> {
// alt self.kind {
// rsk_root { none }
// rsk_body(_) { none }
// rsk_self(_) { none }
// rsk_binding(_, _) { ty::re_bound(ty::br_anon) }
// }
// }

fn resolve_self_helper(bound: bool) -> option<ty::region> {
alt self.kind {
rsk_root { none }
rsk_self(_) if bound { some(ty::re_bound(ty::br_self)) }
rsk_self(_) { some(ty::re_free(self.node_id, ty::br_self)) }
rsk_binding(p, _) { p.resolve_self_helper(bound) }
rsk_body(p) { p.resolve_self_helper(false) }
}
}

fn resolve_self() -> option<ty::region> {
self.resolve_self_helper(true)
}

fn resolve_ident(nm: str) -> option<ty::region> {
alt self.find(nm) {
some(b) if b.node_id == self.node_id {
some(ty::re_bound(b.br))
}

some(b) {
some(ty::re_free(b.node_id, b.br))
}

none {
alt self.kind {
rsk_self(_) | rsk_root | rsk_body(_) { none }
rsk_binding(_, bs) {
let idx = (*bs).len();
let br = ty::br_param(idx, nm);
vec::push(*bs, {node_id: self.node_id,
name: nm,
br: br});
some(ty::re_bound(br))
}
}
}
}
}
}

type ctxt = {
Expand Down Expand Up @@ -351,50 +285,6 @@ fn get_inferred_region(cx: ctxt, sp: syntax::codemap::span) -> ty::region {
}
}

fn resolve_region_binding(cx: ctxt, span: span,
region: ast::region) -> ty::region {
alt region.node {
ast::re_inferred { ty::re_default }
ast::re_static { ty::re_static }
ast::re_named(ident) {
alt cx.scope.resolve_ident(ident) {
some(r) { r }
none {
cx.sess.span_fatal(
span,
#fmt["the region `%s` is not declared", ident]);
}
}
}
ast::re_self {
alt cx.scope.resolve_self() {
some(r) { r }
none {
cx.sess.span_fatal(
span,
"the `self` region is not allowed here");
}
}
}
}
}

fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
let inferred_region = get_inferred_region(cx, ty.span);
cx.region_map.ast_type_to_inferred_region.insert(ty.id, inferred_region);

alt ty.node {
ast::ty_vstore(_, ast::vstore_slice(r)) |
ast::ty_rptr(r, _) {
let region = resolve_region_binding(cx, ty.span, r);
cx.region_map.ast_type_to_region.insert(ty.id, region);
}
_ { /* nothing to do */ }
}

visit::visit_ty(ty, cx, visitor);
}

fn opt_parent_id(cx: ctxt) -> option<ast::node_id> {
alt cx.parent {
pa_fn_item(parent_id) |
Expand Down Expand Up @@ -531,16 +421,12 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
let cx: ctxt = {sess: sess,
def_map: def_map,
region_map: @{parents: map::int_hash(),
ast_type_to_region: map::int_hash(),
local_blocks: map::int_hash(),
ast_type_to_inferred_region:
map::int_hash()},
local_blocks: map::int_hash()},
scope: root_scope(0),
parent: pa_crate};
let visitor = visit::mk_vt(@{
visit_block: resolve_block,
visit_item: resolve_item,
visit_ty: resolve_ty,
visit_arm: resolve_arm,
visit_pat: resolve_pat,
visit_expr: resolve_expr,
Expand Down
8 changes: 3 additions & 5 deletions src/rustc/middle/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ fn check_expr(expr: @ast::expr,
visit::visit_expr(expr, tcx, visitor);

let t = ty::expr_ty(tcx, expr);
if !ty::type_has_rptrs(t) { ret; }
if !ty::type_has_regions(t) { ret; }
ty::walk_ty(t) { |t|
alt ty::get(t).struct {
ty::ty_rptr(region, _) {
alt region {
ty::re_bound(_) | ty::re_free(_, _) | ty::re_static {
ty::re_bound(_) | ty::re_free(_, _) | ty::re_static |
ty::re_var(_) {
/* ok */
}
ty::re_scope(id) {
Expand All @@ -31,9 +32,6 @@ fn check_expr(expr: @ast::expr,
ppaux::re_scope_id_to_str(tcx, id)]);
}
}
ty::re_default | ty::re_var(_) {
tcx.sess.span_bug(expr.span, "unresolved region");
}
}
}
_ { /* no-op */ }
Expand Down
Loading

0 comments on commit 35a93e6

Please sign in to comment.