]> git.lizzy.rs Git - rust.git/commitdiff
Use future lang item instead of hardcoded std::future::Future
authorEvgenii P <eupn@protonmail.com>
Fri, 2 Aug 2019 18:53:51 +0000 (01:53 +0700)
committerEvgenii P <eupn@protonmail.com>
Fri, 2 Aug 2019 18:53:51 +0000 (01:53 +0700)
crates/ra_hir/src/source_binder.rs
crates/ra_ide_api/src/completion/complete_dot.rs

index 67cb19615d1d9eba5c4a27a30692dc846f1f906f..7720329e33a81904da2461709e4463b80d3f43a4 100644 (file)
@@ -24,6 +24,7 @@
         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,
@@ -410,40 +411,18 @@ pub fn autoderef<'a>(
         crate::ty::autoderef(db, &self.resolver, canonical).map(|canonical| canonical.value)
     }
 
-    /// Checks that particular type `ty` implements `std::future::Future` trait.
+    /// Checks that particular type `ty` implements `Future` trait (`future_trait` lang item).
     /// This function is used in `.await` syntax completion.
     pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool {
-        // Search for std::future::Future trait in scope
-        let future_trait = self
-            .resolver
-            .traits_in_scope(db)
-            .into_iter()
-            .filter(|t| {
-                let std = t
-                    .module(db)
-                    .parent(db)
-                    .and_then(|m| m.name(db).and_then(|n| Some(n.to_string() == "std")))
-                    .unwrap_or(false);
-
-                let future = t
-                    .module(db)
-                    .name(db)
-                    .and_then(|n| Some(n.to_string() == "future"))
-                    .unwrap_or(false);
-
-                let future_trait =
-                    t.name(db).and_then(|n| Some(n.to_string() == "Future")).unwrap_or(false);
-
-                std && future && future_trait
-            })
-            .nth(0);
+        let krate = self.resolver.krate();
+        if let Some(krate) = krate {
+            let future_trait = match db.lang_item(krate, "future_trait".into()) {
+                Some(LangItemTarget::Trait(t)) => t,
+                _ => return false,
+            };
 
-        if let Some(trait_) = future_trait {
-            let krate = self.resolver.krate();
-            if let Some(krate) = krate {
-                let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
-                return implements_trait(&canonical_ty, db, &self.resolver, krate, trait_);
-            }
+            let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 };
+            return implements_trait(&canonical_ty, db, &self.resolver, krate, future_trait);
         }
 
         false
index 1dbbdb1bc132d38eef8bd60b345a144677585812..93e5d816d5c2e61b38c0889a489786b85d051a81 100644 (file)
@@ -37,7 +37,7 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) {
             }
             complete_methods(acc, ctx, receiver_ty.clone());
 
-            // Suggest .await syntax for types that implement std::future::Future
+            // Suggest .await syntax for types that implement Future trait
             if ctx.analyzer.impls_future(ctx.db, receiver_ty) {
                 postfix_reference(ctx, ".await", "expr.await", &format!("{}.await", receiver_text))
                     .add_to(acc);
@@ -441,9 +441,14 @@ struct A { the_field: u32 }
     fn test_completion_await_impls_future() {
         assert_debug_snapshot_matches!(
         do_ref_completion(
-            r"
+            r###"
             // Mock Future trait from stdlib
-            pub mod std { pub mod future { pub trait Future {} } }
+            pub mod std {
+                pub mod future {
+                    #[lang = "future_trait"]
+                    pub trait Future {}
+                }
+            }
 
             use std::future::*;
             struct A {}
@@ -452,13 +457,13 @@ impl Future for A {}
             fn foo(a: A) {
                 a.<|>
             }
-            "),
+            "###),
         @r###"
        ⋮[
        ⋮    CompletionItem {
        ⋮        label: ".await",
-       ⋮        source_range: [249; 249),
-       ⋮        delete: [247; 249),
+       ⋮        source_range: [358; 358),
+       ⋮        delete: [356; 358),
        ⋮        insert: "a.await",
        ⋮        detail: "expr.await",
        ⋮    },