Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/path.rs')
-rw-r--r--crates/hir-ty/src/infer/path.rs91
1 files changed, 38 insertions, 53 deletions
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index 9ade842013..b11650bbcd 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -13,11 +13,12 @@ use crate::{
InferenceDiagnostic, ValueTyDefId,
generics::generics,
infer::diagnostics::InferenceTyLoweringContext as TyLoweringContext,
- lower::LifetimeElisionKind,
- method_resolution::{self, VisibleFromModule},
+ lower::{GenericPredicates, LifetimeElisionKind},
+ method_resolution::{self, CandidateId, MethodError},
next_solver::{
GenericArg, GenericArgs, TraitRef, Ty,
infer::traits::{Obligation, ObligationCause},
+ util::clauses_as_obligations,
},
};
@@ -31,7 +32,7 @@ impl<'db> InferenceContext<'_, 'db> {
}
ValuePathResolution::NonGeneric(ty) => return Some(ty),
};
- let args = self.process_remote_user_written_ty(substs);
+ let args = self.insert_type_vars(substs);
self.add_required_obligations_for_value_path(generic_def, args);
@@ -63,7 +64,7 @@ impl<'db> InferenceContext<'_, 'db> {
}
ValueNs::LocalBinding(pat) => {
return match self.result.type_of_binding.get(pat) {
- Some(ty) => Some(ValuePathResolution::NonGeneric(*ty)),
+ Some(ty) => Some(ValuePathResolution::NonGeneric(ty.as_ref())),
None => {
never!("uninferred pattern?");
None
@@ -101,7 +102,7 @@ impl<'db> InferenceContext<'_, 'db> {
// This is something like `TypeAlias::<Args>::EnumVariant`. Do not call `substs_from_path()`,
// as it'll try to re-lower the previous segment assuming it refers to the enum, but it refers
// to the type alias and they may have different generics.
- self.types.empty_args
+ self.types.empty.generic_args
} else {
self.with_body_ty_lowering(|ctx| {
let mut path_ctx = ctx.at_path(path, id);
@@ -221,14 +222,14 @@ impl<'db> InferenceContext<'_, 'db> {
def: GenericDefId,
subst: GenericArgs<'db>,
) {
- let predicates = self.db.generic_predicates(def);
let interner = self.interner();
- let param_env = self.table.trait_env.env;
- if let Some(predicates) = predicates.instantiate(self.interner(), subst) {
- self.table.register_predicates(predicates.map(|predicate| {
- Obligation::new(interner, ObligationCause::new(), param_env, predicate)
- }));
- }
+ let predicates = GenericPredicates::query_all(self.db, def);
+ let param_env = self.table.param_env;
+ self.table.register_predicates(clauses_as_obligations(
+ predicates.iter_instantiated_copied(interner, subst.as_slice()),
+ ObligationCause::new(),
+ param_env,
+ ));
// We need to add `Self: Trait` obligation when `def` is a trait assoc item.
let container = match def {
@@ -239,11 +240,8 @@ impl<'db> InferenceContext<'_, 'db> {
if let ItemContainerId::TraitId(trait_) = container {
let parent_len = generics(self.db, def).parent_generics().map_or(0, |g| g.len_self());
- let parent_subst = GenericArgs::new_from_iter(
- interner,
- subst.as_slice()[..parent_len].iter().copied(),
- );
- let trait_ref = TraitRef::new(interner, trait_.into(), parent_subst);
+ let parent_subst = GenericArgs::new_from_slice(&subst.as_slice()[..parent_len]);
+ let trait_ref = TraitRef::new_from_args(interner, trait_.into(), parent_subst);
self.table.register_predicate(Obligation::new(
interner,
ObligationCause::new(),
@@ -265,7 +263,7 @@ impl<'db> InferenceContext<'_, 'db> {
match item {
AssocItemId::FunctionId(func) => {
if segment.name == &self.db.function_signature(func).name {
- Some(AssocItemId::FunctionId(func))
+ Some(CandidateId::FunctionId(func))
} else {
None
}
@@ -273,7 +271,7 @@ impl<'db> InferenceContext<'_, 'db> {
AssocItemId::ConstId(konst) => {
if self.db.const_signature(konst).name.as_ref() == Some(segment.name) {
- Some(AssocItemId::ConstId(konst))
+ Some(CandidateId::ConstId(konst))
} else {
None
}
@@ -282,9 +280,8 @@ impl<'db> InferenceContext<'_, 'db> {
}
})?;
let def = match item {
- AssocItemId::FunctionId(f) => ValueNs::FunctionId(f),
- AssocItemId::ConstId(c) => ValueNs::ConstId(c),
- AssocItemId::TypeAliasId(_) => unreachable!(),
+ CandidateId::FunctionId(f) => ValueNs::FunctionId(f),
+ CandidateId::ConstId(c) => ValueNs::ConstId(c),
};
self.write_assoc_resolution(id, item, trait_ref.args);
@@ -305,39 +302,23 @@ impl<'db> InferenceContext<'_, 'db> {
return Some(result);
}
- let canonical_ty = self.canonicalize(ty);
-
- let mut not_visible = None;
- let res = method_resolution::iterate_method_candidates(
- &canonical_ty,
- &mut self.table,
- Self::get_traits_in_scope(&self.resolver, &self.traits_in_scope)
- .as_ref()
- .left_or_else(|&it| it),
- VisibleFromModule::Filter(self.resolver.module()),
- Some(name),
- method_resolution::LookupMode::Path,
- |_ty, item, visible| {
- if visible {
- Some((item, true))
- } else {
- if not_visible.is_none() {
- not_visible = Some((item, false));
- }
- None
+ let res = self.with_method_resolution(|ctx| {
+ ctx.probe_for_name(method_resolution::Mode::Path, name.clone(), ty)
+ });
+ let (item, visible) = match res {
+ Ok(res) => (res.item, true),
+ Err(error) => match error {
+ MethodError::PrivateMatch(candidate_id) => (candidate_id.item, false),
+ _ => {
+ self.push_diagnostic(InferenceDiagnostic::UnresolvedAssocItem { id });
+ return None;
}
},
- );
- let res = res.or(not_visible);
- if res.is_none() {
- self.push_diagnostic(InferenceDiagnostic::UnresolvedAssocItem { id });
- }
- let (item, visible) = res?;
+ };
let (def, container) = match item {
- AssocItemId::FunctionId(f) => (ValueNs::FunctionId(f), f.lookup(self.db).container),
- AssocItemId::ConstId(c) => (ValueNs::ConstId(c), c.lookup(self.db).container),
- AssocItemId::TypeAliasId(_) => unreachable!(),
+ CandidateId::FunctionId(f) => (ValueNs::FunctionId(f), f.lookup(self.db).container),
+ CandidateId::ConstId(c) => (ValueNs::ConstId(c), c.lookup(self.db).container),
};
let substs = match container {
ItemContainerId::ImplId(impl_id) => {
@@ -355,11 +336,11 @@ impl<'db> InferenceContext<'_, 'db> {
[ty.into()],
|_, id, _| self.table.next_var_for_param(id),
);
- let trait_ref = TraitRef::new(self.interner(), trait_.into(), args);
+ let trait_ref = TraitRef::new_from_args(self.interner(), trait_.into(), args);
self.table.register_predicate(Obligation::new(
self.interner(),
ObligationCause::new(),
- self.table.trait_env.env,
+ self.table.param_env,
trait_ref,
));
args
@@ -372,6 +353,10 @@ impl<'db> InferenceContext<'_, 'db> {
self.write_assoc_resolution(id, item, substs);
if !visible {
+ let item = match item {
+ CandidateId::FunctionId(it) => it.into(),
+ CandidateId::ConstId(it) => it.into(),
+ };
self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem { id, item });
}
Some((def, substs))