about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/semantics.rs7
-rw-r--r--crates/hir/src/source_analyzer.rs99
-rw-r--r--crates/ide-db/src/defs.rs39
-rw-r--r--crates/ide/src/goto_definition.rs7
4 files changed, 50 insertions, 102 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 2574adb35a5..aa10b0f878f 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -348,9 +348,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.resolve_method_call(call).map(Function::from)
     }
 
-    pub fn resolve_impl_method(&self, call: &ast::Expr) -> Option<Function> {
-        self.imp.resolve_impl_method(call).map(Function::from)
-    }
     pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
         self.imp.resolve_method_call_as_callable(call)
     }
@@ -981,10 +978,6 @@ impl<'db> SemanticsImpl<'db> {
         self.analyze(call.syntax())?.resolve_method_call(self.db, call).map(|(id, _)| id)
     }
 
-    fn resolve_impl_method(&self, call: &ast::Expr) -> Option<FunctionId> {
-        self.analyze(call.syntax())?.resolve_impl_method(self.db, call)
-    }
-
     fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
         let source_analyzer = self.analyze(call.syntax())?;
         let (func, subst) = source_analyzer.resolve_method_call(self.db, call)?;
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 62bcc9de39f..3faae8fc4b8 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -21,8 +21,8 @@ use hir_def::{
     path::{ModPath, Path, PathKind},
     resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
     type_ref::Mutability,
-    AsMacroCall, DefWithBodyId, FieldId, FunctionId, ItemContainerId, LocalFieldId, Lookup,
-    ModuleDefId, VariantId,
+    AsMacroCall, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, LocalFieldId,
+    Lookup, ModuleDefId, VariantId,
 };
 use hir_expand::{
     builtin_fn_macro::BuiltinFnLikeExpander, hygiene::Hygiene, name::AsName, HirFileId, InFile,
@@ -245,55 +245,9 @@ impl SourceAnalyzer {
         call: &ast::MethodCallExpr,
     ) -> Option<(FunctionId, Substitution)> {
         let expr_id = self.expr_id(db, &call.clone().into())?;
-        self.infer.as_ref()?.method_resolution(expr_id)
-    }
-
-    pub(crate) fn resolve_impl_method(
-        &self,
-        db: &dyn HirDatabase,
-        call: &ast::Expr,
-    ) -> Option<FunctionId> {
-        let infered = self.infer.as_ref()?;
-        let expr_id = self.expr_id(db, call)?;
-
-        let mut fun_info = None;
-        match call {
-            &ast::Expr::MethodCallExpr(..) => {
-                let (func, subs) = infered.method_resolution(expr_id)?;
-                if subs.is_empty(Interner) {
-                    return None;
-                }
-                fun_info.replace((func, subs.at(Interner, 0).ty(Interner)?.clone()));
-            }
-            &ast::Expr::PathExpr(..) => {
-                let func_ty = infered.type_of_expr.get(expr_id)?;
-                if let TyKind::FnDef(fn_def, subs) = func_ty.kind(Interner) {
-                    if subs.is_empty(Interner) {
-                        return None;
-                    }
-                    if let hir_ty::CallableDefId::FunctionId(f_id) =
-                        db.lookup_intern_callable_def(fn_def.clone().into())
-                    {
-                        fun_info.replace((f_id, subs.at(Interner, 0).ty(Interner)?.clone()));
-                    }
-                }
-            }
-            _ => (),
-        };
-        let (func, self_ty) = fun_info?;
-        let impled_trait = match func.lookup(db.upcast()).container {
-            ItemContainerId::TraitId(trait_id) => trait_id,
-            _ => return None,
-        };
-
-        let krate = self.resolver.krate();
-        let trait_env = self.resolver.body_owner()?.as_generic_def_id().map_or_else(
-            || Arc::new(hir_ty::TraitEnvironment::empty(krate)),
-            |d| db.trait_environment(d),
-        );
-
-        let fun_data = db.function_data(func);
-        method_resolution::lookup_impl_method(&self_ty, db, trait_env, impled_trait, &fun_data.name)
+        let (f_in_trait, substs) = self.infer.as_ref()?.method_resolution(expr_id)?;
+        let f_in_impl = self.resolve_impl_method(db, f_in_trait, &substs);
+        Some((f_in_impl.unwrap_or(f_in_trait), substs))
     }
 
     pub(crate) fn resolve_field(
@@ -391,6 +345,25 @@ impl SourceAnalyzer {
                 let expr_id = self.expr_id(db, &path_expr.into())?;
                 let infer = self.infer.as_ref()?;
                 if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
+                    let assoc = match assoc {
+                        AssocItemId::FunctionId(f_in_trait) => {
+                            match infer.type_of_expr.get(expr_id) {
+                                None => assoc,
+                                Some(func_ty) => {
+                                    if let TyKind::FnDef(_fn_def, subs) = func_ty.kind(Interner) {
+                                        self.resolve_impl_method(db, f_in_trait, subs)
+                                            .map(AssocItemId::FunctionId)
+                                            .unwrap_or(assoc)
+                                    } else {
+                                        assoc
+                                    }
+                                }
+                            }
+                        }
+
+                        _ => assoc,
+                    };
+
                     return Some(PathResolution::Def(AssocItem::from(assoc).into()));
                 }
                 if let Some(VariantId::EnumVariantId(variant)) =
@@ -616,6 +589,30 @@ impl SourceAnalyzer {
         }
         false
     }
+
+    fn resolve_impl_method(
+        &self,
+        db: &dyn HirDatabase,
+        func: FunctionId,
+        substs: &Substitution,
+    ) -> Option<FunctionId> {
+        let impled_trait = match func.lookup(db.upcast()).container {
+            ItemContainerId::TraitId(trait_id) => trait_id,
+            _ => return None,
+        };
+        if substs.is_empty(Interner) {
+            return None;
+        }
+        let self_ty = substs.at(Interner, 0).ty(Interner)?;
+        let krate = self.resolver.krate();
+        let trait_env = self.resolver.body_owner()?.as_generic_def_id().map_or_else(
+            || Arc::new(hir_ty::TraitEnvironment::empty(krate)),
+            |d| db.trait_environment(d),
+        );
+
+        let fun_data = db.function_data(func);
+        method_resolution::lookup_impl_method(self_ty, db, trait_env, impled_trait, &fun_data.name)
+    }
 }
 
 fn scope_for(
diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs
index 2b1e8e325e4..540cc70dd52 100644
--- a/crates/ide-db/src/defs.rs
+++ b/crates/ide-db/src/defs.rs
@@ -162,22 +162,6 @@ impl IdentClass {
             .or_else(|| NameClass::classify_lifetime(sema, lifetime).map(IdentClass::NameClass))
     }
 
-    pub fn classify_token_to_impl(
-        sema: &Semantics<RootDatabase>,
-        token: &SyntaxToken,
-    ) -> Option<Definition> {
-        let p = token.parent()?;
-        match_ast! {
-            match p {
-                ast::NameRef(name_ref) => match NameRefClass::classify_to_impl(sema, name_ref)? {
-                    NameRefClass::Definition(d) => Some(d),
-                    _ => None,
-                },
-                _ => None,
-            }
-        }
-    }
-
     pub fn definitions(self) -> ArrayVec<Definition, 2> {
         let mut res = ArrayVec::new();
         match self {
@@ -433,29 +417,6 @@ impl NameRefClass {
         }
     }
 
-    fn classify_to_impl(
-        sema: &Semantics<RootDatabase>,
-        name_ref: ast::NameRef,
-    ) -> Option<NameRefClass> {
-        let parent = name_ref.syntax().parent()?;
-        let expr = match_ast! {
-            match parent {
-                ast::MethodCallExpr(method_call) => {
-                    Some(ast::Expr::MethodCallExpr(method_call))
-                },
-                ast::PathSegment(..) => {
-                    parent.ancestors()
-                    .find_map(ast::PathExpr::cast)
-                    .map(ast::Expr::PathExpr)
-                },
-                _=> None
-            }
-        };
-        expr.as_ref()
-            .and_then(|e| sema.resolve_impl_method(e))
-            .map(Definition::Function)
-            .map(NameRefClass::Definition)
-    }
     pub fn classify_lifetime(
         sema: &Semantics<RootDatabase>,
         lifetime: &ast::Lifetime,
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index c3afe14fa3d..e44b5020c37 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -65,7 +65,7 @@ pub(crate) fn goto_definition(
                     .definitions()
                     .into_iter()
                     .flat_map(|def| {
-                        try_filter_trait_item_definition(sema, &def, &token)
+                        try_filter_trait_item_definition(sema, &def)
                             .unwrap_or_else(|| def_to_nav(sema.db, def))
                     })
                     .collect(),
@@ -114,14 +114,11 @@ fn try_lookup_include_path(
 fn try_filter_trait_item_definition(
     sema: &Semantics<RootDatabase>,
     def: &Definition,
-    token: &SyntaxToken,
 ) -> Option<Vec<NavigationTarget>> {
     let db = sema.db;
     let assoc = def.as_assoc_item(db)?;
     match assoc {
-        AssocItem::Function(..) => {
-            IdentClass::classify_token_to_impl(sema, &token).map(|def| def_to_nav(db, def))
-        }
+        AssocItem::Function(..) => None,
         AssocItem::Const(..) | AssocItem::TypeAlias(..) => {
             let imp = match assoc.container(db) {
                 hir::AssocItemContainer::Impl(imp) => imp,