Skip to content

Commit ab73532

Browse files
committed
move regionck into typeck, in the process fixing a bug or two
1 parent fa5cc5b commit ab73532

File tree

12 files changed

+229
-138
lines changed

12 files changed

+229
-138
lines changed

src/rustc/driver/driver.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,6 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
193193
let (root_map, mutbl_map) = time(
194194
time_passes, "borrow checking",
195195
bind middle::borrowck::check_crate(ty_cx, method_map, crate));
196-
time(time_passes, "region checking",
197-
bind middle::regionck::check_crate(ty_cx, crate));
198196
let (copy_map, ref_map) =
199197
time(time_passes, "alias checking",
200198
bind middle::alias::check_crate(ty_cx, crate));

src/rustc/middle/region.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,7 @@ fn resolve_local(local: @ast::local, cx: ctxt, visitor: visit::vt<ctxt>) {
364364

365365
fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt<ctxt>) {
366366
// Items create a new outer block scope as far as we're concerned.
367-
let new_cx: ctxt = {closure_parent: some(item.id),
368-
parent: some(item.id) with cx};
367+
let new_cx: ctxt = {closure_parent: none, parent: none with cx};
369368
visit::visit_item(item, new_cx, visitor);
370369
}
371370

src/rustc/middle/regionck.rs

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/rustc/middle/ty.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export ty_uint, mk_uint, mk_mach_uint;
101101
export ty_uniq, mk_uniq, mk_imm_uniq, type_is_unique_box;
102102
export ty_var, mk_var, type_is_var;
103103
export ty_self, mk_self, type_has_self;
104-
export region, bound_region;
104+
export region, bound_region, encl_region;
105105
export get, type_has_params, type_needs_infer, type_has_regions;
106106
export type_has_resources, type_id;
107107
export tbox_has_flag;
@@ -685,6 +685,15 @@ fn default_arg_mode_for_ty(ty: ty::t) -> ast::rmode {
685685
else { ast::by_ref }
686686
}
687687

688+
// Returns the narrowest lifetime enclosing the evaluation of the expression
689+
// with id `id`.
690+
fn encl_region(cx: ctxt, id: ast::node_id) -> ty::region {
691+
alt cx.region_map.parents.find(id) {
692+
some(encl_scope) {ty::re_scope(encl_scope)}
693+
none {ty::re_static}
694+
}
695+
}
696+
688697
fn walk_ty(ty: t, f: fn(t)) {
689698
maybe_walk_ty(ty, {|t| f(t); true});
690699
}

src/rustc/middle/typeck.rs

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ impl methods for @fn_ctxt {
630630
fn next_region_var() -> ty::region {
631631
ret ty::re_var(self.next_region_var_id());
632632
}
633+
633634
fn report_mismatched_types(sp: span, e: ty::t, a: ty::t,
634635
err: ty::type_err) {
635636
self.ccx.tcx.sess.span_err(
@@ -648,6 +649,10 @@ impl methods for @fn_ctxt {
648649
infer::mk_eqty(self.infcx, sub, sup)
649650
}
650651

652+
fn mk_subr(sub: ty::region, sup: ty::region) -> result<(), ty::type_err> {
653+
infer::mk_subr(self.infcx, sub, sup)
654+
}
655+
651656
fn require_unsafe(sp: span, op: str) {
652657
alt self.purity {
653658
ast::unsafe_fn {/*ok*/}
@@ -796,47 +801,6 @@ fn require_same_types(
796801
}
797802
}
798803

799-
mod demand {
800-
// Requires that the two types unify, and prints an error message if they
801-
// don't.
802-
fn suptype(fcx: @fn_ctxt, sp: span,
803-
expected: ty::t, actual: ty::t) {
804-
805-
// n.b.: order of actual, expected is reversed
806-
alt infer::mk_subty(fcx.infcx, actual, expected) {
807-
result::ok(()) { /* ok */ }
808-
result::err(err) {
809-
fcx.report_mismatched_types(sp, expected, actual, err);
810-
}
811-
}
812-
}
813-
814-
fn eqtype(fcx: @fn_ctxt, sp: span,
815-
expected: ty::t, actual: ty::t) {
816-
817-
alt infer::mk_eqty(fcx.infcx, actual, expected) {
818-
result::ok(()) { /* ok */ }
819-
result::err(err) {
820-
fcx.report_mismatched_types(sp, expected, actual, err);
821-
}
822-
}
823-
}
824-
825-
// Checks that the type `actual` can be assigned to `expected`.
826-
fn assign(fcx: @fn_ctxt, sp: span, borrow_scope: ast::node_id,
827-
expected: ty::t, expr: @ast::expr) {
828-
let expr_ty = fcx.expr_ty(expr);
829-
let anmnt = {expr_id: expr.id, borrow_scope: borrow_scope};
830-
alt infer::mk_assignty(fcx.infcx, anmnt, expr_ty, expected) {
831-
result::ok(()) { /* ok */ }
832-
result::err(err) {
833-
fcx.report_mismatched_types(sp, expected, expr_ty, err);
834-
}
835-
}
836-
}
837-
}
838-
839-
840804
// Returns true if the two types unify and false if they don't.
841805
fn are_compatible(fcx: @fn_ctxt, expected: ty::t, actual: ty::t) -> bool {
842806
alt fcx.mk_eqty(expected, actual) {
@@ -1594,8 +1558,7 @@ fn lookup_field_ty(tcx: ty::ctxt, class_id: ast::def_id,
15941558
*/
15951559
fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
15961560
fn borrow(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
1597-
let parent_id = fcx.ccx.tcx.region_map.parents.get(expr.id);
1598-
ret ty::re_scope(parent_id);
1561+
ty::encl_region(fcx.ccx.tcx, expr.id)
15991562
}
16001563

16011564
fn deref(fcx: @fn_ctxt, base: @ast::expr) -> ty::region {
@@ -1970,7 +1933,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
19701933
let ret_ty = ty::ty_fn_ret(fty);
19711934
let arg_tys = vec::map(ty::ty_fn_args(fty)) {|a| a.ty };
19721935

1973-
check_fn(fcx.ccx, proto, decl, body, expr.id,
1936+
check_fn(fcx.ccx, proto, decl, body,
19741937
ret_ty, arg_tys, is_loop_body, some(fcx),
19751938
fcx.self_ty);
19761939
}
@@ -2780,6 +2743,7 @@ fn check_const(ccx: @crate_ctxt, _sp: span, e: @ast::expr, id: ast::node_id) {
27802743
let cty = fcx.expr_ty(e);
27812744
let declty = fcx.ccx.tcx.tcache.get(local_def(id)).ty;
27822745
demand::suptype(fcx, e.span, declty, cty);
2746+
regionck::regionck_expr(fcx, e);
27832747
writeback::resolve_type_vars_in_expr(fcx, e);
27842748
}
27852749

@@ -2984,15 +2948,14 @@ fn check_bare_fn(ccx: @crate_ctxt,
29842948
let fty = ty::node_id_to_type(ccx.tcx, id);
29852949
let ret_ty = ty::ty_fn_ret(fty);
29862950
let arg_tys = vec::map(ty::ty_fn_args(fty)) {|a| a.ty };
2987-
check_fn(ccx, ast::proto_bare, decl, body, id,
2951+
check_fn(ccx, ast::proto_bare, decl, body,
29882952
ret_ty, arg_tys, false, none, self_ty);
29892953
}
29902954

29912955
fn check_fn(ccx: @crate_ctxt,
29922956
proto: ast::proto,
29932957
decl: ast::fn_decl,
29942958
body: ast::blk,
2995-
fid: ast::node_id,
29962959
ret_ty: ty::t,
29972960
arg_tys: [ty::t],
29982961
indirect_ret: bool,
@@ -3012,7 +2975,7 @@ fn check_fn(ccx: @crate_ctxt,
30122975
let old_isr = option::map_default(old_fcx, @nil) {
30132976
|fcx| fcx.in_scope_regions };
30142977
collect_bound_regions_in_tys(tcx, old_isr, all_tys) {
3015-
|br| ty::re_free(fid, br) }
2978+
|br| ty::re_free(body.node.id, br) }
30162979
};
30172980

30182981
// Replace the bound regions that appear in the arg tys, ret ty, etc with
@@ -3108,6 +3071,7 @@ fn check_fn(ccx: @crate_ctxt,
31083071
// resolved when the enclosing scope finishes up.
31093072
if option::is_none(old_fcx) {
31103073
vtable::resolve_in_block(fcx, body);
3074+
regionck::regionck_fn(fcx, decl, body);
31113075
writeback::resolve_type_vars_in_fn(fcx, decl, body);
31123076
}
31133077

src/rustc/middle/typeck/demand.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Requires that the two types unify, and prints an error message if they
2+
// don't.
3+
fn suptype(fcx: @fn_ctxt, sp: span,
4+
expected: ty::t, actual: ty::t) {
5+
6+
// n.b.: order of actual, expected is reversed
7+
alt infer::mk_subty(fcx.infcx, actual, expected) {
8+
result::ok(()) { /* ok */ }
9+
result::err(err) {
10+
fcx.report_mismatched_types(sp, expected, actual, err);
11+
}
12+
}
13+
}
14+
15+
fn eqtype(fcx: @fn_ctxt, sp: span,
16+
expected: ty::t, actual: ty::t) {
17+
18+
alt infer::mk_eqty(fcx.infcx, actual, expected) {
19+
result::ok(()) { /* ok */ }
20+
result::err(err) {
21+
fcx.report_mismatched_types(sp, expected, actual, err);
22+
}
23+
}
24+
}
25+
26+
// Checks that the type `actual` can be assigned to `expected`.
27+
fn assign(fcx: @fn_ctxt, sp: span, borrow_scope: ast::node_id,
28+
expected: ty::t, expr: @ast::expr) {
29+
let expr_ty = fcx.expr_ty(expr);
30+
let anmnt = {expr_id: expr.id, borrow_scope: borrow_scope};
31+
alt infer::mk_assignty(fcx.infcx, anmnt, expr_ty, expected) {
32+
result::ok(()) { /* ok */ }
33+
result::err(err) {
34+
fcx.report_mismatched_types(sp, expected, expr_ty, err);
35+
}
36+
}
37+
}
38+
39+

src/rustc/middle/typeck/infer.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,20 +1512,18 @@ impl of combine for lub {
15121512

15131513
(f @ ty::re_free(f_id, _), ty::re_scope(s_id)) |
15141514
(ty::re_scope(s_id), f @ ty::re_free(f_id, _)) {
1515-
// For LUB, generally the scope is within the fn and
1516-
// the free region is a parameter to the fn. In that case,
1517-
// the free region will always live as long as the fn,
1518-
// which is longer than the scope.
1519-
//
1520-
// However, with nested fns, it can happen that the
1521-
// scope surrounds the fn itself. In that case, we do
1522-
// not know which will live longer---it depends on the
1523-
// value provided for the free region in any given
1524-
// call. And so we must just back off to re_static as
1525-
// the LUB.
1515+
// A "free" region can be interpreted as "some region
1516+
// at least as big as the block f_id". So, we can
1517+
// reasonably compare free regions and scopes:
15261518
let rm = self.infcx().tcx.region_map;
15271519
alt region::nearest_common_ancestor(rm, f_id, s_id) {
1520+
// if the free region's scope `f_id` is bigger than
1521+
// the scope region `s_id`, then the LUB is the free
1522+
// region itself:
15281523
some(r_id) if r_id == f_id { ok(f) }
1524+
1525+
// otherwise, we don't know what the free region is,
1526+
// so we must conservatively say the LUB is static:
15291527
_ { ok(ty::re_static) }
15301528
}
15311529
}
@@ -1703,15 +1701,11 @@ impl of combine for glb {
17031701

17041702
(ty::re_free(f_id, _), s @ ty::re_scope(s_id)) |
17051703
(s @ ty::re_scope(s_id), ty::re_free(f_id, _)) {
1706-
// For GLB, generally the scope is within the fn and
1707-
// the free region is a parameter to the fn. In that case,
1708-
// the scope is always shorter than the free region.
1709-
//
1710-
// However, with nested fns, it can happen that the
1711-
// scope surrounds the fn itself. In that case, we do
1712-
// not know which will live longer---it depends on the
1713-
// value provided for the free region in any given
1714-
// call. And so we cannot give a GLB.
1704+
// Free region is something "at least as big as
1705+
// `f_id`." If we find that the scope `f_id` is bigger
1706+
// than the scope `s_id`, then we can say that the GLB
1707+
// is the scope `s_id`. Otherwise, as we do not know
1708+
// big the free region is precisely, the GLB is undefined.
17151709
let rm = self.infcx().tcx.region_map;
17161710
alt region::nearest_common_ancestor(rm, f_id, s_id) {
17171711
some(r_id) if r_id == f_id { ok(s) }

0 commit comments

Comments
 (0)