Skip to content

Commit dc3219b

Browse files
committed
Suggest .await when type impls IntoFuture
1 parent 5810c81 commit dc3219b

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

crates/hir/src/lib.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,19 +2780,28 @@ impl Type {
27802780
/// Checks that particular type `ty` implements `std::future::Future`.
27812781
/// This function is used in `.await` syntax completion.
27822782
pub fn impls_future(&self, db: &dyn HirDatabase) -> bool {
2783-
// FIXME: This should be checking for IntoFuture trait, but I don't know how to find the
2784-
// right TraitId in this crate.
2785-
let std_future_trait = db
2786-
.lang_item(self.env.krate, SmolStr::new_inline("future_trait"))
2787-
.and_then(|it| it.as_trait());
2788-
let std_future_trait = match std_future_trait {
2783+
let trait_ = db
2784+
.lang_item(self.env.krate, SmolStr::new_inline("into_future"))
2785+
.and_then(|it| {
2786+
let into_future_fn = it.as_function()?;
2787+
let assoc_item = as_assoc_item(db, AssocItem::Function, into_future_fn)?;
2788+
let into_future_trait = assoc_item.containing_trait_or_trait_impl(db)?;
2789+
Some(into_future_trait.id)
2790+
})
2791+
.or_else(|| {
2792+
let future_trait =
2793+
db.lang_item(self.env.krate, SmolStr::new_inline("future_trait"))?;
2794+
future_trait.as_trait()
2795+
});
2796+
2797+
let trait_ = match trait_ {
27892798
Some(it) => it,
27902799
None => return false,
27912800
};
27922801

27932802
let canonical_ty =
27942803
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
2795-
method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), std_future_trait)
2804+
method_resolution::implements_trait(&canonical_ty, db, self.env.clone(), trait_)
27962805
}
27972806

27982807
/// Checks that particular type `ty` implements `std::ops::FnOnce`.

crates/ide-completion/src/completions/keyword.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,32 @@ fn foo() {
114114
);
115115
}
116116

117+
#[test]
118+
fn test_completion_await_impls_into_future() {
119+
check(
120+
r#"
121+
//- minicore: future
122+
use core::future::*;
123+
struct A {}
124+
impl IntoFuture for A {}
125+
fn foo(a: A) { a.$0 }
126+
"#,
127+
expect![[r#"
128+
kw await expr.await
129+
me into_future() (as IntoFuture) fn(self) -> <Self as IntoFuture>::IntoFuture
130+
sn box Box::new(expr)
131+
sn call function(expr)
132+
sn dbg dbg!(expr)
133+
sn dbgr dbg!(&expr)
134+
sn let let
135+
sn letm let mut
136+
sn match match expr {}
137+
sn ref &expr
138+
sn refm &mut expr
139+
"#]],
140+
);
141+
}
142+
117143
#[test]
118144
fn let_semi() {
119145
cov_mark::check!(let_semi);

0 commit comments

Comments
 (0)