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() -> Option<()> {
90 None?;
91 None
92}
93"#,
94 );
95 check_diagnostics(
96 r#"
97//- minicore: option, try, future
98async fn foo() -> Option<()> {
99 None?;
100 None
101}
102"#,
103 );
104 check_diagnostics(
105 r#"
106//- minicore: option, try, future, fn
107async fn foo() {
108 || { None?; Some(()) };
109}
110"#,
111 );
112 }
113
114 #[test]
115 fn macro_expansion_can_refer_label_defined_before_macro_definition() {
116 check_diagnostics(
117 r#"
118fn foo() {
119 'bar: loop {
120 macro_rules! m {
121 () => { break 'bar };
122 }
123 m!();
124 }
125}
126"#,
127 );
128 check_diagnostics(
129 r#"
130fn foo() {
131 'bar: loop {
132 macro_rules! m {
133 () => { break 'bar };
134 }
135 'bar: loop {
136 m!();
137 }
138 }
139}
140"#,
141 );
142 }
143}