@@ -120,19 +120,16 @@ impl<'a> InferenceContext<'a> {
120120 let ty = match label {
121121 Some ( _) => {
122122 let break_ty = self . table . new_type_var ( ) ;
123- let ( ctx, ty) = self . with_breakable_ctx ( break_ty. clone ( ) , * label, |this| {
124- this. infer_block (
125- tgt_expr,
126- statements,
127- * tail,
128- & Expectation :: has_type ( break_ty) ,
129- )
130- } ) ;
131- if ctx. may_break {
132- ctx. coerce . complete ( )
133- } else {
134- ty
135- }
123+ let ( breaks, ty) =
124+ self . with_breakable_ctx ( break_ty. clone ( ) , * label, |this| {
125+ this. infer_block (
126+ tgt_expr,
127+ statements,
128+ * tail,
129+ & Expectation :: has_type ( break_ty) ,
130+ )
131+ } ) ;
132+ breaks. unwrap_or ( ty)
136133 }
137134 None => self . infer_block ( tgt_expr, statements, * tail, expected) ,
138135 } ;
@@ -164,15 +161,16 @@ impl<'a> InferenceContext<'a> {
164161 }
165162 & Expr :: Loop { body, label } => {
166163 let ty = self . table . new_type_var ( ) ;
167- let ( ctx , ( ) ) = self . with_breakable_ctx ( ty, label, |this| {
164+ let ( breaks , ( ) ) = self . with_breakable_ctx ( ty, label, |this| {
168165 this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
169166 } ) ;
170167
171- if ctx. may_break {
172- self . diverges = Diverges :: Maybe ;
173- ctx. coerce . complete ( )
174- } else {
175- TyKind :: Never . intern ( Interner )
168+ match breaks {
169+ Some ( breaks) => {
170+ self . diverges = Diverges :: Maybe ;
171+ breaks
172+ }
173+ None => TyKind :: Never . intern ( Interner ) ,
176174 }
177175 }
178176 & Expr :: While { condition, body, label } => {
@@ -194,7 +192,7 @@ impl<'a> InferenceContext<'a> {
194192 self . resolve_associated_type ( iterable_ty, self . resolve_into_iter_item ( ) ) ;
195193
196194 self . infer_pat ( pat, & pat_ty, BindingMode :: default ( ) ) ;
197- let ( _ctx , ( ) ) = self . with_breakable_ctx ( self . err_ty ( ) , label, |this| {
195+ self . with_breakable_ctx ( self . err_ty ( ) , label, |this| {
198196 this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
199197 } ) ;
200198
@@ -356,7 +354,15 @@ impl<'a> InferenceContext<'a> {
356354 let resolver = resolver_for_expr ( self . db . upcast ( ) , self . owner , tgt_expr) ;
357355 self . infer_path ( & resolver, p, tgt_expr. into ( ) ) . unwrap_or_else ( || self . err_ty ( ) )
358356 }
359- Expr :: Continue { .. } => TyKind :: Never . intern ( Interner ) ,
357+ Expr :: Continue { label } => {
358+ if let None = find_breakable ( & mut self . breakables , label. as_ref ( ) ) {
359+ self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
360+ expr : tgt_expr,
361+ is_break : false ,
362+ } ) ;
363+ } ;
364+ TyKind :: Never . intern ( Interner )
365+ }
360366 Expr :: Break { expr, label } => {
361367 let mut coerce = match find_breakable ( & mut self . breakables , label. as_ref ( ) ) {
362368 Some ( ctxt) => {
@@ -384,6 +390,7 @@ impl<'a> InferenceContext<'a> {
384390 } else {
385391 self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
386392 expr : tgt_expr,
393+ is_break : true ,
387394 } ) ;
388395 } ;
389396
@@ -1462,13 +1469,13 @@ impl<'a> InferenceContext<'a> {
14621469 ty : Ty ,
14631470 label : Option < LabelId > ,
14641471 cb : impl FnOnce ( & mut Self ) -> T ,
1465- ) -> ( BreakableContext , T ) {
1472+ ) -> ( Option < Ty > , T ) {
14661473 self . breakables . push ( {
14671474 let label = label. map ( |label| self . body [ label] . name . clone ( ) ) ;
14681475 BreakableContext { may_break : false , coerce : CoerceMany :: new ( ty) , label }
14691476 } ) ;
14701477 let res = cb ( self ) ;
14711478 let ctx = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
1472- ( ctx, res)
1479+ ( ctx. may_break . then ( || ctx . coerce . complete ( ) ) , res)
14731480 }
14741481}
0 commit comments