X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Fhir_ty%2Fsrc%2Fmethod_resolution.rs;h=06c834fbc89e1702cea99de5b229a2f0bbe8932c;hb=b301b040f5781a9083348936369a01c37138756f;hp=44ece57a8e0e74142df94770fd828a1bfa6fd7bf;hpb=8f504dc87384b0fa41a55327566f0db9c08eb98c;p=rust.git diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 44ece57a8e0..06c834fbc89 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -6,7 +6,7 @@ use arrayvec::ArrayVec; use base_db::{CrateId, Edition}; -use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; +use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, Mutability, UniverseIndex}; use hir_def::{ item_scope::ItemScope, lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId, ConstId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId, @@ -25,8 +25,9 @@ primitive::{self, FloatTy, IntTy, UintTy}, static_lifetime, utils::all_super_traits, - AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner, - Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, + AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, GenericArgData, + InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, + TyExt, TyKind, }; /// This is used as a key for indexing impls. @@ -278,7 +279,7 @@ pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId impls.collect_def_map(db, &crate_def_map); impls.shrink_to_fit(); - return Arc::new(impls); + Arc::new(impls) } pub(crate) fn inherent_impls_in_block_query( @@ -291,7 +292,7 @@ pub(crate) fn inherent_impls_in_block_query( impls.shrink_to_fit(); return Some(Arc::new(impls)); } - return None; + None } fn shrink_to_fit(&mut self) { @@ -663,7 +664,7 @@ pub fn iterate_method_candidates_dyn( iterate_method_candidates_for_self_ty( ty, db, - env.clone(), + env, traits_in_scope, visible_from_module, name, @@ -693,7 +694,7 @@ fn iterate_method_candidates_with_autoref( iterate_method_candidates_by_receiver( receiver_ty, first_adjustment.clone(), - &rest, + rest, db, env.clone(), traits_in_scope, @@ -731,7 +732,7 @@ fn iterate_method_candidates_with_autoref( first_adjustment.with_autoref(Mutability::Mut), deref_chain, db, - env.clone(), + env, traits_in_scope, visible_from_module, name, @@ -973,7 +974,7 @@ fn impls_for_self_ty( // already happens in `is_valid_candidate` above; if not, we // check it here if receiver_ty.is_none() - && inherent_impl_substs(db, env.clone(), impl_def, &self_ty).is_none() + && inherent_impl_substs(db, env.clone(), impl_def, self_ty).is_none() { cov_mark::hit!(impl_self_type_match_without_receiver); continue; @@ -1087,13 +1088,14 @@ pub(crate) fn inherent_impl_substs( .build(); let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(Interner, &vars); let mut kinds = self_ty.binders.interned().to_vec(); - kinds.extend( - iter::repeat(chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), - UniverseIndex::ROOT, - )) - .take(vars.len(Interner)), - ); + kinds.extend(vars.iter(Interner).map(|x| { + let kind = match x.data(Interner) { + GenericArgData::Ty(_) => chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), + GenericArgData::Const(c) => chalk_ir::VariableKind::Const(c.data(Interner).ty.clone()), + GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime, + }; + chalk_ir::WithKind::new(kind, UniverseIndex::ROOT) + })); let tys = Canonical { binders: CanonicalVarKinds::from_iter(Interner, kinds), value: (self_ty_with_vars, self_ty.value.clone()), @@ -1105,20 +1107,33 @@ pub(crate) fn inherent_impl_substs( // Unknown, and in that case we want the result to contain Unknown in those // places again. let suffix = - Substitution::from_iter(Interner, substs.iter(Interner).cloned().skip(self_ty_vars)); + Substitution::from_iter(Interner, substs.iter(Interner).skip(self_ty_vars).cloned()); Some(fallback_bound_vars(suffix, self_ty_vars)) } /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past /// num_vars_to_keep) by `TyKind::Unknown`. -fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution { - crate::fold_free_vars(s, |bound, binders| { - if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST { - TyKind::Error.intern(Interner) - } else { - bound.shifted_in_from(binders).to_ty(Interner) - } - }) +pub(crate) fn fallback_bound_vars + HasInterner>( + s: T, + num_vars_to_keep: usize, +) -> T::Result { + crate::fold_free_vars( + s, + |bound, binders| { + if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST { + TyKind::Error.intern(Interner) + } else { + bound.shifted_in_from(binders).to_ty(Interner) + } + }, + |ty, bound, binders| { + if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST { + consteval::usize_const(None) + } else { + bound.shifted_in_from(binders).to_const(Interner, ty) + } + }, + ) } fn transform_receiver_ty( @@ -1152,7 +1167,7 @@ pub fn implements_trait( env: Arc, trait_: TraitId, ) -> bool { - let goal = generic_implements_goal(db, env.clone(), trait_, &ty); + let goal = generic_implements_goal(db, env.clone(), trait_, ty); let solution = db.trait_solve(env.krate, goal.cast(Interner)); solution.is_some() @@ -1164,7 +1179,7 @@ pub fn implements_trait_unique( env: Arc, trait_: TraitId, ) -> bool { - let goal = generic_implements_goal(db, env.clone(), trait_, &ty); + let goal = generic_implements_goal(db, env.clone(), trait_, ty); let solution = db.trait_solve(env.krate, goal.cast(Interner)); matches!(solution, Some(crate::Solution::Unique(_))) @@ -1183,13 +1198,18 @@ fn generic_implements_goal( .push(self_ty.value.clone()) .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) .build(); - kinds.extend( - iter::repeat(chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), - UniverseIndex::ROOT, - )) - .take(trait_ref.substitution.len(Interner) - 1), - ); + kinds.extend(trait_ref.substitution.iter(Interner).skip(1).map(|x| { + let vk = match x.data(Interner) { + chalk_ir::GenericArgData::Ty(_) => { + chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General) + } + chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime, + chalk_ir::GenericArgData::Const(c) => { + chalk_ir::VariableKind::Const(c.data(Interner).ty.clone()) + } + }; + chalk_ir::WithKind::new(vk, UniverseIndex::ROOT) + })); let obligation = trait_ref.cast(Interner); Canonical { binders: CanonicalVarKinds::from_iter(Interner, kinds),