@@ -179,6 +179,38 @@ enum Expectation<'tcx> {
179179
180180impl < ' tcx > Copy for Expectation < ' tcx > { }
181181
182+ impl < ' tcx > Expectation < ' tcx > {
183+ // Disregard "castable to" expectations because they
184+ // can lead us astray. Consider for example `if cond
185+ // {22} else {c} as u8` -- if we propagate the
186+ // "castable to u8" constraint to 22, it will pick the
187+ // type 22u8, which is overly constrained (c might not
188+ // be a u8). In effect, the problem is that the
189+ // "castable to" expectation is not the tightest thing
190+ // we can say, so we want to drop it in this case.
191+ // The tightest thing we can say is "must unify with
192+ // else branch". Note that in the case of a "has type"
193+ // constraint, this limitation does not hold.
194+
195+ // If the expected type is just a type variable, then don't use
196+ // an expected type. Otherwise, we might write parts of the type
197+ // when checking the 'then' block which are incompatible with the
198+ // 'else' branch.
199+ fn adjust_for_branches < ' a > ( & self , fcx : & FnCtxt < ' a , ' tcx > ) -> Expectation < ' tcx > {
200+ match self . only_has_type ( ) {
201+ ExpectHasType ( ety) => {
202+ let ety = fcx. infcx ( ) . shallow_resolve ( ety) ;
203+ if !ty:: type_is_ty_var ( ety) {
204+ ExpectHasType ( ety)
205+ } else {
206+ NoExpectation
207+ }
208+ }
209+ _ => NoExpectation
210+ }
211+ }
212+ }
213+
182214#[ deriving( Copy , Clone ) ]
183215pub struct UnsafetyState {
184216 pub def : ast:: NodeId ,
@@ -3047,7 +3079,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
30473079 }
30483080
30493081 // A generic function for checking the then and else in an if
3050- // or if-check
3082+ // or if-else.
30513083 fn check_then_else < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
30523084 cond_expr : & ast:: Expr ,
30533085 then_blk : & ast:: Block ,
@@ -3057,33 +3089,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
30573089 expected : Expectation < ' tcx > ) {
30583090 check_expr_has_type ( fcx, cond_expr, ty:: mk_bool ( ) ) ;
30593091
3060- // Disregard "castable to" expectations because they
3061- // can lead us astray. Consider for example `if cond
3062- // {22} else {c} as u8` -- if we propagate the
3063- // "castable to u8" constraint to 22, it will pick the
3064- // type 22u8, which is overly constrained (c might not
3065- // be a u8). In effect, the problem is that the
3066- // "castable to" expectation is not the tightest thing
3067- // we can say, so we want to drop it in this case.
3068- // The tightest thing we can say is "must unify with
3069- // else branch". Note that in the case of a "has type"
3070- // constraint, this limitation does not hold.
3071-
3072- // If the expected type is just a type variable, then don't use
3073- // an expected type. Otherwise, we might write parts of the type
3074- // when checking the 'then' block which are incompatible with the
3075- // 'else' branch.
3076- let expected = match expected. only_has_type ( ) {
3077- ExpectHasType ( ety) => {
3078- let ety = fcx. infcx ( ) . shallow_resolve ( ety) ;
3079- if !ty:: type_is_ty_var ( ety) {
3080- ExpectHasType ( ety)
3081- } else {
3082- NoExpectation
3083- }
3084- }
3085- _ => NoExpectation
3086- } ;
3092+ let expected = expected. adjust_for_branches ( fcx) ;
30873093 check_block_with_expected ( fcx, then_blk, expected) ;
30883094 let then_ty = fcx. node_ty ( then_blk. id ) ;
30893095
@@ -3989,7 +3995,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
39893995 }
39903996 }
39913997 ast:: ExprMatch ( ref discrim, ref arms, _) => {
3992- _match:: check_match ( fcx, expr, & * * discrim, arms. as_slice ( ) ) ;
3998+ _match:: check_match ( fcx, expr, & * * discrim, arms. as_slice ( ) , expected ) ;
39933999 }
39944000 ast:: ExprClosure ( _, opt_kind, ref decl, ref body) => {
39954001 closure:: check_expr_closure ( fcx, expr, opt_kind, & * * decl, & * * body, expected) ;
0 commit comments