@@ -93,14 +93,17 @@ impl<'a> InferenceContext<'a> {
9393 Ty :: Unknown
9494 }
9595 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+ } ) ;
97100 self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
98101
99102 let ctxt = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
100103 if ctxt. may_break {
101104 self . diverges = Diverges :: Maybe ;
102105 }
103- // FIXME handle break with value
106+
104107 if ctxt. may_break {
105108 ctxt. break_ty
106109 } else {
@@ -229,26 +232,31 @@ impl<'a> InferenceContext<'a> {
229232 }
230233 Expr :: Continue => Ty :: simple ( TypeCtor :: Never ) ,
231234 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+ } ;
233240
234- if let Some ( expr) = expr {
235- has_val_ty = Some ( self . infer_expr ( * expr, & Expectation :: none ( ) ) ) ;
236- }
241+ let mut has_brkctx = false ;
237242
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 ;
247245 } else {
248246 self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
249247 expr : tgt_expr,
250248 } ) ;
251249 }
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+
252260 Ty :: simple ( TypeCtor :: Never )
253261 }
254262 Expr :: Return { expr } => {
0 commit comments