Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/source_analyzer.rs')
-rw-r--r--crates/hir/src/source_analyzer.rs42
1 files changed, 30 insertions, 12 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 3b39e9fa91..133fa810d6 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -10,6 +10,7 @@ use std::{
sync::Arc,
};
+use either::Either;
use hir_def::{
body::{
self,
@@ -51,7 +52,7 @@ use syntax::{
use crate::{
db::HirDatabase, semantics::PathResolution, Adt, AssocItem, BindingMode, BuiltinAttr,
BuiltinType, Callable, Const, DeriveHelper, Field, Function, Local, Macro, ModuleDef, Static,
- Struct, ToolModule, Trait, Type, TypeAlias, Variant,
+ Struct, ToolModule, Trait, TraitAlias, Type, TypeAlias, Variant,
};
/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
@@ -266,6 +267,21 @@ impl SourceAnalyzer {
Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs))
}
+ pub(crate) fn resolve_method_call_fallback(
+ &self,
+ db: &dyn HirDatabase,
+ call: &ast::MethodCallExpr,
+ ) -> Option<Either<FunctionId, FieldId>> {
+ let expr_id = self.expr_id(db, &call.clone().into())?;
+ let inference_result = self.infer.as_ref()?;
+ match inference_result.method_resolution(expr_id) {
+ Some((f_in_trait, substs)) => {
+ Some(Either::Left(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs)))
+ }
+ None => inference_result.field_resolution(expr_id).map(Either::Right),
+ }
+ }
+
pub(crate) fn resolve_await_to_poll(
&self,
db: &dyn HirDatabase,
@@ -406,8 +422,8 @@ impl SourceAnalyzer {
// Shorthand syntax, resolve to the local
let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone()));
match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
- Some(ValueNs::LocalBinding(pat_id)) => {
- Some(Local { pat_id, parent: self.resolver.body_owner()? })
+ Some(ValueNs::LocalBinding(binding_id)) => {
+ Some(Local { binding_id, parent: self.resolver.body_owner()? })
}
_ => None,
}
@@ -791,7 +807,7 @@ impl SourceAnalyzer {
|| Arc::new(hir_ty::TraitEnvironment::empty(krate)),
|d| db.trait_environment(d),
);
- method_resolution::lookup_impl_method(db, env, func, substs)
+ method_resolution::lookup_impl_method(db, env, func, substs).0
}
fn resolve_impl_const_or_trait_def(
@@ -809,7 +825,7 @@ impl SourceAnalyzer {
|| Arc::new(hir_ty::TraitEnvironment::empty(krate)),
|d| db.trait_environment(d),
);
- method_resolution::lookup_impl_const(db, env, const_id, subs)
+ method_resolution::lookup_impl_const(db, env, const_id, subs).0
}
fn lang_trait_fn(
@@ -943,17 +959,17 @@ fn resolve_hir_path_(
res.map(|ty_ns| (ty_ns, path.segments().first()))
}
None => {
- let (ty, remaining) =
+ let (ty, remaining_idx) =
resolver.resolve_path_in_type_ns(db.upcast(), path.mod_path())?;
- match remaining {
- Some(remaining) if remaining > 1 => {
- if remaining + 1 == path.segments().len() {
+ match remaining_idx {
+ Some(remaining_idx) => {
+ if remaining_idx + 1 == path.segments().len() {
Some((ty, path.segments().last()))
} else {
None
}
}
- _ => Some((ty, path.segments().get(1))),
+ None => Some((ty, None)),
}
}
}?;
@@ -978,6 +994,7 @@ fn resolve_hir_path_(
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
+ TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
};
match unresolved {
Some(unresolved) => resolver
@@ -1001,8 +1018,8 @@ fn resolve_hir_path_(
let values = || {
resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| {
let res = match val {
- ValueNs::LocalBinding(pat_id) => {
- let var = Local { parent: body_owner?, pat_id };
+ ValueNs::LocalBinding(binding_id) => {
+ let var = Local { parent: body_owner?, binding_id };
PathResolution::Local(var)
}
ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()),
@@ -1065,6 +1082,7 @@ fn resolve_hir_path_qualifier(
TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
+ TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
})
.or_else(|| {
resolver