about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_passes/messages.ftl10
-rw-r--r--compiler/rustc_passes/src/errors.rs10
-rw-r--r--compiler/rustc_passes/src/loops.rs32
3 files changed, 34 insertions, 18 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 9d58d301e2b..3deefcaa06c 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -52,16 +52,16 @@ passes_attr_only_in_functions =
 passes_both_ffi_const_and_pure =
     `#[ffi_const]` function cannot be `#[ffi_pure]`
 
-passes_break_inside_async_block =
-    `{$name}` inside of an `async` block
-    .label = cannot `{$name}` inside of an `async` block
-    .async_block_label = enclosing `async` block
-
 passes_break_inside_closure =
     `{$name}` inside of a closure
     .label = cannot `{$name}` inside of a closure
     .closure_label = enclosing closure
 
+passes_break_inside_coroutine =
+    `{$name}` inside `{$kind}` {$source}
+    .label = cannot `{$name}` inside `{$kind}` {$source}
+    .coroutine_label = enclosing `{$kind}` {$source}
+
 passes_break_non_loop =
     `break` with value from a `{$kind}` loop
     .label = can only break with a value inside `loop` or breakable block
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 65cad82cc8c..b8586e7e974 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1086,14 +1086,16 @@ pub struct BreakInsideClosure<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_break_inside_async_block, code = E0267)]
-pub struct BreakInsideAsyncBlock<'a> {
+#[diag(passes_break_inside_coroutine, code = E0267)]
+pub struct BreakInsideCoroutine<'a> {
     #[primary_span]
     #[label]
     pub span: Span,
-    #[label(passes_async_block_label)]
-    pub closure_span: Span,
+    #[label(passes_coroutine_label)]
+    pub coroutine_span: Span,
     pub name: &'a str,
+    pub kind: &'a str,
+    pub source: &'a str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 4b5c4dfe991..3b20112eab7 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -13,7 +13,7 @@ use rustc_span::hygiene::DesugaringKind;
 use rustc_span::{BytePos, Span};
 
 use crate::errors::{
-    BreakInsideAsyncBlock, BreakInsideClosure, BreakNonLoop, ContinueLabeledBlock, OutsideLoop,
+    BreakInsideClosure, BreakInsideCoroutine, BreakNonLoop, ContinueLabeledBlock, OutsideLoop,
     OutsideLoopSuggestion, UnlabeledCfInWhileCondition, UnlabeledInLabeledBlock,
 };
 
@@ -23,7 +23,7 @@ enum Context {
     Fn,
     Loop(hir::LoopSource),
     Closure(Span),
-    AsyncClosure(Span),
+    Coroutine { coroutine_span: Span, kind: hir::CoroutineDesugaring, source: hir::CoroutineSource },
     UnlabeledBlock(Span),
     LabeledBlock,
     Constant,
@@ -89,12 +89,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
             hir::ExprKind::Closure(&hir::Closure {
                 ref fn_decl, body, fn_decl_span, kind, ..
             }) => {
-                // FIXME(coroutines): This doesn't handle coroutines correctly
                 let cx = match kind {
-                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(
-                        hir::CoroutineDesugaring::Async,
-                        hir::CoroutineSource::Block,
-                    )) => AsyncClosure(fn_decl_span),
+                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(kind, source)) => {
+                        Coroutine { coroutine_span: fn_decl_span, kind, source }
+                    }
                     _ => Closure(fn_decl_span),
                 };
                 self.visit_fn_decl(fn_decl);
@@ -227,8 +225,24 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
             Closure(closure_span) => {
                 self.sess.dcx().emit_err(BreakInsideClosure { span, closure_span, name });
             }
-            AsyncClosure(closure_span) => {
-                self.sess.dcx().emit_err(BreakInsideAsyncBlock { span, closure_span, name });
+            Coroutine { coroutine_span, kind, source } => {
+                let kind = match kind {
+                    hir::CoroutineDesugaring::Async => "async",
+                    hir::CoroutineDesugaring::Gen => "gen",
+                    hir::CoroutineDesugaring::AsyncGen => "async gen",
+                };
+                let source = match source {
+                    hir::CoroutineSource::Block => "block",
+                    hir::CoroutineSource::Closure => "closure",
+                    hir::CoroutineSource::Fn => "function",
+                };
+                self.sess.dcx().emit_err(BreakInsideCoroutine {
+                    span,
+                    coroutine_span,
+                    name,
+                    kind,
+                    source,
+                });
             }
             UnlabeledBlock(block_span) if is_break && block_span.eq_ctxt(break_span) => {
                 let suggestion = Some(OutsideLoopSuggestion { block_span, break_span });