@@ -23,7 +23,7 @@ use syntax::ast::RangeOp;
23
23
use crate :: {
24
24
autoderef:: { self , Autoderef } ,
25
25
consteval,
26
- infer:: coerce:: CoerceMany ,
26
+ infer:: { coerce:: CoerceMany , find_continuable , BreakableKind } ,
27
27
lower:: {
28
28
const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability, ParamLoweringMode ,
29
29
} ,
@@ -120,25 +120,37 @@ impl<'a> InferenceContext<'a> {
120
120
let ty = match label {
121
121
Some ( _) => {
122
122
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| {
125
128
this. infer_block (
126
129
tgt_expr,
127
130
statements,
128
131
* tail,
129
132
& Expectation :: has_type ( break_ty) ,
130
133
)
131
- } ) ;
134
+ } ,
135
+ ) ;
132
136
breaks. unwrap_or ( ty)
133
137
}
134
138
None => self . infer_block ( tgt_expr, statements, * tail, expected) ,
135
139
} ;
136
140
self . resolver = old_resolver;
137
141
ty
138
142
}
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
+ }
140
150
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
+ } ) ;
142
154
// FIXME should be std::result::Result<{inner}, _>
143
155
self . err_ty ( )
144
156
}
@@ -147,7 +159,10 @@ impl<'a> InferenceContext<'a> {
147
159
let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
148
160
let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
149
161
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
+ } ) ;
151
166
152
167
self . diverges = prev_diverges;
153
168
self . return_ty = prev_ret_ty;
@@ -161,9 +176,10 @@ impl<'a> InferenceContext<'a> {
161
176
}
162
177
& Expr :: Loop { body, label } => {
163
178
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
+ } ) ;
167
183
168
184
match breaks {
169
185
Some ( breaks) => {
@@ -174,7 +190,7 @@ impl<'a> InferenceContext<'a> {
174
190
}
175
191
}
176
192
& 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| {
178
194
this. infer_expr (
179
195
condition,
180
196
& Expectation :: has_type ( TyKind :: Scalar ( Scalar :: Bool ) . intern ( Interner ) ) ,
@@ -192,7 +208,7 @@ impl<'a> InferenceContext<'a> {
192
208
self . resolve_associated_type ( iterable_ty, self . resolve_into_iter_item ( ) ) ;
193
209
194
210
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| {
196
212
this. infer_expr ( body, & Expectation :: has_type ( TyBuilder :: unit ( ) ) ) ;
197
213
} ) ;
198
214
@@ -251,7 +267,9 @@ impl<'a> InferenceContext<'a> {
251
267
let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
252
268
let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
253
269
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
+ } ) ;
255
273
256
274
self . diverges = prev_diverges;
257
275
self . return_ty = prev_ret_ty;
@@ -355,7 +373,7 @@ impl<'a> InferenceContext<'a> {
355
373
self . infer_path ( & resolver, p, tgt_expr. into ( ) ) . unwrap_or_else ( || self . err_ty ( ) )
356
374
}
357
375
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 ( ) ) {
359
377
self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
360
378
expr : tgt_expr,
361
379
is_break : false ,
@@ -1466,13 +1484,14 @@ impl<'a> InferenceContext<'a> {
1466
1484
1467
1485
fn with_breakable_ctx < T > (
1468
1486
& mut self ,
1487
+ kind : BreakableKind ,
1469
1488
ty : Ty ,
1470
1489
label : Option < LabelId > ,
1471
1490
cb : impl FnOnce ( & mut Self ) -> T ,
1472
1491
) -> ( Option < Ty > , T ) {
1473
1492
self . breakables . push ( {
1474
1493
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 }
1476
1495
} ) ;
1477
1496
let res = cb ( self ) ;
1478
1497
let ctx = self . breakables . pop ( ) . expect ( "breakable stack broken" ) ;
0 commit comments