mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Use proper ImplTraits
in insert_inference_vars_for_impl_trait
This commit is contained in:
parent
50b7678621
commit
7e9da2d67d
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user