@@ -2999,35 +2999,36 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
2999
2999
expected : Expectation ) {
3000
3000
check_expr_has_type ( fcx, cond_expr, ty:: mk_bool ( ) ) ;
3001
3001
3002
+ // Disregard "castable to" expectations because they
3003
+ // can lead us astray. Consider for example `if cond
3004
+ // {22} else {c} as u8` -- if we propagate the
3005
+ // "castable to u8" constraint to 22, it will pick the
3006
+ // type 22u8, which is overly constrained (c might not
3007
+ // be a u8). In effect, the problem is that the
3008
+ // "castable to" expectation is not the tightest thing
3009
+ // we can say, so we want to drop it in this case.
3010
+ // The tightest thing we can say is "must unify with
3011
+ // else branch". Note that in the case of a "has type"
3012
+ // constraint, this limitation does not hold.
3013
+
3014
+ // If the expected type is just a type variable, then don't use
3015
+ // an expected type. Otherwise, we might write parts of the type
3016
+ // when checking the 'then' block which are incompatible with the
3017
+ // 'else' branch.
3018
+ let expected = match expected. only_has_type ( ) {
3019
+ ExpectHasType ( ety) => {
3020
+ match infer:: resolve_type ( fcx. infcx ( ) , Some ( sp) , ety, force_tvar) {
3021
+ Ok ( rty) if !ty:: type_is_ty_var ( rty) => ExpectHasType ( rty) ,
3022
+ _ => NoExpectation
3023
+ }
3024
+ }
3025
+ _ => NoExpectation
3026
+ } ;
3027
+ check_block_with_expected ( fcx, then_blk, expected) ;
3028
+ let then_ty = fcx. node_ty ( then_blk. id ) ;
3029
+
3002
3030
let branches_ty = match opt_else_expr {
3003
3031
Some ( ref else_expr) => {
3004
- // Disregard "castable to" expectations because they
3005
- // can lead us astray. Consider for example `if cond
3006
- // {22} else {c} as u8` -- if we propagate the
3007
- // "castable to u8" constraint to 22, it will pick the
3008
- // type 22u8, which is overly constrained (c might not
3009
- // be a u8). In effect, the problem is that the
3010
- // "castable to" expectation is not the tightest thing
3011
- // we can say, so we want to drop it in this case.
3012
- // The tightest thing we can say is "must unify with
3013
- // else branch". Note that in the case of a "has type"
3014
- // constraint, this limitation does not hold.
3015
-
3016
- // If the expected type is just a type variable, then don't use
3017
- // an expected type. Otherwise, we might write parts of the type
3018
- // when checking the 'then' block which are incompatible with the
3019
- // 'else' branch.
3020
- let expected = match expected. only_has_type ( ) {
3021
- ExpectHasType ( ety) => {
3022
- match infer:: resolve_type ( fcx. infcx ( ) , Some ( sp) , ety, force_tvar) {
3023
- Ok ( rty) if !ty:: type_is_ty_var ( rty) => ExpectHasType ( rty) ,
3024
- _ => NoExpectation
3025
- }
3026
- }
3027
- _ => NoExpectation
3028
- } ;
3029
- check_block_with_expected ( fcx, then_blk, expected) ;
3030
- let then_ty = fcx. node_ty ( then_blk. id ) ;
3031
3032
check_expr_with_expectation ( fcx, & * * else_expr, expected) ;
3032
3033
let else_ty = fcx. expr_ty ( & * * else_expr) ;
3033
3034
infer:: common_supertype ( fcx. infcx ( ) ,
@@ -3037,8 +3038,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
3037
3038
else_ty)
3038
3039
}
3039
3040
None => {
3040
- check_block_no_value ( fcx, then_blk) ;
3041
- ty:: mk_nil ( )
3041
+ infer:: common_supertype ( fcx. infcx ( ) ,
3042
+ infer:: IfExpressionWithNoElse ( sp) ,
3043
+ false ,
3044
+ then_ty,
3045
+ ty:: mk_nil ( ) )
3042
3046
}
3043
3047
} ;
3044
3048
0 commit comments