Use std::future::Future trait from stdlib
This commit is contained in:
parent
957de26a1d
commit
6a94f203fc
@ -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
|
||||||
|
@ -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",
|
||||||
⋮ },
|
⋮ },
|
||||||
|
Loading…
Reference in New Issue
Block a user