rustc: Get reference typedefs working

This commit is contained in:
Patrick Walton 2012-03-13 15:52:45 -07:00
parent b968c8e6cd
commit 8cbaebbb49
6 changed files with 62 additions and 15 deletions

View File

@ -103,6 +103,7 @@ fn enc_region(w: io::writer, cx: @ctxt, r: ty::region) {
ty::re_block(nid) {
w.write_char('b'); w.write_int(nid); w.write_char('|');
}
ty::re_inferred { w.write_char('?'); }
}
}
fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {

View File

@ -15,9 +15,10 @@ import std::map::hashmap;
/* Represents the type of the most immediate parent node. */
enum parent {
pa_item(ast::node_id),
pa_fn_item(ast::node_id),
pa_block(ast::node_id),
pa_nested_fn(ast::node_id),
pa_item(ast::node_id),
pa_crate
}
@ -66,6 +67,7 @@ fn region_to_scope(region_map: @region_map, region: ty::region)
ty::re_caller(def_id) { def_id.node }
ty::re_named(def_id) { region_map.region_name_to_fn.get(def_id) }
ty::re_block(node_id) { node_id }
ty::re_inferred { fail "unresolved region in region_to_scope" }
};
}
@ -90,10 +92,11 @@ fn get_inferred_region(cx: ctxt, sp: syntax::codemap::span) -> ty::region {
// TODO: What do we do if we're in an alt?
ret alt cx.parent {
pa_item(item_id) | pa_nested_fn(item_id) {
pa_fn_item(item_id) | pa_nested_fn(item_id) {
ty::re_caller({crate: ast::local_crate, node: item_id})
}
pa_block(block_id) { ty::re_block(block_id) }
pa_item(_) { ty::re_inferred }
pa_crate { cx.sess.span_bug(sp, "inferred region at crate level?!"); }
}
}
@ -121,10 +124,16 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
region = ty::re_named(def_id);
alt cx.parent {
pa_item(fn_id) | pa_nested_fn(fn_id) {
pa_fn_item(fn_id) | pa_nested_fn(fn_id) {
let rf = cx.region_map.region_name_to_fn;
rf.insert(def_id, fn_id);
}
pa_item(_) {
cx.sess.span_err(ty.span,
"named region not " +
"allowed in this " +
"context");
}
pa_block(_) {
cx.sess.span_err(ty.span,
"unknown region `" +
@ -152,7 +161,10 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
fn record_parent(cx: ctxt, child_id: ast::node_id) {
alt cx.parent {
pa_item(parent_id) | pa_block(parent_id) | pa_nested_fn(parent_id) {
pa_fn_item(parent_id) |
pa_item(parent_id) |
pa_block(parent_id) |
pa_nested_fn(parent_id) {
cx.region_map.parents.insert(child_id, parent_id);
}
pa_crate { /* no-op */ }
@ -231,8 +243,12 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
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 parent = alt item.node {
ast::item_fn(_, _, _) { pa_fn_item(item.id) }
_ { pa_item(item.id) }
};
let new_cx: ctxt = {bindings: @list::nil,
parent: pa_item(item.id),
parent: parent,
in_alt: false
with cx};
visit::visit_item(item, new_cx, visitor);

View File

@ -49,6 +49,10 @@ fn check_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
"escapes its block");
}
}
ty::re_inferred {
cx.tcx.sess.span_bug(expr.span,
"unresolved region");
}
}
}
_ { /* no-op */ }

View File

@ -35,7 +35,7 @@ export field;
export field_idx;
export get_field;
export get_fields;
export fm_general;
export fm_general, fm_rptr;
export get_element_type;
export is_binopable;
export is_pred_ty;
@ -88,7 +88,7 @@ export ty_uint, mk_uint, mk_mach_uint;
export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
export ty_var, mk_var;
export ty_self, mk_self;
export region, re_named, re_caller, re_block;
export region, re_named, re_caller, re_block, re_inferred;
export get, type_has_params, type_has_vars, type_has_rptrs, type_id;
export same_type;
export ty_var_id;
@ -234,7 +234,8 @@ type fn_ty = {proto: ast::proto,
enum region {
re_named(def_id),
re_caller(def_id),
re_block(node_id)
re_block(node_id),
re_inferred /* currently unresolved (for typedefs) */
}
// NB: If you change this, you'll probably want to change the corresponding
@ -571,6 +572,7 @@ fn walk_ty(cx: ctxt, ty: t, f: fn(t)) {
enum fold_mode {
fm_var(fn@(int) -> t),
fm_param(fn@(uint, def_id) -> t),
fm_rptr(fn@(region) -> region),
fm_general(fn@(t) -> t),
}
@ -581,6 +583,7 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
alt fld {
fm_var(_) { if !tb.has_vars { ret ty; } }
fm_param(_) { if !tb.has_params { ret ty; } }
fm_rptr(_) { if !tb.has_rptrs { ret ty; } }
fm_general(_) {/* no fast path */ }
}
@ -597,9 +600,6 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
ty_ptr(tm) {
ty = mk_ptr(cx, {ty: fold_ty(cx, fld, tm.ty), mutbl: tm.mutbl});
}
ty_rptr(r, tm) {
ty = mk_rptr(cx, r, {ty: fold_ty(cx, fld, tm.ty), mutbl: tm.mutbl});
}
ty_vec(tm) {
ty = mk_vec(cx, {ty: fold_ty(cx, fld, tm.ty), mutbl: tm.mutbl});
}
@ -647,6 +647,11 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
ty_param(id, did) {
alt fld { fm_param(folder) { ty = folder(id, did); } _ {} }
}
ty_rptr(r, tm) {
let region = alt fld { fm_rptr(folder) { folder(r) } _ { r } };
ty = mk_rptr(cx, region,
{ty: fold_ty(cx, fld, tm.ty), mutbl: tm.mutbl});
}
ty_constr(subty, cs) {
ty = mk_constr(cx, fold_ty(cx, fld, subty), cs);
}
@ -1161,6 +1166,7 @@ fn hash_type_structure(st: sty) -> uint {
re_named(_) { 1u }
re_caller(_) { 2u }
re_block(_) { 3u }
re_inferred { 4u }
}
}
alt st {

View File

@ -247,10 +247,19 @@ enum mode { m_collect, m_check, m_check_tyvar(@fn_ctxt), }
// internal notion of a type. `getter` is a function that returns the type
// corresponding to a definition ID:
fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
fn getter(tcx: ty::ctxt, _use_site: ast::node_id, mode: mode,
fn subst_inferred_regions(tcx: ty::ctxt, use_site: ast::node_id,
ty: ty::t) -> ty::t {
ret ty::fold_ty(tcx, ty::fm_rptr({|r|
if r == ty::re_inferred {
tcx.region_map.ast_type_to_inferred_region.get(use_site)
} else {
r
}
}), ty);
}
fn getter(tcx: ty::ctxt, use_site: ast::node_id, mode: mode,
id: ast::def_id) -> ty::ty_param_bounds_and_ty {
// FIXME (pcwalton): Doesn't work with region inference.
alt mode {
let tpt = alt mode {
m_check | m_check_tyvar(_) { ty::lookup_item_type(tcx, id) }
m_collect {
if id.crate != ast::local_crate { csearch::get_type(tcx, id) }
@ -268,7 +277,13 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
}
}
}
};
if ty::type_has_rptrs(tpt.ty) {
ret {bounds: tpt.bounds,
ty: subst_inferred_regions(tcx, use_site, tpt.ty)};
}
ret tpt;
}
fn ast_mt_to_mt(tcx: ty::ctxt, use_site: ast::node_id, mode: mode,
mt: ast::mt) -> ty::mt {
@ -327,7 +342,11 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
ast::ty_rptr(region, mt) {
let region = alt region.node {
ast::re_inferred | ast::re_self {
tcx.region_map.ast_type_to_inferred_region.get(ast_ty.id)
let attir = tcx.region_map.ast_type_to_inferred_region;
alt attir.find(ast_ty.id) {
some(resolved_region) { resolved_region }
none { ty::re_inferred }
}
}
ast::re_named(_) {
tcx.region_map.ast_type_to_region.get(region.id)

View File

@ -73,6 +73,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
re_named(_) { "<name>." } // TODO: include name
re_caller(_) { "<caller>." }
re_block(_) { "<block>." } // TODO: include line number
re_inferred { "" }
}
}