@@ -15,6 +15,7 @@ use middle::typeck::check::demand;
1515use middle:: typeck:: check:: { check_block, check_expr_has_type, FnCtxt } ;
1616use middle:: typeck:: check:: { instantiate_path, lookup_def} ;
1717use middle:: typeck:: check:: { structure_of, valid_range_bounds} ;
18+ use middle:: typeck:: infer;
1819use middle:: typeck:: require_same_types;
1920
2021use 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
93103pub 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
100108pub 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 ) ]
653660enum PointerKind { Managed , Send , Borrowed }
661+
0 commit comments