@@ -13,7 +13,7 @@ use rustc_span::hygiene::DesugaringKind;
13
13
use rustc_span:: { BytePos , Span } ;
14
14
15
15
use crate :: errors:: {
16
- BreakInsideAsyncBlock , BreakInsideClosure , BreakNonLoop , ContinueLabeledBlock , OutsideLoop ,
16
+ BreakInsideClosure , BreakInsideCoroutine , BreakNonLoop , ContinueLabeledBlock , OutsideLoop ,
17
17
OutsideLoopSuggestion , UnlabeledCfInWhileCondition , UnlabeledInLabeledBlock ,
18
18
} ;
19
19
@@ -23,7 +23,7 @@ enum Context {
23
23
Fn ,
24
24
Loop ( hir:: LoopSource ) ,
25
25
Closure ( Span ) ,
26
- AsyncClosure ( Span ) ,
26
+ Coroutine { coroutine_span : Span , kind : hir :: CoroutineDesugaring , source : hir :: CoroutineSource } ,
27
27
UnlabeledBlock ( Span ) ,
28
28
LabeledBlock ,
29
29
Constant ,
@@ -89,12 +89,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
89
89
hir:: ExprKind :: Closure ( & hir:: Closure {
90
90
ref fn_decl, body, fn_decl_span, kind, ..
91
91
} ) => {
92
- // FIXME(coroutines): This doesn't handle coroutines correctly
93
92
let cx = match kind {
94
- hir:: ClosureKind :: Coroutine ( hir:: CoroutineKind :: Desugared (
95
- hir:: CoroutineDesugaring :: Async ,
96
- hir:: CoroutineSource :: Block ,
97
- ) ) => AsyncClosure ( fn_decl_span) ,
93
+ hir:: ClosureKind :: Coroutine ( hir:: CoroutineKind :: Desugared ( kind, source) ) => {
94
+ Coroutine { coroutine_span : fn_decl_span, kind, source }
95
+ }
98
96
_ => Closure ( fn_decl_span) ,
99
97
} ;
100
98
self . visit_fn_decl ( fn_decl) ;
@@ -227,8 +225,131 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
227
225
Closure ( closure_span) => {
228
226
self . sess . dcx ( ) . emit_err ( BreakInsideClosure { span, closure_span, name } ) ;
229
227
}
230
- AsyncClosure ( closure_span) => {
231
- self . sess . dcx ( ) . emit_err ( BreakInsideAsyncBlock { span, closure_span, name } ) ;
228
+ Coroutine {
229
+ coroutine_span,
230
+ kind : hir:: CoroutineDesugaring :: Async ,
231
+ source : hir:: CoroutineSource :: Block ,
232
+ } => {
233
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
234
+ span,
235
+ coroutine_span,
236
+ name,
237
+ kind : "async" ,
238
+ source : "block" ,
239
+ article : "an" ,
240
+ } ) ;
241
+ }
242
+ Coroutine {
243
+ coroutine_span,
244
+ kind : hir:: CoroutineDesugaring :: Async ,
245
+ source : hir:: CoroutineSource :: Closure ,
246
+ } => {
247
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
248
+ span,
249
+ coroutine_span,
250
+ name,
251
+ kind : "async" ,
252
+ source : "closure" ,
253
+ article : "an" ,
254
+ } ) ;
255
+ }
256
+ Coroutine {
257
+ coroutine_span,
258
+ kind : hir:: CoroutineDesugaring :: Async ,
259
+ source : hir:: CoroutineSource :: Fn ,
260
+ } => {
261
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
262
+ span,
263
+ coroutine_span,
264
+ name,
265
+ kind : "async" ,
266
+ source : "function" ,
267
+ article : "an" ,
268
+ } ) ;
269
+ }
270
+ Coroutine {
271
+ coroutine_span,
272
+ kind : hir:: CoroutineDesugaring :: Gen ,
273
+ source : hir:: CoroutineSource :: Block ,
274
+ } => {
275
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
276
+ span,
277
+ coroutine_span,
278
+ name,
279
+ kind : "gen" ,
280
+ source : "block" ,
281
+ article : "a" ,
282
+ } ) ;
283
+ }
284
+ Coroutine {
285
+ coroutine_span,
286
+ kind : hir:: CoroutineDesugaring :: Gen ,
287
+ source : hir:: CoroutineSource :: Closure ,
288
+ } => {
289
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
290
+ span,
291
+ coroutine_span,
292
+ name,
293
+ kind : "gen" ,
294
+ source : "closure" ,
295
+ article : "a" ,
296
+ } ) ;
297
+ }
298
+ Coroutine {
299
+ coroutine_span,
300
+ kind : hir:: CoroutineDesugaring :: Gen ,
301
+ source : hir:: CoroutineSource :: Fn ,
302
+ } => {
303
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
304
+ span,
305
+ coroutine_span,
306
+ name,
307
+ kind : "gen" ,
308
+ source : "function" ,
309
+ article : "a" ,
310
+ } ) ;
311
+ }
312
+ Coroutine {
313
+ coroutine_span,
314
+ kind : hir:: CoroutineDesugaring :: AsyncGen ,
315
+ source : hir:: CoroutineSource :: Block ,
316
+ } => {
317
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
318
+ span,
319
+ coroutine_span,
320
+ name,
321
+ kind : "async gen" ,
322
+ source : "block" ,
323
+ article : "an" ,
324
+ } ) ;
325
+ }
326
+ Coroutine {
327
+ coroutine_span,
328
+ kind : hir:: CoroutineDesugaring :: AsyncGen ,
329
+ source : hir:: CoroutineSource :: Closure ,
330
+ } => {
331
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
332
+ span,
333
+ coroutine_span,
334
+ name,
335
+ kind : "async gen" ,
336
+ source : "closure" ,
337
+ article : "an" ,
338
+ } ) ;
339
+ }
340
+ Coroutine {
341
+ coroutine_span,
342
+ kind : hir:: CoroutineDesugaring :: AsyncGen ,
343
+ source : hir:: CoroutineSource :: Fn ,
344
+ } => {
345
+ self . sess . dcx ( ) . emit_err ( BreakInsideCoroutine {
346
+ span,
347
+ coroutine_span,
348
+ name,
349
+ kind : "async gen" ,
350
+ source : "function" ,
351
+ article : "an" ,
352
+ } ) ;
232
353
}
233
354
UnlabeledBlock ( block_span) if is_break && block_span. eq_ctxt ( break_span) => {
234
355
let suggestion = Some ( OutsideLoopSuggestion { block_span, break_span } ) ;
0 commit comments