@@ -93,14 +93,17 @@ impl<'a> InferenceContext<'a> {
93
93
Ty :: Unknown
94
94
}
95
95
Expr :: Loop { body } => {
96
- self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
96
+ self . breakables . push ( BreakableContext {
97
+ may_break : false ,
98
+ break_ty : self . table . new_type_var ( ) ,
99
+ } ) ;
97
100
self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
98
101
99
102
let ctxt = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
100
103
if ctxt. may_break {
101
104
self . diverges = Diverges :: Maybe ;
102
105
}
103
- // FIXME handle break with value
106
+
104
107
if ctxt. may_break {
105
108
ctxt. break_ty
106
109
} else {
@@ -229,26 +232,31 @@ impl<'a> InferenceContext<'a> {
229
232
}
230
233
Expr :: Continue => Ty :: simple ( TypeCtor :: Never ) ,
231
234
Expr :: Break { expr } => {
232
- let mut has_val_ty = None ;
235
+ let val_ty = if let Some ( expr) = expr {
236
+ self . infer_expr ( * expr, & Expectation :: none ( ) )
237
+ } else {
238
+ Ty :: unit ( )
239
+ } ;
233
240
234
- if let Some ( expr) = expr {
235
- has_val_ty = Some ( self . infer_expr ( * expr, & Expectation :: none ( ) ) ) ;
236
- }
241
+ let mut has_brkctx = false ;
237
242
238
- if let Some ( ctxt) = self . breakables . last_mut ( ) {
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
- }
243
+ if self . breakables . last ( ) . is_some ( ) {
244
+ has_brkctx = true ;
247
245
} else {
248
246
self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
249
247
expr : tgt_expr,
250
248
} ) ;
251
249
}
250
+
251
+ if has_brkctx {
252
+ let last_ty = self . breakables . last ( ) . expect ( "This is a bug" ) . break_ty . clone ( ) ;
253
+ let merged_type = self . coerce_merge_branch ( & last_ty, & val_ty) ;
254
+
255
+ let ctxt = self . breakables . last_mut ( ) . expect ( "This is a bug" ) ;
256
+ ctxt. may_break = true ;
257
+ ctxt. break_ty = merged_type;
258
+ }
259
+
252
260
Ty :: simple ( TypeCtor :: Never )
253
261
}
254
262
Expr :: Return { expr } => {
0 commit comments