about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_def/src/path.rs10
-rw-r--r--crates/hir_def/src/path/lower.rs4
-rw-r--r--crates/hir_ty/src/display.rs10
3 files changed, 21 insertions, 3 deletions
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index d17e6b1834e..a54352439ca 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -135,6 +135,9 @@ pub struct GenericArgs {
     pub has_self_type: bool,
     /// Associated type bindings like in `Iterator<Item = T>`.
     pub bindings: Vec<AssociatedTypeBinding>,
+    /// Whether these generic args were desugared from `Trait(Arg) -> Output`
+    /// parenthesis notation typically used for the `Fn` traits.
+    pub desugared_from_fn: bool,
 }
 
 /// An associated type binding like in `Iterator<Item = T>`.
@@ -269,7 +272,12 @@ impl GenericArgs {
     }
 
     pub(crate) fn empty() -> GenericArgs {
-        GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() }
+        GenericArgs {
+            args: Vec::new(),
+            has_self_type: false,
+            bindings: Vec::new(),
+            desugared_from_fn: false,
+        }
     }
 }
 
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index 99e7cdc999c..b08708bd28a 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -193,7 +193,7 @@ pub(super) fn lower_generic_args(
     if args.is_empty() && bindings.is_empty() {
         return None;
     }
-    Some(GenericArgs { args, has_self_type: false, bindings })
+    Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: false })
 }
 
 /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
@@ -229,5 +229,5 @@ fn lower_generic_args_from_fn_path(
             bounds: Vec::new(),
         });
     }
-    Some(GenericArgs { args, has_self_type: false, bindings })
+    Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: true })
 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index adce43aa07e..d1ca50c6909 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -1162,6 +1162,16 @@ impl HirDisplay for Path {
             if let Some(generic_args) = segment.args_and_bindings {
                 // We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
                 // Do we actually format expressions?
+                if generic_args.desugared_from_fn {
+                    // First argument will be a tuple, which already includes the parentheses.
+                    generic_args.args[0].hir_fmt(f)?;
+                    if let Some(ret) = &generic_args.bindings[0].type_ref {
+                        write!(f, " -> ")?;
+                        ret.hir_fmt(f)?;
+                    }
+                    return Ok(());
+                }
+
                 write!(f, "<")?;
                 let mut first = true;
                 for arg in &generic_args.args {