aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_binder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r--crates/ra_hir/src/source_binder.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index c2c6921cb..8496b143a 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -23,6 +23,7 @@ use crate::{
23 scope::{ExprScopes, ScopeId}, 23 scope::{ExprScopes, ScopeId},
24 BodySourceMap, 24 BodySourceMap,
25 }, 25 },
26 ty::method_resolution::implements_trait,
26 ids::LocationCtx, 27 ids::LocationCtx,
27 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId, 28 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
28 MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty, 29 MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty,
@@ -409,6 +410,42 @@ impl SourceAnalyzer {
409 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 410 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
410 } 411 }
411 412
413 /// Checks that particular type `ty` implements `std::future::Future` trait.
414 /// This function is used in `.await` syntax completion.
415 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
416 // Search for std::future::Future trait in scope
417 let future_trait = self.resolver.traits_in_scope(db)
418 .into_iter()
419 .filter(|t| {
420 let std = t.module(db).parent(db)
421 .and_then(|m| m
422 .name(db)
423 .and_then(|n| Some(n.to_string() == "std")))
424 .unwrap_or(false);
425
426 let future = t.module(db).name(db)
427 .and_then(|n| Some(n.to_string() == "future"))
428 .unwrap_or(false);
429
430 let future_trait = t.name(db)
431 .and_then(|n| Some(n.to_string() == "Future"))
432 .unwrap_or(false);
433
434 std && future && future_trait
435 })
436 .nth(0);
437
438 if let Some(trait_) = future_trait {
439 let krate = self.resolver.krate();
440 if let Some(krate) = krate {
441 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
442 return implements_trait(&canonical_ty, db, &self.resolver, krate, trait_);
443 }
444 }
445
446 false
447 }
448
412 #[cfg(test)] 449 #[cfg(test)]
413 pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> { 450 pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> {
414 self.body_source_map.clone().unwrap() 451 self.body_source_map.clone().unwrap()