]> git.lizzy.rs Git - rust.git/commitdiff
Complete trait assoc items
authorFlorian Diebold <flodiebold@gmail.com>
Thu, 31 Oct 2019 20:21:48 +0000 (21:21 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Fri, 1 Nov 2019 18:57:08 +0000 (19:57 +0100)
crates/ra_hir/src/lib.rs
crates/ra_hir/src/source_binder.rs
crates/ra_hir/src/ty/method_resolution.rs
crates/ra_ide_api/src/completion/complete_dot.rs
crates/ra_ide_api/src/completion/complete_path.rs

index 40f5562b406a82dd111dbd0790519d71bb9bb4f2..4cace432e32afc4f5032e442320a7669aab4937e 100644 (file)
@@ -76,7 +76,8 @@ fn from(it: $sv) -> $e {
     resolve::ScopeDef,
     source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
     ty::{
-        display::HirDisplay, ApplicationTy, CallableDef, Substs, TraitRef, Ty, TypeCtor, TypeWalk,
+        display::HirDisplay, method_resolution::LookupMode, ApplicationTy, CallableDef, Substs,
+        TraitRef, Ty, TypeCtor, TypeWalk,
     },
 };
 
index 0398806fd18db5b2cde1f54854e20835fb474c82..82e6eb852cd7119d43fca7a8971b5996ef1840ac 100644 (file)
@@ -27,7 +27,7 @@
     },
     ids::LocationCtx,
     resolve::{ScopeDef, TypeNs, ValueNs},
-    ty::method_resolution::implements_trait,
+    ty::method_resolution::{self, implements_trait},
     AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, HasBody, HirFileId,
     MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty,
 };
@@ -327,17 +327,19 @@ pub fn iterate_method_candidates<T>(
         db: &impl HirDatabase,
         ty: Ty,
         name: Option<&Name>,
+        mode: method_resolution::LookupMode,
         callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
     ) -> Option<T> {
         // There should be no inference vars in types passed here
         // FIXME check that?
+        // FIXME replace Unknown by bound vars here
         let canonical = crate::ty::Canonical { value: ty, num_vars: 0 };
-        crate::ty::method_resolution::iterate_method_candidates(
+        method_resolution::iterate_method_candidates(
             &canonical,
             db,
             &self.resolver,
             name,
-            crate::ty::method_resolution::LookupMode::MethodCall,
+            mode,
             callback,
         )
     }
index 43b485ec077e8e3254cd8ad10f18e872e94c6fb5..9caff422fd43c487aa39289fc8670ae33e299d7f 100644 (file)
@@ -176,7 +176,7 @@ pub(crate) fn lookup_method(
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub(crate) enum LookupMode {
+pub enum LookupMode {
     MethodCall,
     Path,
 }
index 7135f481d04d5b51198076aa8452dae4ac17ea65..fe32e7366ff98015736c2bd60f45276cdaf5b14a 100644 (file)
@@ -58,15 +58,21 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
 
 fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
     let mut seen_methods = FxHashSet::default();
-    ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, item| {
-        if let hir::AssocItem::Function(func) = item {
-            let data = func.data(ctx.db);
-            if data.has_self_param() && seen_methods.insert(data.name().clone()) {
-                acc.add_function(ctx, func);
+    ctx.analyzer.iterate_method_candidates(
+        ctx.db,
+        receiver,
+        None,
+        hir::LookupMode::MethodCall,
+        |_ty, item| {
+            if let hir::AssocItem::Function(func) = item {
+                let data = func.data(ctx.db);
+                if data.has_self_param() && seen_methods.insert(data.name().clone()) {
+                    acc.add_function(ctx, func);
+                }
             }
-        }
-        None::<()>
-    });
+            None::<()>
+        },
+    );
 }
 
 #[cfg(test)]
index b471787ebe153b46bce859c0f5168ed1e3ba4414..940858342a8e6befc1b64cea17e534824594e261 100644 (file)
@@ -50,9 +50,12 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
                 hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db),
                 _ => unreachable!(),
             };
-            let krate = ctx.module.map(|m| m.krate());
-            if let Some(krate) = krate {
-                ty.iterate_impl_items(ctx.db, krate, |item| {
+            ctx.analyzer.iterate_method_candidates(
+                ctx.db,
+                ty.clone(),
+                None,
+                hir::LookupMode::Path,
+                |_ty, item| {
                     match item {
                         hir::AssocItem::Function(func) => {
                             let data = func.data(ctx.db);
@@ -64,6 +67,18 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
                         hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
                     }
                     None::<()>
+                },
+            );
+            // Iterate assoc types separately
+            // FIXME: complete T::AssocType
+            let krate = ctx.module.map(|m| m.krate());
+            if let Some(krate) = krate {
+                ty.iterate_impl_items(ctx.db, krate, |item| {
+                    match item {
+                        hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {}
+                        hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
+                    }
+                    None::<()>
                 });
             }
         }
@@ -593,7 +608,22 @@ impl Trait for S {}
                 fn foo() { let _ = S::<|> }
                 "
             ),
-            @"[]"
+            @r###"
+        [
+            CompletionItem {
+                label: "m()",
+                source_range: [99; 99),
+                delete: [99; 99),
+                insert: "m()$0",
+                kind: Function,
+                lookup: "m",
+                detail: "fn m()",
+                documentation: Documentation(
+                    "A trait method",
+                ),
+            },
+        ]
+        "###
         );
     }