about summary refs log tree commit diff
diff options
context:
space:
mode:
authoraustaras <austaras@outlook.com>2023-11-17 16:47:46 +0800
committeraustaras <austaras@outlook.com>2023-11-17 16:53:38 +0800
commit808f6687f7b796dd2c171e3be3829f1dedb6d537 (patch)
tree50ddc8bb3cf9434cb4b37ef901804dd168f8e0e2
parente95ec552731be34a0820ded3c001a91398b6a2e1 (diff)
downloadrust-808f6687f7b796dd2c171e3be3829f1dedb6d537.tar.gz
rust-808f6687f7b796dd2c171e3be3829f1dedb6d537.zip
address comment
-rw-r--r--crates/hir-ty/src/infer/unify.rs31
-rw-r--r--crates/hir-ty/src/method_resolution.rs51
-rw-r--r--crates/hir-ty/src/tests/traits.rs28
3 files changed, 62 insertions, 48 deletions
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index 78bdd62a276..ac39bdf5bf5 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -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)
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 04a55c3536d..732643566a2 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -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 p in alias {
-                if !table.try_resolve_alias(p.cast(Interner)) {
-                    return IsValidCandidate::No;
+            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 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;
                 }
             }
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 48dd9540329..003ae60e8e5 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -2598,6 +2598,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(
         r#"