ra_ap_ide_diagnostics/handlers/
undeclared_label.rs1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3pub(crate) fn undeclared_label(
5 ctx: &DiagnosticsContext<'_>,
6 d: &hir::UndeclaredLabel,
7) -> Diagnostic {
8 let name = &d.name;
9 Diagnostic::new_with_syntax_node_ptr(
10 ctx,
11 DiagnosticCode::RustcHardError("undeclared-label"),
12 format!("use of undeclared label `{}`", name.display(ctx.sema.db, ctx.edition)),
13 d.node.map(|it| it.into()),
14 )
15 .stable()
16}
17
18#[cfg(test)]
19mod tests {
20 use crate::tests::check_diagnostics;
21
22 #[test]
23 fn smoke_test() {
24 check_diagnostics(
25 r#"
26fn foo() {
27 break 'a;
28 //^^^^^^^^ error: break outside of loop
29 //^^ error: use of undeclared label `'a`
30 continue 'a;
31 //^^^^^^^^^^^ error: continue outside of loop
32 //^^ error: use of undeclared label `'a`
33}
34"#,
35 );
36 }
37
38 #[test]
39 fn while_let_loop_with_label_in_condition() {
40 check_diagnostics(
41 r#"
42//- minicore: option
43
44fn foo() {
45 let mut optional = Some(0);
46
47 'my_label: while let Some(_) = match optional {
48 None => break 'my_label,
49 Some(val) => Some(val),
50 } {
51 optional = None;
52 continue 'my_label;
53 }
54}
55"#,
56 );
57 }
58
59 #[test]
60 fn for_loop() {
61 check_diagnostics(
62 r#"
63//- minicore: iterator
64fn foo() {
65 'xxx: for _ in [] {
66 'yyy: for _ in [] {
67 break 'xxx;
68 continue 'yyy;
69 break 'zzz;
70 //^^^^ error: use of undeclared label `'zzz`
71 }
72 continue 'xxx;
73 continue 'yyy;
74 //^^^^ error: use of undeclared label `'yyy`
75 break 'xxx;
76 break 'yyy;
77 //^^^^ error: use of undeclared label `'yyy`
78 }
79}
80"#,
81 );
82 }
83
84 #[test]
85 fn try_operator_desugar_works() {
86 check_diagnostics(
87 r#"
88//- minicore: option, try
89fn foo() {
90 None?;
91}
92"#,
93 );
94 check_diagnostics(
95 r#"
96//- minicore: option, try, future
97async fn foo() {
98 None?;
99}
100"#,
101 );
102 check_diagnostics(
103 r#"
104//- minicore: option, try, future, fn
105async fn foo() {
106 || None?;
107}
108"#,
109 );
110 }
111
112 #[test]
113 fn macro_expansion_can_refer_label_defined_before_macro_definition() {
114 check_diagnostics(
115 r#"
116fn foo() {
117 'bar: loop {
118 macro_rules! m {
119 () => { break 'bar };
120 }
121 m!();
122 }
123}
124"#,
125 );
126 check_diagnostics(
127 r#"
128fn foo() {
129 'bar: loop {
130 macro_rules! m {
131 () => { break 'bar };
132 }
133 'bar: loop {
134 m!();
135 }
136 }
137}
138"#,
139 );
140 }
141}