@@ -93,7 +93,7 @@ impl<'a> InferenceContext<'a> {
9393 Ty :: Unknown
9494 }
9595 Expr :: Loop { body } => {
96- self . breakables . push ( BreakableContext { may_break : false } ) ;
96+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
9797 self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
9898
9999 let ctxt = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
@@ -102,13 +102,13 @@ impl<'a> InferenceContext<'a> {
102102 }
103103 // FIXME handle break with value
104104 if ctxt. may_break {
105- Ty :: unit ( )
105+ ctxt . break_ty
106106 } else {
107107 Ty :: simple ( TypeCtor :: Never )
108108 }
109109 }
110110 Expr :: While { condition, body } => {
111- self . breakables . push ( BreakableContext { may_break : false } ) ;
111+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
112112 // while let is desugared to a match loop, so this is always simple while
113113 self . infer_expr ( * condition, & Expectation :: has_type ( Ty :: simple ( TypeCtor :: Bool ) ) ) ;
114114 self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> {
120120 Expr :: For { iterable, body, pat } => {
121121 let iterable_ty = self . infer_expr ( * iterable, & Expectation :: none ( ) ) ;
122122
123- self . breakables . push ( BreakableContext { may_break : false } ) ;
123+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
124124 let pat_ty =
125125 self . resolve_associated_type ( iterable_ty, self . resolve_into_iter_item ( ) ) ;
126126
@@ -229,12 +229,21 @@ impl<'a> InferenceContext<'a> {
229229 }
230230 Expr :: Continue => Ty :: simple ( TypeCtor :: Never ) ,
231231 Expr :: Break { expr } => {
232+ let mut has_val_ty = None ;
233+
232234 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 ( ) ) ) ;
235236 }
237+
236238 if let Some ( ctxt) = self . breakables . last_mut ( ) {
237239 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+ }
238247 } else {
239248 self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
240249 expr : tgt_expr,
0 commit comments