Skip to content

Commit c720ffd

Browse files
committed
Improve region code surrounding slice types.
1 parent 9d7e4ae commit c720ffd

File tree

3 files changed

+78
-82
lines changed

3 files changed

+78
-82
lines changed

src/rustc/middle/infer.rs

+9
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,15 @@ fn super_tys<C:combine>(
908908
}
909909
}
910910

911+
(ty::ty_evec(a_mt, ty::vstore_slice(a_r)),
912+
ty::ty_evec(b_mt, ty::vstore_slice(b_r))) {
913+
self.contraregions(a_r, b_r).chain {|r|
914+
self.mts(a_mt, b_mt).chain {|mt|
915+
ok(ty::mk_evec(tcx, mt, ty::vstore_slice(r)))
916+
}
917+
}
918+
}
919+
911920
(ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
912921
if a_id == b_id {
913922
self.tys(a_t, b_t).chain {|t|

src/rustc/middle/region.rs

+22-29
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,10 @@ type region_map = {
168168
ast_type_to_inferred_region: hashmap<ast::node_id,ty::region>,
169169
/*
170170
* Mapping from an address-of operator or alt expression to its containing
171-
* block. This is used as the region if the operand is an rvalue.
171+
* region (usually ty::region_scope(block). This is used as the region if
172+
* the operand is an rvalue.
172173
*/
173-
rvalue_to_block: hashmap<ast::node_id,ast::node_id>
174+
rvalue_to_region: hashmap<ast::node_id,ty::region>
174175
};
175176

176177
type region_scope = @{
@@ -366,41 +367,26 @@ fn get_inferred_region(cx: ctxt, sp: syntax::codemap::span) -> ty::region {
366367
}
367368
}
368369

369-
fn resolve_region_binding(cx: ctxt, span: span, region: ast::region) {
370-
371-
let id = region.id;
372-
let rm = cx.region_map;
370+
fn resolve_region_binding(cx: ctxt, span: span,
371+
region: ast::region) -> ty::region {
373372
alt region.node {
374-
ast::re_inferred {
375-
// option::may(cx.scope.resolve_anon()) {|r|
376-
// rm.ast_type_to_region.insert(id, r);
377-
// }
378-
}
379-
380-
ast::re_static { /* fallthrough */ }
381-
373+
ast::re_inferred { ty::re_default }
374+
ast::re_static { ty::re_static }
382375
ast::re_named(ident) {
383376
alt cx.scope.resolve_ident(ident) {
384-
some(r) {
385-
rm.ast_type_to_region.insert(id, r);
386-
}
387-
377+
some(r) { r }
388378
none {
389-
cx.sess.span_err(
379+
cx.sess.span_fatal(
390380
span,
391381
#fmt["the region `%s` is not declared", ident]);
392382
}
393383
}
394384
}
395-
396385
ast::re_self {
397386
alt cx.scope.resolve_self() {
398-
some(r) {
399-
rm.ast_type_to_region.insert(id, r);
400-
}
401-
387+
some(r) { r }
402388
none {
403-
cx.sess.span_err(
389+
cx.sess.span_fatal(
404390
span,
405391
"the `self` region is not allowed here");
406392
}
@@ -416,7 +402,8 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
416402
alt ty.node {
417403
ast::ty_vstore(_, ast::vstore_slice(r)) |
418404
ast::ty_rptr(r, _) {
419-
resolve_region_binding(cx, ty.span, r);
405+
let region = resolve_region_binding(cx, ty.span, r);
406+
cx.region_map.ast_type_to_region.insert(ty.id, region);
420407
}
421408
_ { /* nothing to do */ }
422409
}
@@ -504,12 +491,17 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
504491
in_alt: false with cx};
505492
visit::visit_expr(expr, new_cx, visitor);
506493
}
494+
ast::expr_vstore(e, ast::vstore_slice(r)) {
495+
let region = resolve_region_binding(cx, e.span, r);
496+
cx.region_map.rvalue_to_region.insert(e.id, region);
497+
}
507498
ast::expr_addr_of(_, subexpr) | ast::expr_alt(subexpr, _, _) {
508499
// Record the block that this expression appears in, in case the
509500
// operand is an rvalue.
510501
alt cx.parent {
511502
pa_block(blk_id) {
512-
cx.region_map.rvalue_to_block.insert(subexpr.id, blk_id);
503+
let region = ty::re_scope(blk_id);
504+
cx.region_map.rvalue_to_region.insert(subexpr.id, region);
513505
}
514506
_ { cx.sess.span_bug(expr.span, "expr outside of block?!"); }
515507
}
@@ -522,7 +514,8 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
522514
fn resolve_local(local: @ast::local, cx: ctxt, visitor: visit::vt<ctxt>) {
523515
alt cx.parent {
524516
pa_block(blk_id) {
525-
cx.region_map.rvalue_to_block.insert(local.node.id, blk_id);
517+
let region = ty::re_scope(blk_id);
518+
cx.region_map.rvalue_to_region.insert(local.node.id, region);
526519
}
527520
_ { cx.sess.span_bug(local.span, "local outside of block?!"); }
528521
}
@@ -566,7 +559,7 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
566559
local_blocks: map::int_hash(),
567560
ast_type_to_inferred_region:
568561
map::int_hash(),
569-
rvalue_to_block: map::int_hash()},
562+
rvalue_to_region: map::int_hash()},
570563
scope: root_scope(0),
571564
mut queued_locals: [],
572565
parent: pa_crate,

src/rustc/middle/typeck.rs

+47-53
Original file line numberDiff line numberDiff line change
@@ -276,49 +276,39 @@ fn type_is_c_like_enum(fcx: @fn_ctxt, sp: span, typ: ty::t) -> bool {
276276

277277
enum mode { m_collect, m_check, m_check_tyvar(@fn_ctxt), }
278278

279-
fn ast_region_to_region(tcx: ty::ctxt,
280-
region: ast::region) -> ty::region {
281-
alt region.node {
282-
ast::re_inferred {
283-
// this must be replaced later by a fixup_regions() pass
284-
ty::re_default
279+
fn ast_ty_vstore_to_vstore(tcx: ty::ctxt, ty: @ast::ty,
280+
v: ast::vstore) -> ty::vstore {
281+
alt v {
282+
ast::vstore_fixed(none) {
283+
tcx.sess.span_bug(ty.span,
284+
"implied fixed length in ast_ty_vstore_to_vstore");
285285
}
286-
ast::re_self | ast::re_named(_) {
287-
tcx.region_map.ast_type_to_region.get(region.id)
286+
ast::vstore_fixed(some(u)) {
287+
ty::vstore_fixed(u)
288288
}
289-
ast::re_static {
290-
ty::re_static
289+
ast::vstore_uniq { ty::vstore_uniq }
290+
ast::vstore_box { ty::vstore_box }
291+
ast::vstore_slice(r) {
292+
ty::vstore_slice(tcx.region_map.ast_type_to_region.get(ty.id))
291293
}
292294
}
293295
}
294296

295-
fn ast_vstore_to_vstore(tcx: ty::ctxt, span: span, n: option<uint>,
296-
v: ast::vstore) -> ty::vstore {
297+
fn ast_expr_vstore_to_vstore(fcx: @fn_ctxt, e: @ast::expr, n: uint,
298+
v: ast::vstore) -> ty::vstore {
297299
alt v {
298-
ast::vstore_fixed(none) {
299-
alt n {
300-
some(n) { ty::vstore_fixed(n) }
301-
none {
302-
tcx.sess.bug("implied fixed length in ast_vstore_to_vstore with \
303-
no default length")
304-
}
305-
}
306-
}
300+
ast::vstore_fixed(none) { ty::vstore_fixed(n) }
307301
ast::vstore_fixed(some(u)) {
308-
alt n {
309-
some(n) if n != u {
310-
tcx.sess.span_err(span,
311-
#fmt("fixed-size sequence mismatch: %u vs. %u",
312-
u, n));
313-
}
314-
_ { }
302+
if n != u {
303+
let s = #fmt("fixed-size sequence mismatch: %u vs. %u",u, n);
304+
fcx.ccx.tcx.sess.span_err(e.span,s);
315305
}
316306
ty::vstore_fixed(u)
317307
}
318308
ast::vstore_uniq { ty::vstore_uniq }
319309
ast::vstore_box { ty::vstore_box }
320-
ast::vstore_slice(region) {
321-
ty::vstore_slice(ast_region_to_region(tcx, region))
310+
ast::vstore_slice(r) {
311+
ty::vstore_slice(region_of(fcx, e))
322312
}
323313
}
324314
}
@@ -408,7 +398,7 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
408398
ty::mk_ptr(tcx, ast_mt_to_mt(tcx, mode, mt))
409399
}
410400
ast::ty_rptr(region, mt) {
411-
let region = ast_region_to_region(tcx, region);
401+
let region = tcx.region_map.ast_type_to_region.get(ast_ty.id);
412402
ty::mk_rptr(tcx, region, ast_mt_to_mt(tcx, mode, mt))
413403
}
414404
ast::ty_tup(fields) {
@@ -473,16 +463,17 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
473463
}
474464
}
475465
ast::ty_vstore(t, vst) {
476-
let vst = ast_vstore_to_vstore(tcx, ast_ty.span, none, vst);
477-
alt ty::get(do_ast_ty_to_ty(tcx, mode, t)).struct {
466+
let vst = ast_ty_vstore_to_vstore(tcx, ast_ty, vst);
467+
let ty = alt ty::get(do_ast_ty_to_ty(tcx, mode, t)).struct {
478468
ty::ty_vec(mt) { ty::mk_evec(tcx, mt, vst) }
479469
ty::ty_str { ty::mk_estr(tcx, vst) }
480470
_ {
481471
tcx.sess.span_fatal(ast_ty.span,
482472
"found sequence storage modifier \
483473
on non-sequence type");
484474
}
485-
}
475+
};
476+
fixup_regions_to_block(tcx, ty, ast_ty)
486477
}
487478
ast::ty_constr(t, cs) {
488479
let mut out_cs = [];
@@ -2512,8 +2503,7 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
25122503
}
25132504
}
25142505
_ {
2515-
let blk_id = fcx.ccx.tcx.region_map.rvalue_to_block.get(expr.id);
2516-
ret ty::re_scope(blk_id);
2506+
ret fcx.ccx.tcx.region_map.rvalue_to_region.get(expr.id);
25172507
}
25182508
}
25192509
}
@@ -2849,27 +2839,32 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
28492839
alt expr.node {
28502840

28512841
ast::expr_vstore(ev, vst) {
2852-
alt ev.node {
2842+
let mut typ = alt ev.node {
28532843
ast::expr_lit(@{node: ast::lit_str(s), span:_}) {
2854-
let tt = ast_vstore_to_vstore(tcx, expr.span,
2855-
some(str::len(s)), vst);
2856-
let typ = ty::mk_estr(tcx, tt);
2857-
fcx.write_ty(ev.id, typ);
2858-
fcx.write_ty(id, typ);
2844+
let tt = ast_expr_vstore_to_vstore(fcx, ev,
2845+
str::len(s), vst);
2846+
ty::mk_estr(tcx, tt)
28592847
}
28602848
ast::expr_vec(args, mutbl) {
2861-
let tt = ast_vstore_to_vstore(tcx, expr.span,
2862-
some(vec::len(args)), vst);
2849+
let tt = ast_expr_vstore_to_vstore(fcx, ev,
2850+
vec::len(args), vst);
28632851
let t: ty::t = next_ty_var(fcx);
28642852
for args.each {|e| bot |= check_expr_with(fcx, e, t); }
2865-
let typ = ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt);
2866-
fcx.write_ty(ev.id, typ);
2867-
fcx.write_ty(id, typ);
2853+
ty::mk_evec(tcx, {ty: t, mutbl: mutbl}, tt)
28682854
}
28692855
_ {
2870-
tcx.sess.span_err(expr.span, "vstore modifier on non-sequence");
2856+
tcx.sess.span_bug(expr.span, "vstore modifier on non-sequence")
2857+
}
2858+
};
2859+
alt vst {
2860+
ast::vstore_slice(_) {
2861+
let region = fcx.ccx.tcx.region_map.rvalue_to_region.get(ev.id);
2862+
typ = replace_default_region(tcx, region, typ);
28712863
}
2864+
_ { }
28722865
}
2866+
fcx.write_ty(ev.id, typ);
2867+
fcx.write_ty(id, typ);
28732868
}
28742869

28752870
ast::expr_lit(lit) {
@@ -3075,7 +3070,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
30753070
let pattern_ty = next_ty_var(fcx);
30763071
bot = check_expr_with(fcx, discrim, pattern_ty);
30773072

3078-
let parent_block = tcx.region_map.rvalue_to_block.get(discrim.id);
3073+
let parent_region = tcx.region_map.rvalue_to_region.get(discrim.id);
30793074

30803075
// Typecheck the patterns first, so that we get types for all the
30813076
// bindings.
@@ -3084,9 +3079,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
30843079
let pcx = {
30853080
fcx: fcx,
30863081
map: pat_util::pat_id_map(tcx.def_map, arm.pats[0]),
3087-
alt_region: ty::re_scope(parent_block),
3082+
alt_region: parent_region,
30883083
block_region: ty::re_scope(arm.body.node.id),
3089-
pat_region: ty::re_scope(parent_block)
3084+
pat_region: parent_region
30903085
};
30913086

30923087
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 {
35293524
_ {/* fall through */ }
35303525
}
35313526

3532-
let block_id = fcx.ccx.tcx.region_map.rvalue_to_block.get(local.node.id);
3533-
let region = ty::re_scope(block_id);
3527+
let region = fcx.ccx.tcx.region_map.rvalue_to_region.get(local.node.id);
35343528
let pcx = {
35353529
fcx: fcx,
35363530
map: pat_util::pat_id_map(fcx.ccx.tcx.def_map, local.node.pat),

0 commit comments

Comments
 (0)