Push resolver further up
This commit is contained in:
parent
7ec62ea5e6
commit
21c5fd8b1b
@ -358,10 +358,17 @@ impl SourceAnalyzer {
|
|||||||
// FIXME check that?
|
// FIXME check that?
|
||||||
// FIXME replace Unknown by bound vars here
|
// FIXME replace Unknown by bound vars here
|
||||||
let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
|
let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
|
||||||
|
|
||||||
|
let env = TraitEnvironment::lower(db, &self.resolver);
|
||||||
|
let krate = self.resolver.krate()?;
|
||||||
|
let traits_in_scope = self.resolver.traits_in_scope(db);
|
||||||
|
|
||||||
method_resolution::iterate_method_candidates(
|
method_resolution::iterate_method_candidates(
|
||||||
&canonical,
|
&canonical,
|
||||||
db,
|
db,
|
||||||
&self.resolver,
|
env,
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
method_resolution::LookupMode::MethodCall,
|
method_resolution::LookupMode::MethodCall,
|
||||||
|ty, it| match it {
|
|ty, it| match it {
|
||||||
@ -382,10 +389,17 @@ impl SourceAnalyzer {
|
|||||||
// FIXME check that?
|
// FIXME check that?
|
||||||
// FIXME replace Unknown by bound vars here
|
// FIXME replace Unknown by bound vars here
|
||||||
let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
|
let canonical = Canonical { value: ty.ty.value.clone(), num_vars: 0 };
|
||||||
|
|
||||||
|
let env = TraitEnvironment::lower(db, &self.resolver);
|
||||||
|
let krate = self.resolver.krate()?;
|
||||||
|
let traits_in_scope = self.resolver.traits_in_scope(db);
|
||||||
|
|
||||||
method_resolution::iterate_method_candidates(
|
method_resolution::iterate_method_candidates(
|
||||||
&canonical,
|
&canonical,
|
||||||
db,
|
db,
|
||||||
&self.resolver,
|
env,
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
name,
|
name,
|
||||||
method_resolution::LookupMode::Path,
|
method_resolution::LookupMode::Path,
|
||||||
|ty, it| callback(ty, it.into()),
|
|ty, it| callback(ty, it.into()),
|
||||||
|
@ -569,12 +569,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||||||
) -> Ty {
|
) -> Ty {
|
||||||
let receiver_ty = self.infer_expr(receiver, &Expectation::none());
|
let receiver_ty = self.infer_expr(receiver, &Expectation::none());
|
||||||
let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone());
|
let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone());
|
||||||
let resolved = method_resolution::lookup_method(
|
|
||||||
&canonicalized_receiver.value,
|
let traits_in_scope = self.resolver.traits_in_scope(self.db);
|
||||||
self.db,
|
|
||||||
method_name,
|
let resolved = self.resolver.krate().and_then(|krate| {
|
||||||
&self.resolver,
|
method_resolution::lookup_method(
|
||||||
);
|
&canonicalized_receiver.value,
|
||||||
|
self.db,
|
||||||
|
self.trait_env.clone(),
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
|
method_name,
|
||||||
|
)
|
||||||
|
});
|
||||||
let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
|
let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
|
||||||
Some((ty, func)) => {
|
Some((ty, func)) => {
|
||||||
let ty = canonicalized_receiver.decanonicalize_ty(ty);
|
let ty = canonicalized_receiver.decanonicalize_ty(ty);
|
||||||
|
@ -11,7 +11,7 @@ use hir_expand::name::Name;
|
|||||||
|
|
||||||
use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId};
|
use crate::{db::HirDatabase, method_resolution, Substs, Ty, TypeWalk, ValueTyDefId};
|
||||||
|
|
||||||
use super::{ExprOrPatId, InferenceContext, TraitRef};
|
use super::{ExprOrPatId, InferenceContext, TraitEnvironment, TraitRef};
|
||||||
|
|
||||||
impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
pub(super) fn infer_path(
|
pub(super) fn infer_path(
|
||||||
@ -193,11 +193,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone());
|
let canonical_ty = self.canonicalizer().canonicalize_ty(ty.clone());
|
||||||
|
let env = TraitEnvironment::lower(self.db, &self.resolver);
|
||||||
|
let krate = self.resolver.krate()?;
|
||||||
|
let traits_in_scope = self.resolver.traits_in_scope(self.db);
|
||||||
|
|
||||||
method_resolution::iterate_method_candidates(
|
method_resolution::iterate_method_candidates(
|
||||||
&canonical_ty.value,
|
&canonical_ty.value,
|
||||||
self.db,
|
self.db,
|
||||||
&self.resolver.clone(),
|
env,
|
||||||
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
Some(name),
|
Some(name),
|
||||||
method_resolution::LookupMode::Path,
|
method_resolution::LookupMode::Path,
|
||||||
move |_ty, item| {
|
move |_ty, item| {
|
||||||
|
@ -6,8 +6,8 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
lang_item::LangItemTarget, resolver::Resolver, type_ref::Mutability, AssocContainerId,
|
lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId,
|
||||||
AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId,
|
HasModule, ImplId, Lookup, TraitId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use ra_db::CrateId;
|
use ra_db::CrateId;
|
||||||
@ -144,14 +144,24 @@ impl Ty {
|
|||||||
pub(crate) fn lookup_method(
|
pub(crate) fn lookup_method(
|
||||||
ty: &Canonical<Ty>,
|
ty: &Canonical<Ty>,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
|
env: Arc<TraitEnvironment>,
|
||||||
|
krate: CrateId,
|
||||||
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: &Name,
|
name: &Name,
|
||||||
resolver: &Resolver,
|
|
||||||
) -> Option<(Ty, FunctionId)> {
|
) -> Option<(Ty, FunctionId)> {
|
||||||
iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f
|
iterate_method_candidates(
|
||||||
{
|
ty,
|
||||||
AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
|
db,
|
||||||
_ => None,
|
env,
|
||||||
})
|
krate,
|
||||||
|
&traits_in_scope,
|
||||||
|
Some(name),
|
||||||
|
LookupMode::MethodCall,
|
||||||
|
|ty, f| match f {
|
||||||
|
AssocItemId::FunctionId(f) => Some((ty.clone(), f)),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether we're looking up a dotted method call (like `v.len()`) or a path
|
/// Whether we're looking up a dotted method call (like `v.len()`) or a path
|
||||||
@ -172,14 +182,13 @@ pub enum LookupMode {
|
|||||||
pub fn iterate_method_candidates<T>(
|
pub fn iterate_method_candidates<T>(
|
||||||
ty: &Canonical<Ty>,
|
ty: &Canonical<Ty>,
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
env: Arc<TraitEnvironment>,
|
||||||
|
krate: CrateId,
|
||||||
|
traits_in_scope: &FxHashSet<TraitId>,
|
||||||
name: Option<&Name>,
|
name: Option<&Name>,
|
||||||
mode: LookupMode,
|
mode: LookupMode,
|
||||||
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
mut callback: impl FnMut(&Ty, AssocItemId) -> Option<T>,
|
||||||
) -> Option<T> {
|
) -> Option<T> {
|
||||||
let traits_in_scope = resolver.traits_in_scope(db);
|
|
||||||
let krate = resolver.krate()?;
|
|
||||||
let env = TraitEnvironment::lower(db, resolver);
|
|
||||||
match mode {
|
match mode {
|
||||||
LookupMode::MethodCall => {
|
LookupMode::MethodCall => {
|
||||||
// For method calls, rust first does any number of autoderef, and then one
|
// For method calls, rust first does any number of autoderef, and then one
|
||||||
@ -190,9 +199,7 @@ pub fn iterate_method_candidates<T>(
|
|||||||
// Also note that when we've got a receiver like &S, even if the method we
|
// Also note that when we've got a receiver like &S, even if the method we
|
||||||
// find in the end takes &self, we still do the autoderef step (just as
|
// find in the end takes &self, we still do the autoderef step (just as
|
||||||
// rustc does an autoderef and then autoref again).
|
// rustc does an autoderef and then autoref again).
|
||||||
let environment = TraitEnvironment::lower(db, resolver);
|
let ty = InEnvironment { value: ty.clone(), environment: env.clone() };
|
||||||
let ty = InEnvironment { value: ty.clone(), environment };
|
|
||||||
let krate = resolver.krate()?;
|
|
||||||
|
|
||||||
// We have to be careful about the order we're looking at candidates
|
// We have to be careful about the order we're looking at candidates
|
||||||
// in here. Consider the case where we're resolving `x.clone()`
|
// in here. Consider the case where we're resolving `x.clone()`
|
||||||
@ -214,7 +221,7 @@ pub fn iterate_method_candidates<T>(
|
|||||||
db,
|
db,
|
||||||
env.clone(),
|
env.clone(),
|
||||||
krate,
|
krate,
|
||||||
&traits_in_scope,
|
traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
) {
|
) {
|
||||||
@ -230,7 +237,7 @@ pub fn iterate_method_candidates<T>(
|
|||||||
db,
|
db,
|
||||||
env,
|
env,
|
||||||
krate,
|
krate,
|
||||||
&traits_in_scope,
|
traits_in_scope,
|
||||||
name,
|
name,
|
||||||
&mut callback,
|
&mut callback,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user