ide_diagnostics/handlers/
await_outside_of_async.rs

1use crate::{Diagnostic, DiagnosticsContext, adjusted_display_range};
2
3// Diagnostic: await-outside-of-async
4//
5// This diagnostic is triggered if the `await` keyword is used outside of an async function or block
6pub(crate) fn await_outside_of_async(
7    ctx: &DiagnosticsContext<'_>,
8    d: &hir::AwaitOutsideOfAsync,
9) -> Diagnostic {
10    let display_range =
11        adjusted_display_range(ctx, d.node, &|node| Some(node.await_token()?.text_range()));
12    Diagnostic::new(
13        crate::DiagnosticCode::RustcHardError("E0728"),
14        format!("`await` is used inside {}, which is not an `async` context", d.location),
15        display_range,
16    )
17    .stable()
18}
19
20#[cfg(test)]
21mod tests {
22    use crate::tests::check_diagnostics;
23
24    #[test]
25    fn await_inside_non_async_fn() {
26        check_diagnostics(
27            r#"
28async fn foo() {}
29
30fn bar() {
31    foo().await;
32        //^^^^^ error: `await` is used inside non-async function, which is not an `async` context
33}
34"#,
35        );
36    }
37
38    #[test]
39    fn await_inside_async_fn() {
40        check_diagnostics(
41            r#"
42async fn foo() {}
43
44async fn bar() {
45    foo().await;
46}
47"#,
48        );
49    }
50
51    #[test]
52    fn await_inside_closure() {
53        check_diagnostics(
54            r#"
55async fn foo() {}
56
57async fn bar() {
58    let _a = || { foo().await };
59                      //^^^^^ error: `await` is used inside non-async closure, which is not an `async` context
60}
61"#,
62        );
63    }
64
65    #[test]
66    fn await_inside_async_block() {
67        check_diagnostics(
68            r#"
69async fn foo() {}
70
71fn bar() {
72    let _a = async { foo().await };
73}
74"#,
75        );
76    }
77
78    #[test]
79    fn await_in_complex_context() {
80        check_diagnostics(
81            r#"
82async fn foo() {}
83
84fn bar() {
85    async fn baz() {
86        let a = foo().await;
87    }
88
89    let x = || {
90        let y = async {
91            baz().await;
92            let z = || {
93                baz().await;
94                    //^^^^^ error: `await` is used inside non-async closure, which is not an `async` context
95            };
96        };
97    };
98}
99"#,
100        );
101    }
102}