Skip to content

Commit ab34864

Browse files
committed
Merge pull request #7187 from nikomatsakis/issue-3238-defer-reasoning-about-regions
Defer reasoning about regions until after regionck
2 parents a2db7c1 + ef5c439 commit ab34864

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+2507
-1363
lines changed

src/librustc/middle/region.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pass builds up the `scope_map`, which describes the parent links in
1515
the region hierarchy. The second pass infers which types must be
1616
region parameterized.
1717
18+
Most of the documentation on regions can be found in
19+
`middle/typeck/infer/region_inference.rs`
20+
1821
*/
1922

2023

src/librustc/middle/typeck/check/_match.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use middle::typeck::check::demand;
1515
use middle::typeck::check::{check_block, check_expr_has_type, FnCtxt};
1616
use middle::typeck::check::{instantiate_path, lookup_def};
1717
use middle::typeck::check::{structure_of, valid_range_bounds};
18+
use middle::typeck::infer;
1819
use middle::typeck::require_same_types;
1920

2021
use std::hashmap::{HashMap, HashSet};
@@ -29,26 +30,31 @@ pub fn check_match(fcx: @mut FnCtxt,
2930
arms: &[ast::arm]) {
3031
let tcx = fcx.ccx.tcx;
3132

32-
let pattern_ty = fcx.infcx().next_ty_var();
33-
check_expr_has_type(fcx, discrim, pattern_ty);
33+
let discrim_ty = fcx.infcx().next_ty_var();
34+
check_expr_has_type(fcx, discrim, discrim_ty);
3435

3536
// Typecheck the patterns first, so that we get types for all the
3637
// bindings.
3738
for arms.iter().advance |arm| {
3839
let pcx = pat_ctxt {
3940
fcx: fcx,
4041
map: pat_id_map(tcx.def_map, arm.pats[0]),
41-
match_region: ty::re_scope(expr.id),
42-
block_region: ty::re_scope(arm.body.node.id)
4342
};
4443

45-
for arm.pats.iter().advance |p| { check_pat(&pcx, *p, pattern_ty);}
44+
for arm.pats.iter().advance |p| { check_pat(&pcx, *p, discrim_ty);}
4645
}
4746

47+
// The result of the match is the common supertype of all the
48+
// arms. Start out the value as bottom, since it's the, well,
49+
// bottom the type lattice, and we'll be moving up the lattice as
50+
// we process each arm. (Note that any match with 0 arms is matching
51+
// on any empty type and is therefore unreachable; should the flow
52+
// of execution reach it, we will fail, so bottom is an appropriate
53+
// type in that case)
54+
let mut result_ty = ty::mk_bot();
55+
4856
// Now typecheck the blocks.
49-
let mut result_ty = fcx.infcx().next_ty_var();
50-
let mut arm_non_bot = false;
51-
let mut saw_err = false;
57+
let mut saw_err = ty::type_is_error(discrim_ty);
5258
for arms.iter().advance |arm| {
5359
let mut guard_err = false;
5460
let mut guard_bot = false;
@@ -75,26 +81,28 @@ pub fn check_match(fcx: @mut FnCtxt,
7581
else if guard_bot {
7682
fcx.write_bot(arm.body.node.id);
7783
}
78-
else if !ty::type_is_bot(bty) {
79-
arm_non_bot = true; // If the match *may* evaluate to a non-_|_
80-
// expr, the whole thing is non-_|_
81-
}
82-
demand::suptype(fcx, arm.body.span, result_ty, bty);
84+
85+
result_ty =
86+
infer::common_supertype(
87+
fcx.infcx(),
88+
infer::MatchExpression(expr.span),
89+
true, // result_ty is "expected" here
90+
result_ty,
91+
bty);
8392
}
93+
8494
if saw_err {
8595
result_ty = ty::mk_err();
86-
}
87-
else if !arm_non_bot {
96+
} else if ty::type_is_bot(discrim_ty) {
8897
result_ty = ty::mk_bot();
8998
}
99+
90100
fcx.write_ty(expr.id, result_ty);
91101
}
92102

93103
pub struct pat_ctxt {
94104
fcx: @mut FnCtxt,
95105
map: PatIdMap,
96-
match_region: ty::Region, // Region for the match as a whole
97-
block_region: ty::Region, // Region for the block of the arm
98106
}
99107

100108
pub fn check_pat_variant(pcx: &pat_ctxt, pat: @ast::pat, path: @ast::Path,
@@ -442,8 +450,8 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
442450
// then the type of x is &M T where M is the mutability
443451
// and T is the expected type
444452
let region_var =
445-
fcx.infcx().next_region_var_with_lb(
446-
pat.span, pcx.block_region);
453+
fcx.infcx().next_region_var(
454+
infer::PatternRegion(pat.span));
447455
let mt = ty::mt {ty: expected, mutbl: mutbl};
448456
let region_ty = ty::mk_rptr(tcx, region_var, mt);
449457
demand::eqtype(fcx, pat.span, region_ty, typ);
@@ -544,9 +552,8 @@ pub fn check_pat(pcx: &pat_ctxt, pat: @ast::pat, expected: ty::t) {
544552
}
545553
ast::pat_vec(ref before, slice, ref after) => {
546554
let default_region_var =
547-
fcx.infcx().next_region_var_with_lb(
548-
pat.span, pcx.block_region
549-
);
555+
fcx.infcx().next_region_var(
556+
infer::PatternRegion(pat.span));
550557
551558
let (elt_type, region_var) = match structure_of(
552559
fcx, pat.span, expected
@@ -651,3 +658,4 @@ pub fn check_pointer_pat(pcx: &pat_ctxt,
651658

652659
#[deriving(Eq)]
653660
enum PointerKind { Managed, Send, Borrowed }
661+

src/librustc/middle/typeck/check/demand.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub fn suptype_with_fn(fcx: @mut FnCtxt,
3535
ty_a: ty::t, ty_b: ty::t,
3636
handle_err: &fn(span, ty::t, ty::t, &ty::type_err)) {
3737
// n.b.: order of actual, expected is reversed
38-
match infer::mk_subty(fcx.infcx(), b_is_expected, sp,
38+
match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp),
3939
ty_b, ty_a) {
4040
result::Ok(()) => { /* ok */ }
4141
result::Err(ref err) => {
@@ -45,7 +45,7 @@ pub fn suptype_with_fn(fcx: @mut FnCtxt,
4545
}
4646

4747
pub fn eqtype(fcx: @mut FnCtxt, sp: span, expected: ty::t, actual: ty::t) {
48-
match infer::mk_eqty(fcx.infcx(), false, sp, actual, expected) {
48+
match infer::mk_eqty(fcx.infcx(), false, infer::Misc(sp), actual, expected) {
4949
Ok(()) => { /* ok */ }
5050
Err(ref err) => {
5151
fcx.report_mismatched_types(sp, expected, actual, err);

src/librustc/middle/typeck/check/method.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -619,14 +619,18 @@ impl<'self> LookupContext<'self> {
619619
autoref: None}))
620620
}
621621
ty::ty_rptr(_, self_mt) => {
622-
let region = self.infcx().next_region_var_nb(self.expr.span);
622+
let region =
623+
self.infcx().next_region_var(
624+
infer::Autoref(self.expr.span));
623625
(ty::mk_rptr(tcx, region, self_mt),
624626
ty::AutoDerefRef(ty::AutoDerefRef {
625627
autoderefs: autoderefs+1,
626628
autoref: Some(ty::AutoPtr(region, self_mt.mutbl))}))
627629
}
628630
ty::ty_evec(self_mt, vstore_slice(_)) => {
629-
let region = self.infcx().next_region_var_nb(self.expr.span);
631+
let region =
632+
self.infcx().next_region_var(
633+
infer::Autoref(self.expr.span));
630634
(ty::mk_evec(tcx, self_mt, vstore_slice(region)),
631635
ty::AutoDerefRef(ty::AutoDerefRef {
632636
autoderefs: autoderefs,
@@ -758,7 +762,9 @@ impl<'self> LookupContext<'self> {
758762
-> Option<method_map_entry> {
759763
// This is hokey. We should have mutability inference as a
760764
// variable. But for now, try &const, then &, then &mut:
761-
let region = self.infcx().next_region_var_nb(self.expr.span);
765+
let region =
766+
self.infcx().next_region_var(
767+
infer::Autoref(self.expr.span));
762768
for mutbls.iter().advance |mutbl| {
763769
let autoref_ty = mk_autoref_ty(*mutbl, region);
764770
match self.search_for_method(autoref_ty) {
@@ -970,7 +976,8 @@ impl<'self> LookupContext<'self> {
970976
let (_, opt_transformed_self_ty, fn_sig) =
971977
replace_bound_regions_in_fn_sig(
972978
tcx, @Nil, Some(transformed_self_ty), &bare_fn_ty.sig,
973-
|_br| self.fcx.infcx().next_region_var_nb(self.expr.span));
979+
|br| self.fcx.infcx().next_region_var(
980+
infer::BoundRegionInFnCall(self.expr.span, br)));
974981
let transformed_self_ty = opt_transformed_self_ty.get();
975982
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {sig: fn_sig, ..bare_fn_ty});
976983
debug!("after replacing bound regions, fty=%s", self.ty_to_str(fty));
@@ -982,7 +989,7 @@ impl<'self> LookupContext<'self> {
982989
// variables to unify etc). Since we checked beforehand, and
983990
// nothing has changed in the meantime, this unification
984991
// should never fail.
985-
match self.fcx.mk_subty(false, self.self_expr.span,
992+
match self.fcx.mk_subty(false, infer::Misc(self.self_expr.span),
986993
rcvr_ty, transformed_self_ty) {
987994
result::Ok(_) => (),
988995
result::Err(_) => {

0 commit comments

Comments
 (0)