summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs')
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs120
1 files changed, 116 insertions, 4 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
index d12594a4c..0c92e706b 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
@@ -7,9 +7,10 @@ pub(crate) fn break_outside_of_loop(
ctx: &DiagnosticsContext<'_>,
d: &hir::BreakOutsideOfLoop,
) -> Diagnostic {
+ let construct = if d.is_break { "break" } else { "continue" };
Diagnostic::new(
"break-outside-of-loop",
- "break outside of loop",
+ format!("{construct} outside of loop"),
ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
)
}
@@ -19,11 +20,122 @@ mod tests {
use crate::tests::check_diagnostics;
#[test]
- fn break_outside_of_loop() {
+ fn outside_of_loop() {
check_diagnostics(
r#"
-fn foo() { break; }
- //^^^^^ error: break outside of loop
+fn foo() {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn try_blocks_are_borders() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ try {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn async_blocks_are_borders() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ try {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn closures_are_borders() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ try {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ //^^^^^^^^ error: break outside of loop
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ };
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn blocks_pass_through() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: loop {
+ {
+ break;
+ break 'a;
+ continue;
+ continue 'a;
+ }
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn label_blocks() {
+ check_diagnostics(
+ r#"
+fn foo() {
+ 'a: {
+ break;
+ //^^^^^ error: break outside of loop
+ break 'a;
+ continue;
+ //^^^^^^^^ error: continue outside of loop
+ continue 'a;
+ //^^^^^^^^^^^ error: continue outside of loop
+ }
+}
"#,
);
}