Skip to content

Commit 808f668

Browse files
committed
address comment
1 parent e95ec55 commit 808f668

File tree

3 files changed

+62
-48
lines changed

3 files changed

+62
-48
lines changed

crates/hir-ty/src/infer/unify.rs

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ where
4343
}
4444

4545
impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
46-
pub(super) fn apply_solution(
46+
pub(crate) fn apply_solution(
4747
&self,
4848
ctx: &mut InferenceTable<'_>,
4949
solution: Canonical<Substitution>,
@@ -495,35 +495,6 @@ impl<'a> InferenceTable<'a> {
495495
solution
496496
}
497497

498-
pub(crate) fn try_resolve_alias(&mut self, goal: Goal) -> bool {
499-
let in_env = InEnvironment::new(&self.trait_env.env, goal);
500-
let canonicalized = self.canonicalize(in_env);
501-
let solution = self.db.trait_solve(
502-
self.trait_env.krate,
503-
self.trait_env.block,
504-
canonicalized.value.clone(),
505-
);
506-
507-
match solution {
508-
Some(Solution::Unique(canonical_subst)) => {
509-
canonicalized.apply_solution(
510-
self,
511-
Canonical {
512-
binders: canonical_subst.binders,
513-
value: canonical_subst.value.subst,
514-
},
515-
);
516-
true
517-
}
518-
Some(Solution::Ambig(Guidance::Definite(substs))) => {
519-
canonicalized.apply_solution(self, substs);
520-
true
521-
}
522-
Some(_) => true,
523-
None => false,
524-
}
525-
}
526-
527498
pub(crate) fn register_obligation(&mut self, goal: Goal) {
528499
let in_env = InEnvironment::new(&self.trait_env.env, goal);
529500
self.register_obligation_in_env(in_env)

crates/hir-ty/src/method_resolution.rs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ use crate::{
2727
primitive::{FloatTy, IntTy, UintTy},
2828
static_lifetime, to_chalk_trait_id,
2929
utils::all_super_traits,
30-
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, InEnvironment,
31-
Interner, Scalar, Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyExt,
30+
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, DynTyExt, ForeignDefId, Goal, Guidance,
31+
InEnvironment, Interner, Scalar, Solution, Substitution, TraitEnvironment, TraitRef,
32+
TraitRefExt, Ty, TyBuilder, TyExt,
3233
};
3334

3435
/// This is used as a key for indexing impls.
@@ -1478,33 +1479,47 @@ fn is_valid_fn_candidate(
14781479
// We need to consider the bounds on the impl to distinguish functions of the same name
14791480
// for a type.
14801481
let predicates = db.generic_predicates(impl_id.into());
1481-
let mut alias = Vec::new();
1482-
let mut other_predicate = Vec::new();
1483-
1484-
for predicate in predicates.iter() {
1485-
let (p, b) = predicate
1482+
let goals = predicates.iter().map(|p| {
1483+
let (p, b) = p
14861484
.clone()
14871485
.substitute(Interner, &impl_subst)
14881486
// Skipping the inner binders is ok, as we don't handle quantified where
14891487
// clauses yet.
14901488
.into_value_and_skipped_binders();
14911489
stdx::always!(b.len(Interner) == 0);
14921490

1493-
if let WhereClause::AliasEq(_) = p {
1494-
alias.push(p);
1495-
} else {
1496-
other_predicate.push(p);
1497-
}
1498-
}
1491+
p.cast::<Goal>(Interner)
1492+
});
14991493

1500-
for p in alias {
1501-
if !table.try_resolve_alias(p.cast(Interner)) {
1502-
return IsValidCandidate::No;
1494+
for goal in goals.clone() {
1495+
let in_env = InEnvironment::new(&table.trait_env.env, goal);
1496+
let canonicalized = table.canonicalize(in_env);
1497+
let solution = table.db.trait_solve(
1498+
table.trait_env.krate,
1499+
table.trait_env.block,
1500+
canonicalized.value.clone(),
1501+
);
1502+
1503+
match solution {
1504+
Some(Solution::Unique(canonical_subst)) => {
1505+
canonicalized.apply_solution(
1506+
table,
1507+
Canonical {
1508+
binders: canonical_subst.binders,
1509+
value: canonical_subst.value.subst,
1510+
},
1511+
);
1512+
}
1513+
Some(Solution::Ambig(Guidance::Definite(substs))) => {
1514+
canonicalized.apply_solution(table, substs);
1515+
}
1516+
Some(_) => (),
1517+
None => return IsValidCandidate::No,
15031518
}
15041519
}
15051520

1506-
for p in other_predicate {
1507-
if table.try_obligation(p.cast(Interner)).is_none() {
1521+
for goal in goals {
1522+
if table.try_obligation(goal).is_none() {
15081523
return IsValidCandidate::No;
15091524
}
15101525
}

crates/hir-ty/src/tests/traits.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,34 @@ fn test<T: Trait>() {
25972597
);
25982598
}
25992599

2600+
#[test]
2601+
fn associated_type_in_type_bound() {
2602+
check_types(
2603+
r#"
2604+
//- minicore: deref
2605+
fn fb(f: Foo<&u8>) {
2606+
f.foobar();
2607+
//^^^^^^^^^^ u8
2608+
}
2609+
trait Bar {
2610+
fn bar(&self) -> u8;
2611+
}
2612+
impl Bar for u8 {
2613+
fn bar(&self) -> u8 { *self }
2614+
}
2615+
2616+
struct Foo<F> {
2617+
foo: F,
2618+
}
2619+
impl<F: core::ops::Deref<Target = impl Bar>> Foo<F> {
2620+
fn foobar(&self) -> u8 {
2621+
self.foo.deref().bar()
2622+
}
2623+
}
2624+
"#,
2625+
)
2626+
}
2627+
26002628
#[test]
26012629
fn dyn_trait_through_chalk() {
26022630
check_types(

0 commit comments

Comments
 (0)