aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/source_binder.rs57
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs19
2 files changed, 44 insertions, 32 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 7720329e3..6a9f228b8 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -7,28 +7,29 @@
7/// purely for "IDE needs". 7/// purely for "IDE needs".
8use std::sync::Arc; 8use std::sync::Arc;
9 9
10use ra_db::{FileId, FilePosition};
11use ra_syntax::{
12 algo::find_node_at_offset,
13 ast::{self, AstNode, NameOwner},
14 AstPtr,
15 SyntaxKind::*,
16 SyntaxNode, SyntaxNodePtr, TextRange, TextUnit,
17};
18use rustc_hash::{FxHashMap, FxHashSet};
19
20use crate::{ 10use crate::{
21 expr,
22 expr::{ 11 expr::{
12 self,
23 scope::{ExprScopes, ScopeId}, 13 scope::{ExprScopes, ScopeId},
24 BodySourceMap, 14 BodySourceMap,
25 }, 15 },
26 ids::LocationCtx, 16 ids::LocationCtx,
27 lang_item::LangItemTarget, 17 name,
18 path::{PathKind, PathSegment},
28 ty::method_resolution::implements_trait, 19 ty::method_resolution::implements_trait,
29 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId, 20 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
30 MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty, 21 MacroDef, Module, ModuleDef, Name, Path, PerNs, Resolution, Resolver, Static, Struct, Trait,
22 Ty,
23};
24use ra_db::{FileId, FilePosition};
25use ra_syntax::{
26 algo::find_node_at_offset,
27 ast::{self, AstNode, NameOwner},
28 AstPtr,
29 SyntaxKind::*,
30 SyntaxNode, SyntaxNodePtr, TextRange, TextUnit,
31}; 31};
32use rustc_hash::{FxHashMap, FxHashSet};
32 33
33/// Locates the module by `FileId`. Picks topmost module in the file. 34/// Locates the module by `FileId`. Picks topmost module in the file.
34pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Option<Module> { 35pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Option<Module> {
@@ -411,18 +412,32 @@ impl SourceAnalyzer {
411 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 412 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
412 } 413 }
413 414
414 /// Checks that particular type `ty` implements `Future` trait (`future_trait` lang item). 415 /// Checks that particular type `ty` implements `std::future::Future`.
415 /// This function is used in `.await` syntax completion. 416 /// This function is used in `.await` syntax completion.
416 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { 417 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
417 let krate = self.resolver.krate(); 418 let std_future_path = Path {
418 if let Some(krate) = krate { 419 kind: PathKind::Abs,
419 let future_trait = match db.lang_item(krate, "future_trait".into()) { 420 segments: vec![
420 Some(LangItemTarget::Trait(t)) => t, 421 PathSegment { name: name::STD, args_and_bindings: None },
421 _ => return false, 422 PathSegment { name: name::FUTURE_MOD, args_and_bindings: None },
423 PathSegment { name: name::FUTURE_TYPE, args_and_bindings: None },
424 ],
425 };
426
427 let std_future_trait =
428 match self.resolver.resolve_path_segments(db, &std_future_path).into_fully_resolved() {
429 PerNs { types: Some(Resolution::Def(ModuleDef::Trait(trait_))), .. } => {
430 Some(trait_)
431 }
432 _ => None,
422 }; 433 };
423 434
424 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; 435 let krate = self.resolver.krate();
425 return implements_trait(&canonical_ty, db, &self.resolver, krate, future_trait); 436 if let Some(krate) = krate {
437 if let Some(trait_) = std_future_trait {
438 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
439 return implements_trait(&canonical_ty, db, &self.resolver, krate, trait_);
440 }
426 } 441 }
427 442
428 false 443 false
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index e8fd37bca..9a3b353a9 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -425,28 +425,25 @@ mod tests {
425 assert_debug_snapshot_matches!( 425 assert_debug_snapshot_matches!(
426 do_completion( 426 do_completion(
427 r###" 427 r###"
428 // Mock Future trait from stdlib 428 //- /main.rs
429 pub mod std {
430 pub mod future {
431 #[lang = "future_trait"]
432 pub trait Future {}
433 }
434 }
435
436 use std::future::*; 429 use std::future::*;
437 struct A {} 430 struct A {}
438 impl Future for A {} 431 impl Future for A {}
439
440 fn foo(a: A) { 432 fn foo(a: A) {
441 a.<|> 433 a.<|>
442 } 434 }
435
436 //- /std/lib.rs
437 pub mod future {
438 pub trait Future {}
439 }
443 "###, CompletionKind::Keyword), 440 "###, CompletionKind::Keyword),
444 @r###" 441 @r###"
445 ⋮[ 442 ⋮[
446 ⋮ CompletionItem { 443 ⋮ CompletionItem {
447 ⋮ label: "await", 444 ⋮ label: "await",
448 ⋮ source_range: [358; 358), 445 ⋮ source_range: [74; 74),
449 ⋮ delete: [358; 358), 446 ⋮ delete: [74; 74),
450 ⋮ insert: "await", 447 ⋮ insert: "await",
451 ⋮ detail: "expr.await", 448 ⋮ detail: "expr.await",
452 ⋮ }, 449 ⋮ },