aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorEvgenii P <[email protected]>2019-08-02 19:15:43 +0100
committerEvgenii P <[email protected]>2019-08-02 19:15:43 +0100
commitc417b98f02004a10819111903882482b39e50d17 (patch)
tree4ab6cce4d3b2c6dc5342cfa6ecfd04f281d8660b /crates/ra_hir/src
parent831d39b0f7ed0041cbc2fb8beb4cb375ab9652b1 (diff)
Implement completion for the .await syntax
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/source_binder.rs37
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs16
2 files changed, 52 insertions, 1 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()
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index d421bf9ef..2e2f88138 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -15,7 +15,7 @@ use crate::{
15 resolve::Resolver, 15 resolve::Resolver,
16 traits::TraitItem, 16 traits::TraitItem,
17 ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy}, 17 ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy},
18 ty::{Ty, TypeCtor}, 18 ty::{Ty, TypeCtor, traits::Solution},
19 Crate, Function, HirDatabase, Module, Name, Trait, 19 Crate, Function, HirDatabase, Module, Name, Trait,
20}; 20};
21 21
@@ -255,6 +255,20 @@ fn iterate_inherent_methods<T>(
255 None 255 None
256} 256}
257 257
258pub(crate) fn implements_trait(ty: &Canonical<Ty>, db: &impl HirDatabase, resolver: &Resolver, krate: Crate, trait_: Trait) -> bool {
259 let env = lower::trait_env(db, resolver);
260 let goal = generic_implements_goal(db, env.clone(), trait_, ty.clone());
261 let solution = db.trait_solve(krate, goal);
262
263 if let Some(solution) = solution {
264 if let Solution::Unique(_) = solution {
265 return true
266 }
267 }
268
269 false
270}
271
258impl Ty { 272impl Ty {
259 // This would be nicer if it just returned an iterator, but that runs into 273 // This would be nicer if it just returned an iterator, but that runs into
260 // lifetime problems, because we need to borrow temp `CrateImplBlocks`. 274 // lifetime problems, because we need to borrow temp `CrateImplBlocks`.