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.rs | 91 |
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)) |