Use proper ImplTraits in insert_inference_vars_for_impl_trait

This commit is contained in:
Shoyu Vanilla 2024-06-27 23:51:33 +09:00
parent 50b7678621
commit 7e9da2d67d

View File

@ -835,11 +835,7 @@ impl<'a> InferenceContext<'a> {
let return_ty = if let Some(rpits) = self.db.return_type_impl_traits(func) { let return_ty = if let Some(rpits) = self.db.return_type_impl_traits(func) {
// RPIT opaque types use substitution of their parent function. // RPIT opaque types use substitution of their parent function.
let fn_placeholders = TyBuilder::placeholder_subst(self.db, func); let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
let result = self.insert_inference_vars_for_impl_trait( let result = self.insert_inference_vars_for_impl_trait(return_ty, fn_placeholders);
return_ty,
rpits.clone(),
fn_placeholders,
);
let rpits = rpits.skip_binders(); let rpits = rpits.skip_binders();
for (id, _) in rpits.impl_traits.iter() { for (id, _) in rpits.impl_traits.iter() {
if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) { if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
@ -862,12 +858,7 @@ impl<'a> InferenceContext<'a> {
self.insert_atpit_coercion_table(params_and_ret_tys.iter()); self.insert_atpit_coercion_table(params_and_ret_tys.iter());
} }
fn insert_inference_vars_for_impl_trait<T>( fn insert_inference_vars_for_impl_trait<T>(&mut self, t: T, placeholders: Substitution) -> T
&mut self,
t: T,
rpits: Arc<chalk_ir::Binders<crate::ImplTraits>>,
placeholders: Substitution,
) -> T
where where
T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>, T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>,
{ {
@ -878,13 +869,21 @@ impl<'a> InferenceContext<'a> {
TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id, TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id,
_ => return ty, _ => return ty,
}; };
let idx = match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) { let (impl_traits, idx) =
ImplTraitId::ReturnTypeImplTrait(_, idx) => idx, match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
ImplTraitId::AssociatedTypeImplTrait(_, idx) => idx, ImplTraitId::ReturnTypeImplTrait(def, idx) => {
_ => unreachable!(), (self.db.return_type_impl_traits(def), idx)
}
ImplTraitId::AssociatedTypeImplTrait(def, idx) => {
(self.db.type_alias_impl_traits(def), idx)
}
_ => unreachable!(),
};
let Some(impl_traits) = impl_traits else {
return ty;
}; };
let bounds = let bounds = (*impl_traits)
(*rpits).map_ref(|rpits| rpits.impl_traits[idx].bounds.map_ref(|it| it.iter())); .map_ref(|rpits| rpits.impl_traits[idx].bounds.map_ref(|it| it.iter()));
let var = self.table.new_type_var(); let var = self.table.new_type_var();
let var_subst = Substitution::from1(Interner, var.clone()); let var_subst = Substitution::from1(Interner, var.clone());
for bound in bounds { for bound in bounds {
@ -892,11 +891,8 @@ impl<'a> InferenceContext<'a> {
let (var_predicate, binders) = let (var_predicate, binders) =
predicate.substitute(Interner, &var_subst).into_value_and_skipped_binders(); predicate.substitute(Interner, &var_subst).into_value_and_skipped_binders();
always!(binders.is_empty(Interner)); // quantified where clauses not yet handled always!(binders.is_empty(Interner)); // quantified where clauses not yet handled
let var_predicate = self.insert_inference_vars_for_impl_trait( let var_predicate = self
var_predicate, .insert_inference_vars_for_impl_trait(var_predicate, placeholders.clone());
rpits.clone(),
placeholders.clone(),
);
self.push_obligation(var_predicate.cast(Interner)); self.push_obligation(var_predicate.cast(Interner));
} }
self.result.type_of_rpit.insert(idx, var.clone()); self.result.type_of_rpit.insert(idx, var.clone());
@ -983,16 +979,8 @@ impl<'a> InferenceContext<'a> {
self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) self.db.lookup_intern_impl_trait_id(opaque_ty_id.into())
{ {
if assoc_tys.contains(&alias_id) { if assoc_tys.contains(&alias_id) {
let atpits = self
.db
.type_alias_impl_traits(alias_id)
.expect("Marked as ATPIT but no impl traits!");
let alias_placeholders = TyBuilder::placeholder_subst(self.db, alias_id); let alias_placeholders = TyBuilder::placeholder_subst(self.db, alias_id);
let ty = self.insert_inference_vars_for_impl_trait( let ty = self.insert_inference_vars_for_impl_trait(ty, alias_placeholders);
ty,
atpits,
alias_placeholders,
);
return Some((opaque_ty_id, ty)); return Some((opaque_ty_id, ty));
} }
} }