@@ -23,7 +23,7 @@ use syntax::ast::RangeOp;
2323use crate :: {
2424 autoderef:: { self , Autoderef } ,
2525 consteval,
26- infer:: coerce:: CoerceMany ,
26+ infer:: { coerce:: CoerceMany , find_continuable , BreakableKind } ,
2727 lower:: {
2828 const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode ,
2929 } ,
@@ -120,25 +120,37 @@ impl<'a> InferenceContext<'a> {
120120 let ty = match label {
121121 Some ( _) => {
122122 let break_ty = self . table . new_type_var ( ) ;
123- let ( breaks, ty) =
124- self . with_breakable_ctx ( break_ty. clone ( ) , * label, |this| {
123+ let ( breaks, ty) = self . with_breakable_ctx (
124+ BreakableKind :: Block ,
125+ break_ty. clone ( ) ,
126+ * label,
127+ |this| {
125128 this. infer_block (
126129 tgt_expr,
127130 statements,
128131 * tail,
129132 & Expectation :: has_type ( break_ty) ,
130133 )
131- } ) ;
134+ } ,
135+ ) ;
132136 breaks. unwrap_or ( ty)
133137 }
134138 None => self . infer_block ( tgt_expr, statements, * tail, expected) ,
135139 } ;
136140 self . resolver = old_resolver;
137141 ty
138142 }
139- Expr :: Unsafe { body } | Expr :: Const { body } => self . infer_expr ( * body, expected) ,
143+ Expr :: Unsafe { body } => self . infer_expr ( * body, expected) ,
144+ Expr :: Const { body } => {
145+ self . with_breakable_ctx ( BreakableKind :: Border , self . err_ty ( ) , None , |this| {
146+ this. infer_expr ( * body, expected)
147+ } )
148+ . 1
149+ }
140150 Expr :: TryBlock { body } => {
141- let _inner = self . infer_expr ( * body, expected) ;
151+ self . with_breakable_ctx ( BreakableKind :: Border , self . err_ty ( ) , None , |this| {
152+ let _inner = this. infer_expr ( * body, expected) ;
153+ } ) ;
142154 // FIXME should be std::result::Result<{inner}, _>
143155 self . err_ty ( )
144156 }
@@ -147,7 +159,10 @@ impl<'a> InferenceContext<'a> {
147159 let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
148160 let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
149161
150- let inner_ty = self . infer_expr_coerce ( * body, & Expectation :: has_type ( ret_ty) ) ;
162+ let ( _, inner_ty) =
163+ self . with_breakable_ctx ( BreakableKind :: Border , self . err_ty ( ) , None , |this| {
164+ this. infer_expr_coerce ( * body, & Expectation :: has_type ( ret_ty) )
165+ } ) ;
151166
152167 self . diverges = prev_diverges;
153168 self . return_ty = prev_ret_ty;
@@ -161,9 +176,10 @@ impl<'a> InferenceContext<'a> {
161176 }
162177 & Expr :: Loop { body, label } => {
163178 let ty = self . table . new_type_var ( ) ;
164- let ( breaks, ( ) ) = self . with_breakable_ctx ( ty, label, |this| {
165- this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
166- } ) ;
179+ let ( breaks, ( ) ) =
180+ self . with_breakable_ctx ( BreakableKind :: Loop , ty, label, |this| {
181+ this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
182+ } ) ;
167183
168184 match breaks {
169185 Some ( breaks) => {
@@ -174,7 +190,7 @@ impl<'a> InferenceContext<'a> {
174190 }
175191 }
176192 & Expr :: While { condition, body, label } => {
177- self . with_breakable_ctx ( self . err_ty ( ) , label, |this| {
193+ self . with_breakable_ctx ( BreakableKind :: Loop , self . err_ty ( ) , label, |this| {
178194 this. infer_expr (
179195 condition,
180196 & Expectation :: has_type ( TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ) ,
@@ -192,7 +208,7 @@ impl<'a> InferenceContext<'a> {
192208 self . resolve_associated_type ( iterable_ty, self . resolve_into_iter_item ( ) ) ;
193209
194210 self . infer_pat ( pat, & pat_ty, BindingMode :: default ( ) ) ;
195- self . with_breakable_ctx ( self . err_ty ( ) , label, |this| {
211+ self . with_breakable_ctx ( BreakableKind :: Loop , self . err_ty ( ) , label, |this| {
196212 this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
197213 } ) ;
198214
@@ -251,7 +267,9 @@ impl<'a> InferenceContext<'a> {
251267 let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
252268 let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
253269
254- self . infer_expr_coerce ( * body, & Expectation :: has_type ( ret_ty) ) ;
270+ self . with_breakable_ctx ( BreakableKind :: Border , self . err_ty ( ) , None , |this| {
271+ this. infer_expr_coerce ( * body, & Expectation :: has_type ( ret_ty) ) ;
272+ } ) ;
255273
256274 self . diverges = prev_diverges;
257275 self . return_ty = prev_ret_ty;
@@ -355,7 +373,7 @@ impl<'a> InferenceContext<'a> {
355373 self . infer_path ( & resolver, p, tgt_expr. into ( ) ) . unwrap_or_else ( || self . err_ty ( ) )
356374 }
357375 Expr :: Continue { label } => {
358- if let None = find_breakable ( & mut self . breakables , label. as_ref ( ) ) {
376+ if let None = find_continuable ( & mut self . breakables , label. as_ref ( ) ) {
359377 self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
360378 expr : tgt_expr,
361379 is_break : false ,
@@ -1466,13 +1484,14 @@ impl<'a> InferenceContext<'a> {
14661484
14671485 fn with_breakable_ctx < T > (
14681486 & mut self ,
1487+ kind : BreakableKind ,
14691488 ty : Ty ,
14701489 label : Option < LabelId > ,
14711490 cb : impl FnOnce ( & mut Self ) -> T ,
14721491 ) -> ( Option < Ty > , T ) {
14731492 self . breakables . push ( {
14741493 let label = label. map ( |label| self . body [ label] . name . clone ( ) ) ;
1475- BreakableContext { may_break : false , coerce : CoerceMany :: new ( ty) , label }
1494+ BreakableContext { kind , may_break : false , coerce : CoerceMany :: new ( ty) , label }
14761495 } ) ;
14771496 let res = cb ( self ) ;
14781497 let ctx = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
0 commit comments