@@ -93,7 +93,7 @@ impl<'a> InferenceContext<'a> {
93
93
Ty :: Unknown
94
94
}
95
95
Expr :: Loop { body } => {
96
- self . breakables . push ( BreakableContext { may_break : false } ) ;
96
+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
97
97
self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
98
98
99
99
let ctxt = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
@@ -102,13 +102,13 @@ impl<'a> InferenceContext<'a> {
102
102
}
103
103
// FIXME handle break with value
104
104
if ctxt. may_break {
105
- Ty :: unit ( )
105
+ ctxt . break_ty
106
106
} else {
107
107
Ty :: simple ( TypeCtor :: Never )
108
108
}
109
109
}
110
110
Expr :: While { condition, body } => {
111
- self . breakables . push ( BreakableContext { may_break : false } ) ;
111
+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
112
112
// while let is desugared to a match loop, so this is always simple while
113
113
self . infer_expr ( * condition, & Expectation :: has_type ( Ty :: simple ( TypeCtor :: Bool ) ) ) ;
114
114
self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> {
120
120
Expr :: For { iterable, body, pat } => {
121
121
let iterable_ty = self . infer_expr ( * iterable, & Expectation :: none ( ) ) ;
122
122
123
- self . breakables . push ( BreakableContext { may_break : false } ) ;
123
+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
124
124
let pat_ty =
125
125
self . resolve_associated_type ( iterable_ty, self . resolve_into_iter_item ( ) ) ;
126
126
@@ -229,12 +229,21 @@ impl<'a> InferenceContext<'a> {
229
229
}
230
230
Expr :: Continue => Ty :: simple ( TypeCtor :: Never ) ,
231
231
Expr :: Break { expr } => {
232
+ let mut has_val_ty = None ;
233
+
232
234
if let Some ( expr) = expr {
233
- // FIXME handle break with value
234
- self . infer_expr ( * expr, & Expectation :: none ( ) ) ;
235
+ has_val_ty = Some ( self . infer_expr ( * expr, & Expectation :: none ( ) ) ) ;
235
236
}
237
+
236
238
if let Some ( ctxt) = self . breakables . last_mut ( ) {
237
239
ctxt. may_break = true ;
240
+ if let Some ( val_ty) = has_val_ty {
241
+ if ctxt. break_ty == Ty :: Unknown {
242
+ ctxt. break_ty = val_ty;
243
+ } else if ctxt. break_ty != val_ty {
244
+ // TODO: Unify partially matching type information (Option<{unknown}> + Option<i32> => Option<i32>)
245
+ }
246
+ }
238
247
} else {
239
248
self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
240
249
expr : tgt_expr,
0 commit comments