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