]> git.lizzy.rs Git - rust.git/blob - crates/ide-diagnostics/src/handlers/break_outside_of_loop.rs
Actually test closures in `closures_are_borders`
[rust.git] / crates / ide-diagnostics / src / handlers / break_outside_of_loop.rs
1 use crate::{Diagnostic, DiagnosticsContext};
2
3 // Diagnostic: break-outside-of-loop
4 //
5 // This diagnostic is triggered if the `break` keyword is used outside of a loop.
6 pub(crate) fn break_outside_of_loop(
7     ctx: &DiagnosticsContext<'_>,
8     d: &hir::BreakOutsideOfLoop,
9 ) -> Diagnostic {
10     let construct = if d.is_break { "break" } else { "continue" };
11     Diagnostic::new(
12         "break-outside-of-loop",
13         format!("{construct} outside of loop"),
14         ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range,
15     )
16 }
17
18 #[cfg(test)]
19 mod tests {
20     use crate::tests::check_diagnostics;
21
22     #[test]
23     fn outside_of_loop() {
24         check_diagnostics(
25             r#"
26 fn foo() {
27     break;
28   //^^^^^ error: break outside of loop
29     break 'a;
30   //^^^^^^^^ error: break outside of loop
31     continue;
32   //^^^^^^^^ error: continue outside of loop
33     continue 'a;
34   //^^^^^^^^^^^ error: continue outside of loop
35 }
36 "#,
37         );
38     }
39
40     #[test]
41     fn async_blocks_are_borders() {
42         check_diagnostics(
43             r#"
44 fn foo() {
45     'a: loop {
46         async {
47                 break;
48               //^^^^^ error: break outside of loop
49                 break 'a;
50               //^^^^^^^^ error: break outside of loop
51                 continue;
52               //^^^^^^^^ error: continue outside of loop
53                 continue 'a;
54               //^^^^^^^^^^^ error: continue outside of loop
55         };
56     }
57 }
58 "#,
59         );
60     }
61
62     #[test]
63     fn closures_are_borders() {
64         check_diagnostics(
65             r#"
66 fn foo() {
67     'a: loop {
68         || {
69                 break;
70               //^^^^^ error: break outside of loop
71                 break 'a;
72               //^^^^^^^^ error: break outside of loop
73                 continue;
74               //^^^^^^^^ error: continue outside of loop
75                 continue 'a;
76               //^^^^^^^^^^^ error: continue outside of loop
77         };
78     }
79 }
80 "#,
81         );
82     }
83
84     #[test]
85     fn blocks_pass_through() {
86         check_diagnostics(
87             r#"
88 fn foo() {
89     'a: loop {
90         {
91             break;
92             break 'a;
93             continue;
94             continue 'a;
95         }
96     }
97 }
98 "#,
99         );
100     }
101
102     #[test]
103     fn try_blocks_pass_through() {
104         check_diagnostics(
105             r#"
106 fn foo() {
107     'a: loop {
108         try {
109                 break;
110                 break 'a;
111                 continue;
112                 continue 'a;
113         };
114     }
115 }
116 "#,
117         );
118     }
119
120     #[test]
121     fn label_blocks() {
122         check_diagnostics(
123             r#"
124 fn foo() {
125     'a: {
126         break;
127       //^^^^^ error: break outside of loop
128         break 'a;
129         continue;
130       //^^^^^^^^ error: continue outside of loop
131         continue 'a;
132       //^^^^^^^^^^^ error: continue outside of loop
133     }
134 }
135 "#,
136         );
137     }
138 }