@@ -93,22 +93,25 @@ 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 {
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 {
105- Ty :: unit ( )
108+ ctxt . break_ty
106109 } else {
107110 Ty :: simple ( TypeCtor :: Never )
108111 }
109112 }
110113 Expr :: While { condition, body } => {
111- self . breakables . push ( BreakableContext { may_break : false } ) ;
114+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
112115 // while let is desugared to a match loop, so this is always simple while
113116 self . infer_expr ( * condition, & Expectation :: has_type ( Ty :: simple ( TypeCtor :: Bool ) ) ) ;
114117 self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
@@ -120,7 +123,7 @@ impl<'a> InferenceContext<'a> {
120123 Expr :: For { iterable, body, pat } => {
121124 let iterable_ty = self . infer_expr ( * iterable, & Expectation :: none ( ) ) ;
122125
123- self . breakables . push ( BreakableContext { may_break : false } ) ;
126+ self . breakables . push ( BreakableContext { may_break : false , break_ty : Ty :: Unknown } ) ;
124127 let pat_ty =
125128 self . resolve_associated_type ( iterable_ty, self . resolve_into_iter_item ( ) ) ;
126129
@@ -229,17 +232,29 @@ impl<'a> InferenceContext<'a> {
229232 }
230233 Expr :: Continue => Ty :: simple ( TypeCtor :: Never ) ,
231234 Expr :: Break { expr } => {
232- if let Some ( expr) = expr {
233- // FIXME handle break with value
234- self . infer_expr ( * expr, & Expectation :: none ( ) ) ;
235- }
235+ let val_ty = if let Some ( expr) = expr {
236+ self . infer_expr ( * expr, & Expectation :: none ( ) )
237+ } else {
238+ Ty :: unit ( )
239+ } ;
240+
241+ let last_ty = if let Some ( ctxt) = self . breakables . last ( ) {
242+ ctxt. break_ty . clone ( )
243+ } else {
244+ Ty :: Unknown
245+ } ;
246+
247+ let merged_type = self . coerce_merge_branch ( & last_ty, & val_ty) ;
248+
236249 if let Some ( ctxt) = self . breakables . last_mut ( ) {
250+ ctxt. break_ty = merged_type;
237251 ctxt. may_break = true ;
238252 } else {
239253 self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
240254 expr : tgt_expr,
241255 } ) ;
242256 }
257+
243258 Ty :: simple ( TypeCtor :: Never )
244259 }
245260 Expr :: Return { expr } => {
0 commit comments