Use std::future::Future trait from stdlib

This commit is contained in:
Evgenii P 2019-08-03 17:07:20 +07:00
parent 957de26a1d
commit 6a94f203fc
2 changed files with 44 additions and 32 deletions

View File

@ -7,6 +7,20 @@
/// purely for "IDE needs". /// purely for "IDE needs".
use std::sync::Arc; use std::sync::Arc;
use crate::{
expr::{
self,
scope::{ExprScopes, ScopeId},
BodySourceMap,
},
ids::LocationCtx,
name,
path::{PathKind, PathSegment},
ty::method_resolution::implements_trait,
AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, Struct, Trait,
Ty,
};
use ra_db::{FileId, FilePosition}; use ra_db::{FileId, FilePosition};
use ra_syntax::{ use ra_syntax::{
algo::find_node_at_offset, algo::find_node_at_offset,
@ -17,19 +31,6 @@
}; };
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use crate::{
expr,
expr::{
scope::{ExprScopes, ScopeId},
BodySourceMap,
},
ids::LocationCtx,
lang_item::LangItemTarget,
ty::method_resolution::implements_trait,
AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty,
};
/// Locates the module by `FileId`. Picks topmost module in the file. /// Locates the module by `FileId`. Picks topmost module in the file.
pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Option<Module> { pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Option<Module> {
module_from_source(db, file_id.into(), None) module_from_source(db, file_id.into(), None)
@ -411,18 +412,32 @@ pub fn autoderef<'a>(
crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
} }
/// Checks that particular type `ty` implements `Future` trait (`future_trait` lang item). /// Checks that particular type `ty` implements `std::future::Future`.
/// This function is used in `.await` syntax completion. /// This function is used in `.await` syntax completion.
pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
let krate = self.resolver.krate(); let std_future_path = Path {
if let Some(krate) = krate { kind: PathKind::Abs,
let future_trait = match db.lang_item(krate, "future_trait".into()) { segments: vec![
Some(LangItemTarget::Trait(t)) => t, PathSegment { name: name::STD, args_and_bindings: None },
_ => return false, PathSegment { name: name::FUTURE_MOD, args_and_bindings: None },
PathSegment { name: name::FUTURE_TYPE, args_and_bindings: None },
],
};
let std_future_trait =
match self.resolver.resolve_path_segments(db, &std_future_path).into_fully_resolved() {
PerNs { types: Some(Resolution::Def(ModuleDef::Trait(trait_))), .. } => {
Some(trait_)
}
_ => None,
}; };
let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; let krate = self.resolver.krate();
return implements_trait(&canonical_ty, db, &self.resolver, krate, future_trait); if let Some(krate) = krate {
if let Some(trait_) = std_future_trait {
let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
return implements_trait(&canonical_ty, db, &self.resolver, krate, trait_);
}
} }
false false

View File

@ -425,28 +425,25 @@ fn test_completion_await_impls_future() {
assert_debug_snapshot_matches!( assert_debug_snapshot_matches!(
do_completion( do_completion(
r###" r###"
// Mock Future trait from stdlib //- /main.rs
pub mod std {
pub mod future {
#[lang = "future_trait"]
pub trait Future {}
}
}
use std::future::*; use std::future::*;
struct A {} struct A {}
impl Future for A {} impl Future for A {}
fn foo(a: A) { fn foo(a: A) {
a.<|> a.<|>
} }
//- /std/lib.rs
pub mod future {
pub trait Future {}
}
"###, CompletionKind::Keyword), "###, CompletionKind::Keyword),
@r###" @r###"
[ [
CompletionItem { CompletionItem {
label: "await", label: "await",
source_range: [358; 358), source_range: [74; 74),
delete: [358; 358), delete: [74; 74),
insert: "await", insert: "await",
detail: "expr.await", detail: "expr.await",
}, },