ide_diagnostics/handlers/
parenthesized_generic_args_without_fn_trait.rs

1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3// Diagnostic: parenthesized-generic-args-without-fn-trait
4//
5// This diagnostic is shown when a `Fn`-trait-style generic parameters (`Trait(A, B) -> C`)
6// was used on non-`Fn` trait/type.
7pub(crate) fn parenthesized_generic_args_without_fn_trait(
8    ctx: &DiagnosticsContext<'_>,
9    d: &hir::ParenthesizedGenericArgsWithoutFnTrait,
10) -> Diagnostic {
11    Diagnostic::new_with_syntax_node_ptr(
12        ctx,
13        DiagnosticCode::RustcHardError("E0214"),
14        "parenthesized type parameters may only be used with a `Fn` trait",
15        d.args.map(Into::into),
16    )
17    .stable()
18}
19
20#[cfg(test)]
21mod tests {
22    use crate::tests::check_diagnostics;
23
24    #[test]
25    fn fn_traits_work() {
26        check_diagnostics(
27            r#"
28//- minicore: async_fn, fn
29fn foo<
30    A: Fn(),
31    B: FnMut() -> i32,
32    C: FnOnce(&str, bool),
33    D: AsyncFn::(u32) -> u32,
34    E: AsyncFnMut(),
35    F: AsyncFnOnce() -> bool,
36>() {}
37        "#,
38        );
39    }
40
41    #[test]
42    fn non_fn_trait() {
43        check_diagnostics(
44            r#"
45struct Struct<T>(T);
46enum Enum<T> { EnumVariant(T) }
47type TypeAlias<T> = bool;
48
49type Foo = TypeAlias() -> bool;
50                 // ^^ error: parenthesized type parameters may only be used with a `Fn` trait
51
52fn foo(_a: Struct(i32)) {
53              // ^^^^^ error: parenthesized type parameters may only be used with a `Fn` trait
54    let _ = <Enum::(u32)>::EnumVariant(0);
55              // ^^^^^^^ error: parenthesized type parameters may only be used with a `Fn` trait
56}
57        "#,
58        );
59    }
60}