mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 05:45:12 +00:00
Implement completion for the .await syntax
This commit is contained in:
parent
831d39b0f7
commit
c417b98f02
3 changed files with 122 additions and 11 deletions
|
@ -23,6 +23,7 @@ use crate::{
|
|||
scope::{ExprScopes, ScopeId},
|
||||
BodySourceMap,
|
||||
},
|
||||
ty::method_resolution::implements_trait,
|
||||
ids::LocationCtx,
|
||||
AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
|
||||
MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty,
|
||||
|
@ -409,6 +410,42 @@ impl SourceAnalyzer {
|
|||
crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
|
||||
}
|
||||
|
||||
/// Checks that particular type `ty` implements `std::future::Future` trait.
|
||||
/// This function is used in `.await` syntax completion.
|
||||
pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
|
||||
// Search for std::future::Future trait in scope
|
||||
let future_trait = self.resolver.traits_in_scope(db)
|
||||
.into_iter()
|
||||
.filter(|t| {
|
||||
let std = t.module(db).parent(db)
|
||||
.and_then(|m| m
|
||||
.name(db)
|
||||
.and_then(|n| Some(n.to_string() == "std")))
|
||||
.unwrap_or(false);
|
||||
|
||||
let future = t.module(db).name(db)
|
||||
.and_then(|n| Some(n.to_string() == "future"))
|
||||
.unwrap_or(false);
|
||||
|
||||
let future_trait = t.name(db)
|
||||
.and_then(|n| Some(n.to_string() == "Future"))
|
||||
.unwrap_or(false);
|
||||
|
||||
std && future && future_trait
|
||||
})
|
||||
.nth(0);
|
||||
|
||||
if let Some(trait_) = future_trait {
|
||||
let krate = self.resolver.krate();
|
||||
if let Some(krate) = krate {
|
||||
let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
|
||||
return implements_trait(&canonical_ty, db, &self.resolver, krate, trait_);
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn body_source_map(&self) -> Arc<BodySourceMap> {
|
||||
self.body_source_map.clone().unwrap()
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
|||
resolve::Resolver,
|
||||
traits::TraitItem,
|
||||
ty::primitive::{FloatBitness, UncertainFloatTy, UncertainIntTy},
|
||||
ty::{Ty, TypeCtor},
|
||||
ty::{Ty, TypeCtor, traits::Solution},
|
||||
Crate, Function, HirDatabase, Module, Name, Trait,
|
||||
};
|
||||
|
||||
|
@ -255,6 +255,20 @@ fn iterate_inherent_methods<T>(
|
|||
None
|
||||
}
|
||||
|
||||
pub(crate) fn implements_trait(ty: &Canonical<Ty>, db: &impl HirDatabase, resolver: &Resolver, krate: Crate, trait_: Trait) -> bool {
|
||||
let env = lower::trait_env(db, resolver);
|
||||
let goal = generic_implements_goal(db, env.clone(), trait_, ty.clone());
|
||||
let solution = db.trait_solve(krate, goal);
|
||||
|
||||
if let Some(solution) = solution {
|
||||
if let Solution::Unique(_) = solution {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
impl Ty {
|
||||
// This would be nicer if it just returned an iterator, but that runs into
|
||||
// lifetime problems, because we need to borrow temp `CrateImplBlocks`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue