address comment

This commit is contained in:
austaras 2023-11-17 16:47:46 +08:00
parent e95ec55273
commit 808f6687f7
3 changed files with 63 additions and 49 deletions

View File

@ -43,7 +43,7 @@ where
}
impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
pub(super) fn apply_solution(
pub(crate) fn apply_solution(
&self,
ctx: &mut InferenceTable<'_>,
solution: Canonical<Substitution>,
@ -495,35 +495,6 @@ impl<'a> InferenceTable<'a> {
solution
}
pub(crate) fn try_resolve_alias(&mut self, goal: Goal) -> bool {
let in_env = InEnvironment::new(&self.trait_env.env, goal);
let canonicalized = self.canonicalize(in_env);
let solution = self.db.trait_solve(
self.trait_env.krate,
self.trait_env.block,
canonicalized.value.clone(),
);
match solution {
Some(Solution::Unique(canonical_subst)) => {
canonicalized.apply_solution(
self,
Canonical {
binders: canonical_subst.binders,
value: canonical_subst.value.subst,
},
);
true
}
Some(Solution::Ambig(Guidance::Definite(substs))) => {
canonicalized.apply_solution(self, substs);
true
}
Some(_) => true,
None => false,
}
}
pub(crate) fn register_obligation(&mut self, goal: Goal) {
let in_env = InEnvironment::new(&self.trait_env.env, goal);
self.register_obligation_in_env(in_env)

View File

@ -27,8 +27,9 @@ use crate::{
primitive::{FloatTy, IntTy, UintTy},
static_lifetime, to_chalk_trait_id,
utils::all_super_traits,
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, InEnvironment,
Interner, Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt,
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
TraitRefExt, Ty, TyBuilder, TyExt,
};
/// This is used as a key for indexing impls.
@ -1478,11 +1479,8 @@ fn is_valid_fn_candidate(
// We need to consider the bounds on the impl to distinguish functions of the same name
// for a type.
let predicates = db.generic_predicates(impl_id.into());
let mut alias = Vec::new();
let mut other_predicate = Vec::new();
for predicate in predicates.iter() {
let (p, b) = predicate
let goals = predicates.iter().map(|p| {
let (p, b) = p
.clone()
.substitute(Interner, &impl_subst)
// Skipping the inner binders is ok, as we don't handle quantified where
@ -1490,21 +1488,38 @@ fn is_valid_fn_candidate(
.into_value_and_skipped_binders();
stdx::always!(b.len(Interner) == 0);
if let WhereClause::AliasEq(_) = p {
alias.push(p);
} else {
other_predicate.push(p);
p.cast::<Goal>(Interner)
});
for goal in goals.clone() {
let in_env = InEnvironment::new(&table.trait_env.env, goal);
let canonicalized = table.canonicalize(in_env);
let solution = table.db.trait_solve(
table.trait_env.krate,
table.trait_env.block,
canonicalized.value.clone(),
);
match solution {
Some(Solution::Unique(canonical_subst)) => {
canonicalized.apply_solution(
table,
Canonical {
binders: canonical_subst.binders,
value: canonical_subst.value.subst,
},
);
}
Some(Solution::Ambig(Guidance::Definite(substs))) => {
canonicalized.apply_solution(table, substs);
}
Some(_) => (),
None => return IsValidCandidate::No,
}
}
for p in alias {
if !table.try_resolve_alias(p.cast(Interner)) {
return IsValidCandidate::No;
}
}
for p in other_predicate {
if table.try_obligation(p.cast(Interner)).is_none() {
for goal in goals {
if table.try_obligation(goal).is_none() {
return IsValidCandidate::No;
}
}

View File

@ -2597,6 +2597,34 @@ fn test<T: Trait>() {
);
}
#[test]
fn associated_type_in_type_bound() {
check_types(
r#"
//- minicore: deref
fn fb(f: Foo<&u8>) {
f.foobar();
//^^^^^^^^^^ u8
}
trait Bar {
fn bar(&self) -> u8;
}
impl Bar for u8 {
fn bar(&self) -> u8 { *self }
}
struct Foo<F> {
foo: F,
}
impl<F: core::ops::Deref<Target = impl Bar>> Foo<F> {
fn foobar(&self) -> u8 {
self.foo.deref().bar()
}
}
"#,
)
}
#[test]
fn dyn_trait_through_chalk() {
check_types(