aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/source_binder.rs35
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs14
2 files changed, 47 insertions, 2 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index c2c6921cb..e86716d74 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -18,14 +18,18 @@ use ra_syntax::{
18use rustc_hash::{FxHashMap, FxHashSet}; 18use rustc_hash::{FxHashMap, FxHashSet};
19 19
20use crate::{ 20use crate::{
21 expr,
22 expr::{ 21 expr::{
22 self,
23 scope::{ExprScopes, ScopeId}, 23 scope::{ExprScopes, ScopeId},
24 BodySourceMap, 24 BodySourceMap,
25 }, 25 },
26 ids::LocationCtx, 26 ids::LocationCtx,
27 name,
28 path::{PathKind, PathSegment},
29 ty::method_resolution::implements_trait,
27 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId, 30 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
28 MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty, 31 MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, Struct, Trait,
32 Ty,
29}; 33};
30 34
31/// Locates the module by `FileId`. Picks topmost module in the file. 35/// Locates the module by `FileId`. Picks topmost module in the file.
@@ -409,6 +413,33 @@ impl SourceAnalyzer {
409 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 413 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
410 } 414 }
411 415
416 /// Checks that particular type `ty` implements `std::future::Future`.
417 /// This function is used in `.await` syntax completion.
418 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
419 let std_future_path = Path {
420 kind: PathKind::Abs,
421 segments: vec![
422 PathSegment { name: name::STD, args_and_bindings: None },
423 PathSegment { name: name::FUTURE_MOD, args_and_bindings: None },
424 PathSegment { name: name::FUTURE_TYPE, args_and_bindings: None },
425 ],
426 };
427
428 let std_future_trait =
429 match self.resolver.resolve_path_segments(db, &std_future_path).into_fully_resolved() {
430 PerNs { types: Some(Resolution::Def(ModuleDef::Trait(trait_))), .. } => trait_,
431 _ => return false,
432 };
433
434 let krate = match self.resolver.krate() {
435 Some(krate) => krate,
436 _ => return false,
437 };
438
439 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
440 implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait)
441 }
442
412 #[cfg(test)] 443 #[cfg(test)]
413 pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> { 444 pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> {
414 self.body_source_map.clone().unwrap() 445 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..88d012a74 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -255,6 +255,20 @@ fn iterate_inherent_methods<T>(
255 None 255 None
256} 256}
257 257
258pub(crate) fn implements_trait(
259 ty: &Canonical<Ty>,
260 db: &impl HirDatabase,
261 resolver: &Resolver,
262 krate: Crate,
263 trait_: Trait,
264) -> bool {
265 let env = lower::trait_env(db, resolver);
266 let goal = generic_implements_goal(db, env.clone(), trait_, ty.clone());
267 let solution = db.trait_solve(krate, goal);
268
269 solution.is_some()
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`.