ide_diagnostics/handlers/
break_outside_of_loop.rs1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3pub(crate) fn break_outside_of_loop(
7 ctx: &DiagnosticsContext<'_>,
8 d: &hir::BreakOutsideOfLoop,
9) -> Diagnostic {
10 let message = if d.bad_value_break {
11 "can't break with a value in this position".to_owned()
12 } else {
13 let construct = if d.is_break { "break" } else { "continue" };
14 format!("{construct} outside of loop")
15 };
16 Diagnostic::new_with_syntax_node_ptr(
17 ctx,
18 DiagnosticCode::RustcHardError("E0268"),
19 message,
20 d.expr.map(|it| it.into()),
21 )
22 .stable()
23}
24
25#[cfg(test)]
26mod tests {
27 use crate::tests::check_diagnostics;
28
29 #[test]
30 fn outside_of_loop() {
31 check_diagnostics(
32 r#"
33fn foo() {
34 break;
35 //^^^^^ error: break outside of loop
36 continue;
37 //^^^^^^^^ error: continue outside of loop
38}
39"#,
40 );
41 }
42
43 #[test]
44 fn async_blocks_are_borders() {
45 check_diagnostics(
46 r#"
47fn foo() {
48 'a: loop {
49 async {
50 break;
51 //^^^^^ error: break outside of loop
52 continue;
53 //^^^^^^^^ error: continue outside of loop
54 };
55 }
56}
57"#,
58 );
59 }
60
61 #[test]
62 fn closures_are_borders() {
63 check_diagnostics(
64 r#"
65fn foo() {
66 'a: loop {
67 || {
68 break;
69 //^^^^^ error: break outside of loop
70 continue;
71 //^^^^^^^^ error: continue outside of loop
72 };
73 }
74}
75"#,
76 );
77 }
78
79 #[test]
80 fn blocks_pass_through() {
81 check_diagnostics(
82 r#"
83fn foo() {
84 'a: loop {
85 {
86 break;
87 continue;
88 }
89 }
90}
91"#,
92 );
93 }
94
95 #[test]
96 fn try_blocks_pass_through() {
97 check_diagnostics(
98 r#"
99fn foo() {
100 'a: loop {
101 try {
102 break;
103 continue;
104 };
105 }
106}
107"#,
108 );
109 }
110
111 #[test]
112 fn label_blocks() {
113 check_diagnostics(
114 r#"
115fn foo() {
116 'a: {
117 break;
118 //^^^^^ error: break outside of loop
119 continue;
120 //^^^^^^^^ error: continue outside of loop
121 }
122}
123"#,
124 );
125 }
126
127 #[test]
128 fn value_break_in_for_loop() {
129 check_diagnostics(
131 r#"
132//- minicore: iterator
133fn test() {
134 for _ in [()] {
135 break 3;
136 // ^ error: expected (), found i32
137 }
138}
139"#,
140 );
141 }
142
143 #[test]
144 fn try_block_desugaring_inside_closure() {
145 check_diagnostics(
147 r#"
148//- minicore: option, try
149fn test() {
150 try {
151 || {
152 let x = Some(2);
153 Some(x?)
154 };
155 };
156}
157"#,
158 );
159 }
160}