@@ -179,6 +179,38 @@ enum Expectation<'tcx> {
179
179
180
180
impl < ' tcx > Copy for Expectation < ' tcx > { }
181
181
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
+
182
214
#[ deriving( Copy , Clone ) ]
183
215
pub struct UnsafetyState {
184
216
pub def : ast:: NodeId ,
@@ -3047,7 +3079,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3047
3079
}
3048
3080
3049
3081
// A generic function for checking the then and else in an if
3050
- // or if-check
3082
+ // or if-else.
3051
3083
fn check_then_else < ' a , ' tcx > ( fcx : & FnCtxt < ' a , ' tcx > ,
3052
3084
cond_expr : & ast:: Expr ,
3053
3085
then_blk : & ast:: Block ,
@@ -3057,33 +3089,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3057
3089
expected : Expectation < ' tcx > ) {
3058
3090
check_expr_has_type ( fcx, cond_expr, ty:: mk_bool ( ) ) ;
3059
3091
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) ;
3087
3093
check_block_with_expected ( fcx, then_blk, expected) ;
3088
3094
let then_ty = fcx. node_ty ( then_blk. id ) ;
3089
3095
@@ -3989,7 +3995,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3989
3995
}
3990
3996
}
3991
3997
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 ) ;
3993
3999
}
3994
4000
ast:: ExprClosure ( _, opt_kind, ref decl, ref body) => {
3995
4001
closure:: check_expr_closure ( fcx, expr, opt_kind, & * * decl, & * * body, expected) ;
0 commit comments