Skip to content

Commit 6ecabe3

Browse files
committed
functions resolve to impl
1 parent 36fadc4 commit 6ecabe3

File tree

4 files changed

+50
-102
lines changed

4 files changed

+50
-102
lines changed

crates/hir/src/semantics.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
348348
self.imp.resolve_method_call(call).map(Function::from)
349349
}
350350

351-
pub fn resolve_impl_method(&self, call: &ast::Expr) -> Option<Function> {
352-
self.imp.resolve_impl_method(call).map(Function::from)
353-
}
354351
pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
355352
self.imp.resolve_method_call_as_callable(call)
356353
}
@@ -981,10 +978,6 @@ impl<'db> SemanticsImpl<'db> {
981978
self.analyze(call.syntax())?.resolve_method_call(self.db, call).map(|(id, _)| id)
982979
}
983980

984-
fn resolve_impl_method(&self, call: &ast::Expr) -> Option<FunctionId> {
985-
self.analyze(call.syntax())?.resolve_impl_method(self.db, call)
986-
}
987-
988981
fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
989982
let source_analyzer = self.analyze(call.syntax())?;
990983
let (func, subst) = source_analyzer.resolve_method_call(self.db, call)?;

crates/hir/src/source_analyzer.rs

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use hir_def::{
2121
path::{ModPath, Path, PathKind},
2222
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
2323
type_ref::Mutability,
24-
AsMacroCall, DefWithBodyId, FieldId, FunctionId, ItemContainerId, LocalFieldId, Lookup,
25-
ModuleDefId, VariantId,
24+
AsMacroCall, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, LocalFieldId,
25+
Lookup, ModuleDefId, VariantId,
2626
};
2727
use hir_expand::{
2828
builtin_fn_macro::BuiltinFnLikeExpander, hygiene::Hygiene, name::AsName, HirFileId, InFile,
@@ -245,55 +245,9 @@ impl SourceAnalyzer {
245245
call: &ast::MethodCallExpr,
246246
) -> Option<(FunctionId, Substitution)> {
247247
let expr_id = self.expr_id(db, &call.clone().into())?;
248-
self.infer.as_ref()?.method_resolution(expr_id)
249-
}
250-
251-
pub(crate) fn resolve_impl_method(
252-
&self,
253-
db: &dyn HirDatabase,
254-
call: &ast::Expr,
255-
) -> Option<FunctionId> {
256-
let infered = self.infer.as_ref()?;
257-
let expr_id = self.expr_id(db, call)?;
258-
259-
let mut fun_info = None;
260-
match call {
261-
&ast::Expr::MethodCallExpr(..) => {
262-
let (func, subs) = infered.method_resolution(expr_id)?;
263-
if subs.is_empty(Interner) {
264-
return None;
265-
}
266-
fun_info.replace((func, subs.at(Interner, 0).ty(Interner)?.clone()));
267-
}
268-
&ast::Expr::PathExpr(..) => {
269-
let func_ty = infered.type_of_expr.get(expr_id)?;
270-
if let TyKind::FnDef(fn_def, subs) = func_ty.kind(Interner) {
271-
if subs.is_empty(Interner) {
272-
return None;
273-
}
274-
if let hir_ty::CallableDefId::FunctionId(f_id) =
275-
db.lookup_intern_callable_def(fn_def.clone().into())
276-
{
277-
fun_info.replace((f_id, subs.at(Interner, 0).ty(Interner)?.clone()));
278-
}
279-
}
280-
}
281-
_ => (),
282-
};
283-
let (func, self_ty) = fun_info?;
284-
let impled_trait = match func.lookup(db.upcast()).container {
285-
ItemContainerId::TraitId(trait_id) => trait_id,
286-
_ => return None,
287-
};
288-
289-
let krate = self.resolver.krate();
290-
let trait_env = self.resolver.body_owner()?.as_generic_def_id().map_or_else(
291-
|| Arc::new(hir_ty::TraitEnvironment::empty(krate)),
292-
|d| db.trait_environment(d),
293-
);
294-
295-
let fun_data = db.function_data(func);
296-
method_resolution::lookup_impl_method(&self_ty, db, trait_env, impled_trait, &fun_data.name)
248+
let (f_in_trait, substs) = self.infer.as_ref()?.method_resolution(expr_id)?;
249+
let f_in_impl = self.resolve_impl_method(db, f_in_trait, &substs);
250+
Some((f_in_impl.unwrap_or(f_in_trait), substs))
297251
}
298252

299253
pub(crate) fn resolve_field(
@@ -391,6 +345,25 @@ impl SourceAnalyzer {
391345
let expr_id = self.expr_id(db, &path_expr.into())?;
392346
let infer = self.infer.as_ref()?;
393347
if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
348+
let assoc = match assoc {
349+
AssocItemId::FunctionId(f_in_trait) => {
350+
match infer.type_of_expr.get(expr_id) {
351+
None => assoc,
352+
Some(func_ty) => {
353+
if let TyKind::FnDef(_fn_def, subs) = func_ty.kind(Interner) {
354+
self.resolve_impl_method(db, f_in_trait, subs)
355+
.map(AssocItemId::FunctionId)
356+
.unwrap_or(assoc)
357+
} else {
358+
assoc
359+
}
360+
}
361+
}
362+
}
363+
364+
_ => assoc,
365+
};
366+
394367
return Some(PathResolution::Def(AssocItem::from(assoc).into()));
395368
}
396369
if let Some(VariantId::EnumVariantId(variant)) =
@@ -616,6 +589,30 @@ impl SourceAnalyzer {
616589
}
617590
false
618591
}
592+
593+
fn resolve_impl_method(
594+
&self,
595+
db: &dyn HirDatabase,
596+
func: FunctionId,
597+
substs: &Substitution,
598+
) -> Option<FunctionId> {
599+
let impled_trait = match func.lookup(db.upcast()).container {
600+
ItemContainerId::TraitId(trait_id) => trait_id,
601+
_ => return None,
602+
};
603+
if substs.is_empty(Interner) {
604+
return None;
605+
}
606+
let self_ty = substs.at(Interner, 0).ty(Interner)?;
607+
let krate = self.resolver.krate();
608+
let trait_env = self.resolver.body_owner()?.as_generic_def_id().map_or_else(
609+
|| Arc::new(hir_ty::TraitEnvironment::empty(krate)),
610+
|d| db.trait_environment(d),
611+
);
612+
613+
let fun_data = db.function_data(func);
614+
method_resolution::lookup_impl_method(self_ty, db, trait_env, impled_trait, &fun_data.name)
615+
}
619616
}
620617

621618
fn scope_for(

crates/ide-db/src/defs.rs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -162,22 +162,6 @@ impl IdentClass {
162162
.or_else(|| NameClass::classify_lifetime(sema, lifetime).map(IdentClass::NameClass))
163163
}
164164

165-
pub fn classify_token_to_impl(
166-
sema: &Semantics<RootDatabase>,
167-
token: &SyntaxToken,
168-
) -> Option<Definition> {
169-
let p = token.parent()?;
170-
match_ast! {
171-
match p {
172-
ast::NameRef(name_ref) => match NameRefClass::classify_to_impl(sema, name_ref)? {
173-
NameRefClass::Definition(d) => Some(d),
174-
_ => None,
175-
},
176-
_ => None,
177-
}
178-
}
179-
}
180-
181165
pub fn definitions(self) -> ArrayVec<Definition, 2> {
182166
let mut res = ArrayVec::new();
183167
match self {
@@ -433,29 +417,6 @@ impl NameRefClass {
433417
}
434418
}
435419

436-
fn classify_to_impl(
437-
sema: &Semantics<RootDatabase>,
438-
name_ref: ast::NameRef,
439-
) -> Option<NameRefClass> {
440-
let parent = name_ref.syntax().parent()?;
441-
let expr = match_ast! {
442-
match parent {
443-
ast::MethodCallExpr(method_call) => {
444-
Some(ast::Expr::MethodCallExpr(method_call))
445-
},
446-
ast::PathSegment(..) => {
447-
parent.ancestors()
448-
.find_map(ast::PathExpr::cast)
449-
.map(ast::Expr::PathExpr)
450-
},
451-
_=> None
452-
}
453-
};
454-
expr.as_ref()
455-
.and_then(|e| sema.resolve_impl_method(e))
456-
.map(Definition::Function)
457-
.map(NameRefClass::Definition)
458-
}
459420
pub fn classify_lifetime(
460421
sema: &Semantics<RootDatabase>,
461422
lifetime: &ast::Lifetime,

crates/ide/src/goto_definition.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub(crate) fn goto_definition(
6565
.definitions()
6666
.into_iter()
6767
.flat_map(|def| {
68-
try_filter_trait_item_definition(sema, &def, &token)
68+
try_filter_trait_item_definition(sema, &def)
6969
.unwrap_or_else(|| def_to_nav(sema.db, def))
7070
})
7171
.collect(),
@@ -114,14 +114,11 @@ fn try_lookup_include_path(
114114
fn try_filter_trait_item_definition(
115115
sema: &Semantics<RootDatabase>,
116116
def: &Definition,
117-
token: &SyntaxToken,
118117
) -> Option<Vec<NavigationTarget>> {
119118
let db = sema.db;
120119
let assoc = def.as_assoc_item(db)?;
121120
match assoc {
122-
AssocItem::Function(..) => {
123-
IdentClass::classify_token_to_impl(sema, &token).map(|def| def_to_nav(db, def))
124-
}
121+
AssocItem::Function(..) => None,
125122
AssocItem::Const(..) | AssocItem::TypeAlias(..) => {
126123
let imp = match assoc.container(db) {
127124
hir::AssocItemContainer::Impl(imp) => imp,

0 commit comments

Comments
 (0)