address comment
This commit is contained in:
parent
e95ec55273
commit
808f6687f7
@ -43,7 +43,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
|
impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
|
||||||
pub(super) fn apply_solution(
|
pub(crate) fn apply_solution(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut InferenceTable<'_>,
|
ctx: &mut InferenceTable<'_>,
|
||||||
solution: Canonical<Substitution>,
|
solution: Canonical<Substitution>,
|
||||||
@ -495,35 +495,6 @@ impl<'a> InferenceTable<'a> {
|
|||||||
solution
|
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) {
|
pub(crate) fn register_obligation(&mut self, goal: Goal) {
|
||||||
let in_env = InEnvironment::new(&self.trait_env.env, goal);
|
let in_env = InEnvironment::new(&self.trait_env.env, goal);
|
||||||
self.register_obligation_in_env(in_env)
|
self.register_obligation_in_env(in_env)
|
||||||
|
@ -27,8 +27,9 @@ use crate::{
|
|||||||
primitive::{FloatTy, IntTy, UintTy},
|
primitive::{FloatTy, IntTy, UintTy},
|
||||||
static_lifetime, to_chalk_trait_id,
|
static_lifetime, to_chalk_trait_id,
|
||||||
utils::all_super_traits,
|
utils::all_super_traits,
|
||||||
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, InEnvironment,
|
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
|
||||||
Interner, Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt,
|
InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
|
||||||
|
TraitRefExt, Ty, TyBuilder, TyExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is used as a key for indexing impls.
|
/// 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
|
// We need to consider the bounds on the impl to distinguish functions of the same name
|
||||||
// for a type.
|
// for a type.
|
||||||
let predicates = db.generic_predicates(impl_id.into());
|
let predicates = db.generic_predicates(impl_id.into());
|
||||||
let mut alias = Vec::new();
|
let goals = predicates.iter().map(|p| {
|
||||||
let mut other_predicate = Vec::new();
|
let (p, b) = p
|
||||||
|
|
||||||
for predicate in predicates.iter() {
|
|
||||||
let (p, b) = predicate
|
|
||||||
.clone()
|
.clone()
|
||||||
.substitute(Interner, &impl_subst)
|
.substitute(Interner, &impl_subst)
|
||||||
// Skipping the inner binders is ok, as we don't handle quantified where
|
// 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();
|
.into_value_and_skipped_binders();
|
||||||
stdx::always!(b.len(Interner) == 0);
|
stdx::always!(b.len(Interner) == 0);
|
||||||
|
|
||||||
if let WhereClause::AliasEq(_) = p {
|
p.cast::<Goal>(Interner)
|
||||||
alias.push(p);
|
});
|
||||||
} else {
|
|
||||||
other_predicate.push(p);
|
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 {
|
for goal in goals {
|
||||||
if !table.try_resolve_alias(p.cast(Interner)) {
|
if table.try_obligation(goal).is_none() {
|
||||||
return IsValidCandidate::No;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for p in other_predicate {
|
|
||||||
if table.try_obligation(p.cast(Interner)).is_none() {
|
|
||||||
return IsValidCandidate::No;
|
return IsValidCandidate::No;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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]
|
#[test]
|
||||||
fn dyn_trait_through_chalk() {
|
fn dyn_trait_through_chalk() {
|
||||||
check_types(
|
check_types(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user