aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgenii P <[email protected]>2019-08-02 19:53:51 +0100
committerEvgenii P <[email protected]>2019-08-02 19:53:51 +0100
commitab7774545cb5e45064c907429417bdee8d89f4d4 (patch)
tree21642a3ffe5cf19191513609c0e09bdc90ca9777
parent30bc3b93bec06256350b66869f2885ee71c3bedd (diff)
Use future lang item instead of hardcoded std::future::Future
-rw-r--r--crates/ra_hir/src/source_binder.rs41
-rw-r--r--crates/ra_ide_api/src/completion/complete_dot.rs17
2 files changed, 21 insertions, 37 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 67cb19615..7720329e3 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -24,6 +24,7 @@ use crate::{
24 BodySourceMap, 24 BodySourceMap,
25 }, 25 },
26 ids::LocationCtx, 26 ids::LocationCtx,
27 lang_item::LangItemTarget,
27 ty::method_resolution::implements_trait, 28 ty::method_resolution::implements_trait,
28 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId, 29 AsName, AstId, Const, Crate, DefWithBody, Either, Enum, Function, HirDatabase, HirFileId,
29 MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty, 30 MacroDef, Module, Name, Path, PerNs, Resolver, Static, Struct, Trait, Ty,
@@ -410,40 +411,18 @@ impl SourceAnalyzer {
410 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value) 411 crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
411 } 412 }
412 413
413 /// Checks that particular type `ty` implements `std::future::Future` trait. 414 /// Checks that particular type `ty` implements `Future` trait (`future_trait` lang item).
414 /// This function is used in `.await` syntax completion. 415 /// This function is used in `.await` syntax completion.
415 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { 416 pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
416 // Search for std::future::Future trait in scope 417 let krate = self.resolver.krate();
417 let future_trait = self 418 if let Some(krate) = krate {
418 .resolver 419 let future_trait = match db.lang_item(krate, "future_trait".into()) {
419 .traits_in_scope(db) 420 Some(LangItemTarget::Trait(t)) => t,
420 .into_iter() 421 _ => return false,
421 .filter(|t| { 422 };
422 let std = t
423 .module(db)
424 .parent(db)
425 .and_then(|m| m.name(db).and_then(|n| Some(n.to_string() == "std")))
426 .unwrap_or(false);
427
428 let future = t
429 .module(db)
430 .name(db)
431 .and_then(|n| Some(n.to_string() == "future"))
432 .unwrap_or(false);
433
434 let future_trait =
435 t.name(db).and_then(|n| Some(n.to_string() == "Future")).unwrap_or(false);
436
437 std && future && future_trait
438 })
439 .nth(0);
440 423
441 if let Some(trait_) = future_trait { 424 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
442 let krate = self.resolver.krate(); 425 return implements_trait(&canonical_ty, db, &self.resolver, krate, future_trait);
443 if let Some(krate) = krate {
444 let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
445 return implements_trait(&canonical_ty, db, &self.resolver, krate, trait_);
446 }
447 } 426 }
448 427
449 false 428 false
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs
index 1dbbdb1bc..93e5d816d 100644
--- a/crates/ra_ide_api/src/completion/complete_dot.rs
+++ b/crates/ra_ide_api/src/completion/complete_dot.rs
@@ -37,7 +37,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
37 } 37 }
38 complete_methods(acc, ctx, receiver_ty.clone()); 38 complete_methods(acc, ctx, receiver_ty.clone());
39 39
40 // Suggest .await syntax for types that implement std::future::Future 40 // Suggest .await syntax for types that implement Future trait
41 if ctx.analyzer.impls_future(ctx.db, receiver_ty) { 41 if ctx.analyzer.impls_future(ctx.db, receiver_ty) {
42 postfix_reference(ctx, ".await", "expr.await", &format!("{}.await", receiver_text)) 42 postfix_reference(ctx, ".await", "expr.await", &format!("{}.await", receiver_text))
43 .add_to(acc); 43 .add_to(acc);
@@ -441,9 +441,14 @@ mod tests {
441 fn test_completion_await_impls_future() { 441 fn test_completion_await_impls_future() {
442 assert_debug_snapshot_matches!( 442 assert_debug_snapshot_matches!(
443 do_ref_completion( 443 do_ref_completion(
444 r" 444 r###"
445 // Mock Future trait from stdlib 445 // Mock Future trait from stdlib
446 pub mod std { pub mod future { pub trait Future {} } } 446 pub mod std {
447 pub mod future {
448 #[lang = "future_trait"]
449 pub trait Future {}
450 }
451 }
447 452
448 use std::future::*; 453 use std::future::*;
449 struct A {} 454 struct A {}
@@ -452,13 +457,13 @@ mod tests {
452 fn foo(a: A) { 457 fn foo(a: A) {
453 a.<|> 458 a.<|>
454 } 459 }
455 "), 460 "###),
456 @r###" 461 @r###"
457 ⋮[ 462 ⋮[
458 ⋮ CompletionItem { 463 ⋮ CompletionItem {
459 ⋮ label: ".await", 464 ⋮ label: ".await",
460 ⋮ source_range: [249; 249), 465 ⋮ source_range: [358; 358),
461 ⋮ delete: [247; 249), 466 ⋮ delete: [356; 358),
462 ⋮ insert: "a.await", 467 ⋮ insert: "a.await",
463 ⋮ detail: "expr.await", 468 ⋮ detail: "expr.await",
464 ⋮ }, 469 ⋮ },