Improve region code surrounding slice types.
This commit is contained in:
parent
9d7e4aefee
commit
c720ffdbc4
3 changed files with 78 additions and 82 deletions
|
@ -908,6 +908,15 @@ fn super_tys<C:combine>(
|
|||
}
|
||||
}
|
||||
|
||||
(ty::ty_evec(a_mt, ty::vstore_slice(a_r)),
|
||||
ty::ty_evec(b_mt, ty::vstore_slice(b_r))) {
|
||||
self.contraregions(a_r, b_r).chain {|r|
|
||||
self.mts(a_mt, b_mt).chain {|mt|
|
||||
ok(ty::mk_evec(tcx, mt, ty::vstore_slice(r)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
|
||||
if a_id == b_id {
|
||||
self.tys(a_t, b_t).chain {|t|
|
||||
|
|
|
@ -168,9 +168,10 @@ type region_map = {
|
|||
ast_type_to_inferred_region: hashmap<ast::node_id,ty::region>,
|
||||
/*
|
||||
* Mapping from an address-of operator or alt expression to its containing
|
||||
* block. This is used as the region if the operand is an rvalue.
|
||||
* region (usually ty::region_scope(block). This is used as the region if
|
||||
* the operand is an rvalue.
|
||||
*/
|
||||
rvalue_to_block: hashmap<ast::node_id,ast::node_id>
|
||||
rvalue_to_region: hashmap<ast::node_id,ty::region>
|
||||
};
|
||||
|
||||
type region_scope = @{
|
||||
|
@ -366,41 +367,26 @@ fn get_inferred_region(cx: ctxt, sp: syntax::codemap::span) -> ty::region {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_region_binding(cx: ctxt, span: span, region: ast::region) {
|
||||
|
||||
let id = region.id;
|
||||
let rm = cx.region_map;
|
||||
fn resolve_region_binding(cx: ctxt, span: span,
|
||||
region: ast::region) -> ty::region {
|
||||
alt region.node {
|
||||
ast::re_inferred {
|
||||
// option::may(cx.scope.resolve_anon()) {|r|
|
||||
// rm.ast_type_to_region.insert(id, r);
|
||||
// }
|
||||
}
|
||||
|
||||
ast::re_static { /* fallthrough */ }
|
||||
|
||||
ast::re_inferred { ty::re_default }
|
||||
ast::re_static { ty::re_static }
|
||||
ast::re_named(ident) {
|
||||
alt cx.scope.resolve_ident(ident) {
|
||||
some(r) {
|
||||
rm.ast_type_to_region.insert(id, r);
|
||||
}
|
||||
|
||||
some(r) { r }
|
||||
none {
|
||||
cx.sess.span_err(
|
||||
cx.sess.span_fatal(
|
||||
span,
|
||||
#fmt["the region `%s` is not declared", ident]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::re_self {
|
||||
alt cx.scope.resolve_self() {
|
||||
some(r) {
|
||||
rm.ast_type_to_region.insert(id, r);
|
||||
}
|
||||
|
||||
some(r) { r }
|
||||
none {
|
||||
cx.sess.span_err(
|
||||
cx.sess.span_fatal(
|
||||
span,
|
||||
"the `self` region is not allowed here");
|
||||
}
|
||||
|
@ -416,7 +402,8 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
|
|||
alt ty.node {
|
||||
ast::ty_vstore(_, ast::vstore_slice(r)) |
|
||||
ast::ty_rptr(r, _) {
|
||||
resolve_region_binding(cx, ty.span, r);
|
||||
let region = resolve_region_binding(cx, ty.span, r);
|
||||
cx.region_map.ast_type_to_region.insert(ty.id, region);
|
||||
}
|
||||
_ { /* nothing to do */ }
|
||||
}
|
||||
|
@ -504,12 +491,17 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
|
|||
in_alt: false with cx};
|
||||
visit::visit_expr(expr, new_cx, visitor);
|
||||
}
|
||||
ast::expr_vstore(e, ast::vstore_slice(r)) {
|
||||
let region = resolve_region_binding(cx, e.span, r);
|
||||
cx.region_map.rvalue_to_region.insert(e.id, region);
|
||||
}
|
||||
ast::expr_addr_of(_, subexpr) | ast::expr_alt(subexpr, _, _) {
|
||||
// Record the block that this expression appears in, in case the
|
||||
// operand is an rvalue.
|
||||
alt cx.parent {
|
||||
pa_block(blk_id) {
|
||||
cx.region_map.rvalue_to_block.insert(subexpr.id, blk_id);
|
||||
let region = ty::re_scope(blk_id);
|
||||
cx.region_map.rvalue_to_region.insert(subexpr.id, region);
|
||||
}
|
||||
_ { cx.sess.span_bug(expr.span, "expr outside of block?!"); }
|
||||
}
|
||||
|
@ -522,7 +514,8 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
|
|||
fn resolve_local(local: @ast::local, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
alt cx.parent {
|
||||
pa_block(blk_id) {
|
||||
cx.region_map.rvalue_to_block.insert(local.node.id, blk_id);
|
||||
let region = ty::re_scope(blk_id);
|
||||
cx.region_map.rvalue_to_region.insert(local.node.id, region);
|
||||
}
|
||||
_ { cx.sess.span_bug(local.span, "local outside of block?!"); }
|
||||
}
|
||||
|
@ -566,7 +559,7 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
|
|||
local_blocks: map::int_hash(),
|
||||
ast_type_to_inferred_region:
|
||||
map::int_hash(),
|
||||
rvalue_to_block: map::int_hash()},
|
||||
rvalue_to_region: map::int_hash()},
|
||||
scope: root_scope(0),
|
||||
mut queued_locals: [],
|
||||
parent: pa_crate,
|
||||
|
|
|
@ -276,49 +276,39 @@ fn type_is_c_like_enum(fcx: @fn_ctxt, sp: span, typ: ty::t) -> bool {
|
|||
|
||||
enum mode { m_collect, m_check, m_check_tyvar(@fn_ctxt), }
|
||||
|
||||
fn ast_region_to_region(tcx: ty::ctxt,
|
||||
region: ast::region) -> ty::region {
|
||||
alt region.node {
|
||||
ast::re_inferred {
|
||||
// this must be replaced later by a fixup_regions() pass
|
||||
ty::re_default
|
||||
fn ast_ty_vstore_to_vstore(tcx: ty::ctxt, ty: @ast::ty,
|
||||
v: ast::vstore) -> ty::vstore {
|
||||
alt v {
|
||||
ast::vstore_fixed(none) {
|
||||
tcx.sess.span_bug(ty.span,
|
||||
"implied fixed length in ast_ty_vstore_to_vstore");
|
||||
}
|
||||
ast::re_self | ast::re_named(_) {
|
||||
tcx.region_map.ast_type_to_region.get(region.id)
|
||||
ast::vstore_fixed(some(u)) {
|
||||
ty::vstore_fixed(u)
|
||||
}
|
||||
ast::re_static {
|
||||
ty::re_static
|
||||
ast::vstore_uniq { ty::vstore_uniq }
|
||||
ast::vstore_box { ty::vstore_box }
|
||||
ast::vstore_slice(r) {
|
||||
ty::vstore_slice(tcx.region_map.ast_type_to_region.get(ty.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ast_vstore_to_vstore(tcx: ty::ctxt, span: span, n: option<uint>,
|
||||
v: ast::vstore) -> ty::vstore {
|
||||
fn ast_expr_vstore_to_vstore(fcx: @fn_ctxt, e: @ast::expr, n: uint,
|
||||
v: ast::vstore) -> ty::vstore {
|
||||
alt v {
|
||||
ast::vstore_fixed(none) {
|
||||
alt n {
|
||||
some(n) { ty::vstore_fixed(n) }
|
||||
none {
|
||||
tcx.sess.bug("implied fixed length in ast_vstore_to_vstore with \
|
||||
no default length")
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::vstore_fixed(none) { ty::vstore_fixed(n) }
|
||||
ast::vstore_fixed(some(u)) {
|
||||
alt n {
|
||||
some(n) if n != u {
|
||||
tcx.sess.span_err(span,
|
||||
#fmt("fixed-size sequence mismatch: %u vs. %u",
|
||||
u, n));
|
||||
}
|
||||
_ { }
|
||||
if n != u {
|
||||
let s = #fmt("fixed-size sequence mismatch: %u vs. %u",u, n);
|
||||
fcx.ccx.tcx.sess.span_err(e.span,s);
|
||||
}
|
||||
ty::vstore_fixed(u)
|
||||
}
|
||||
ast::vstore_uniq { ty::vstore_uniq }
|
||||
ast::vstore_box { ty::vstore_box }
|
||||
ast::vstore_slice(region) {
|
||||
ty::vstore_slice(ast_region_to_region(tcx, region))
|
||||
ast::vstore_slice(r) {
|
||||
ty::vstore_slice(region_of(fcx, e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +398,7 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
|
|||
ty::mk_ptr(tcx, ast_mt_to_mt(tcx, mode, mt))
|
||||
}
|
||||
ast::ty_rptr(region, mt) {
|
||||
let region = ast_region_to_region(tcx, region);
|
||||
let region = tcx.region_map.ast_type_to_region.get(ast_ty.id);
|
||||
ty::mk_rptr(tcx, region, ast_mt_to_mt(tcx, mode, mt))
|
||||
}
|
||||
ast::ty_tup(fields) {
|
||||
|
@ -473,8 +463,8 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
|
|||
}
|
||||
}
|
||||
ast::ty_vstore(t, vst) {
|
||||
let vst = ast_vstore_to_vstore(tcx, ast_ty.span, none, vst);
|
||||
alt ty::get(do_ast_ty_to_ty(tcx, mode, t)).struct {
|
||||
let vst = ast_ty_vstore_to_vstore(tcx, ast_ty, vst);
|
||||
let ty = alt ty::get(do_ast_ty_to_ty(tcx, mode, t)).struct {
|
||||
ty::ty_vec(mt) { ty::mk_evec(tcx, mt, vst) }
|
||||
ty::ty_str { ty::mk_estr(tcx, vst) }
|
||||
_ {
|
||||
|
@ -482,7 +472,8 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
|
|||
"found sequence storage modifier \
|
||||
on non-sequence type");
|
||||
}
|
||||
}
|
||||
};
|
||||
fixup_regions_to_block(tcx, ty, ast_ty)
|
||||
}
|
||||
ast::ty_constr(t, cs) {
|
||||
let mut out_cs = [];
|
||||
|
@ -2512,8 +2503,7 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
|
|||
}
|
||||
}
|
||||
_ {
|
||||
let blk_id = fcx.ccx.tcx.region_map.rvalue_to_block.get(expr.id);
|
||||
ret ty::re_scope(blk_id);
|
||||
ret fcx.ccx.tcx.region_map.rvalue_to_region.get(expr.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2849,27 +2839,32 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
alt expr.node {
|
||||
|
||||
ast::expr_vstore(ev, vst) {
|
||||
alt ev.node {
|
||||
let mut typ = alt ev.node {
|
||||
ast::expr_lit(@{node: ast::lit_str(s), span:_}) {
|
||||
let tt = ast_vstore_to_vstore(tcx, expr.span,
|
||||
some(str::len(s)), vst);
|
||||
let typ = ty::mk_estr(tcx, tt);
|
||||
fcx.write_ty(ev.id, typ);
|
||||
fcx.write_ty(id, typ);
|
||||
let tt = ast_expr_vstore_to_vstore(fcx, ev,
|
||||
str::len(s), vst);
|
||||
ty::mk_estr(tcx, tt)
|
||||
}
|
||||
ast::expr_vec(args, mutbl) {
|
||||
let tt = ast_vstore_to_vstore(tcx, expr.span,
|
||||
some(vec::len(args)), vst);
|
||||
let tt = ast_expr_vstore_to_vstore(fcx, ev,
|
||||
vec::len(args), vst);
|
||||
let t: ty::t = next_ty_var(fcx);
|
||||
for args.each {|e| bot |= check_expr_with(fcx, e, t); }
|
||||
let typ = ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt);
|
||||
fcx.write_ty(ev.id, typ);
|
||||
fcx.write_ty(id, typ);
|
||||
ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt)
|
||||
}
|
||||
_ {
|
||||
tcx.sess.span_err(expr.span, "vstore modifier on non-sequence");
|
||||
tcx.sess.span_bug(expr.span, "vstore modifier on non-sequence")
|
||||
}
|
||||
};
|
||||
alt vst {
|
||||
ast::vstore_slice(_) {
|
||||
let region = fcx.ccx.tcx.region_map.rvalue_to_region.get(ev.id);
|
||||
typ = replace_default_region(tcx, region, typ);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
fcx.write_ty(ev.id, typ);
|
||||
fcx.write_ty(id, typ);
|
||||
}
|
||||
|
||||
ast::expr_lit(lit) {
|
||||
|
@ -3075,7 +3070,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
let pattern_ty = next_ty_var(fcx);
|
||||
bot = check_expr_with(fcx, discrim, pattern_ty);
|
||||
|
||||
let parent_block = tcx.region_map.rvalue_to_block.get(discrim.id);
|
||||
let parent_region = tcx.region_map.rvalue_to_region.get(discrim.id);
|
||||
|
||||
// Typecheck the patterns first, so that we get types for all the
|
||||
// bindings.
|
||||
|
@ -3084,9 +3079,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
let pcx = {
|
||||
fcx: fcx,
|
||||
map: pat_util::pat_id_map(tcx.def_map, arm.pats[0]),
|
||||
alt_region: ty::re_scope(parent_block),
|
||||
alt_region: parent_region,
|
||||
block_region: ty::re_scope(arm.body.node.id),
|
||||
pat_region: ty::re_scope(parent_block)
|
||||
pat_region: parent_region
|
||||
};
|
||||
|
||||
for arm.pats.each {|p| check_pat(pcx, p, pattern_ty);}
|
||||
|
@ -3529,8 +3524,7 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
|
|||
_ {/* fall through */ }
|
||||
}
|
||||
|
||||
let block_id = fcx.ccx.tcx.region_map.rvalue_to_block.get(local.node.id);
|
||||
let region = ty::re_scope(block_id);
|
||||
let region = fcx.ccx.tcx.region_map.rvalue_to_region.get(local.node.id);
|
||||
let pcx = {
|
||||
fcx: fcx,
|
||||
map: pat_util::pat_id_map(fcx.ccx.tcx.def_map, local.node.pat),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue