diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 57 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_dot.rs | 19 |
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". |
8 | use std::sync::Arc; | 8 | use std::sync::Arc; |
9 | 9 | ||
10 | use ra_db::{FileId, FilePosition}; | ||
11 | use ra_syntax::{ | ||
12 | algo::find_node_at_offset, | ||
13 | ast::{self, AstNode, NameOwner}, | ||
14 | AstPtr, | ||
15 | SyntaxKind::*, | ||
16 | SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, | ||
17 | }; | ||
18 | use rustc_hash::{FxHashMap, FxHashSet}; | ||
19 | |||
20 | use crate::{ | 10 | use 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 | }; | ||
24 | use ra_db::{FileId, FilePosition}; | ||
25 | use ra_syntax::{ | ||
26 | algo::find_node_at_offset, | ||
27 | ast::{self, AstNode, NameOwner}, | ||
28 | AstPtr, | ||
29 | SyntaxKind::*, | ||
30 | SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, | ||
31 | }; | 31 | }; |
32 | use 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. |
34 | pub fn module_from_file_id(db: &impl HirDatabase, file_id: FileId) -> Option<Module> { | 35 | pub 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 | ⋮ }, |