about summary refs log tree commit diff
diff options
context:
space:
mode:
authoriDawer <ilnur.iskhakov.oss@outlook.com>2022-04-14 17:44:17 +0500
committeriDawer <ilnur.iskhakov.oss@outlook.com>2022-04-16 13:53:22 +0500
commit9d787e1bfe79064be4376c914ce11948041ccbef (patch)
treef1e1df7e6f8f3bde9e6c4cc4e89e8ba344a4c5bb
parentf972adc2012fc49b35124d080a000a0d44c95452 (diff)
downloadrust-9d787e1bfe79064be4376c914ce11948041ccbef.tar.gz
rust-9d787e1bfe79064be4376c914ce11948041ccbef.zip
Add `hir::Function::async_ret_type` method
Adjust completion detail for `async fn` return types
-rw-r--r--crates/hir/src/lib.rs17
-rw-r--r--crates/ide_completion/src/render/function.rs2
-rw-r--r--crates/ide_completion/src/tests/expression.rs5
3 files changed, 21 insertions, 3 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 7cda75b3478..5aa1ca7e0ba 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1364,6 +1364,23 @@ impl Function {
         Type::new_with_resolver_inner(db, &resolver, ty)
     }
 
+    pub fn async_ret_type(self, db: &dyn HirDatabase) -> Option<Type> {
+        if !self.is_async(db) {
+            return None;
+        }
+        let resolver = self.id.resolver(db.upcast());
+        let substs = TyBuilder::placeholder_subst(db, self.id);
+        let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs);
+        let ret_ty = callable_sig.ret().clone();
+        for pred in ret_ty.impl_trait_bounds(db).into_iter().flatten() {
+            if let WhereClause::AliasEq(output_eq) = pred.into_value_and_skipped_binders().0 {
+                return Type::new_with_resolver_inner(db, &resolver, output_eq.ty).into();
+            }
+        }
+        never!("Async fn ret_type should be impl Future");
+        None
+    }
+
     pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
         if !db.function_data(self.id).has_self_param() {
             return None;
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 38520e1832f..cbaecd208df 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -228,7 +228,7 @@ fn should_add_parens(ctx: &CompletionContext) -> bool {
 }
 
 fn detail(db: &dyn HirDatabase, func: hir::Function) -> String {
-    let ret_ty = func.ret_type(db);
+    let ret_ty = func.async_ret_type(db).unwrap_or_else(|| func.ret_type(db));
     let mut detail = String::new();
 
     if func.is_const(db) {
diff --git a/crates/ide_completion/src/tests/expression.rs b/crates/ide_completion/src/tests/expression.rs
index f25e14e0fcd..77296d9099f 100644
--- a/crates/ide_completion/src/tests/expression.rs
+++ b/crates/ide_completion/src/tests/expression.rs
@@ -624,12 +624,12 @@ fn main() {
 
 #[test]
 fn detail_async_fn() {
-    // FIXME: #11438
     check_empty(
         r#"
 //- minicore: future, sized
 trait Trait<T> {}
 async fn foo() -> u8 {}
+async fn bar<U>() -> impl Trait<U> {}
 fn main() {
     self::$0
 }
@@ -637,7 +637,8 @@ fn main() {
         expect![[r"
             tt Trait
             fn main() fn()
-            fn foo()  async fn() -> impl Future<Output = u8>
+            fn bar()  async fn() -> impl Trait<U>
+            fn foo()  async fn() -> u8
         "]],
     );
 }