@@ -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,26 +1479,52 @@ 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 valid = predicates
1482- . iter ( )
1483- . map ( |predicate| {
1484- let ( p, b) = predicate
1485- . clone ( )
1486- . substitute ( Interner , & impl_subst)
1487- // Skipping the inner binders is ok, as we don't handle quantified where
1488- // clauses yet.
1489- . into_value_and_skipped_binders ( ) ;
1490- stdx:: always!( b. len( Interner ) == 0 ) ;
1491- p
1492- } )
1493- // It's ok to get ambiguity here, as we may not have enough information to prove
1494- // obligations. We'll check if the user is calling the selected method properly
1495- // later anyway.
1496- . all ( |p| table. try_obligation ( p. cast ( Interner ) ) . is_some ( ) ) ;
1497- match valid {
1498- true => IsValidCandidate :: Yes ,
1499- false => IsValidCandidate :: No ,
1482+ let goals = predicates. iter ( ) . map ( |p| {
1483+ let ( p, b) = p
1484+ . clone ( )
1485+ . substitute ( Interner , & impl_subst)
1486+ // Skipping the inner binders is ok, as we don't handle quantified where
1487+ // clauses yet.
1488+ . into_value_and_skipped_binders ( ) ;
1489+ stdx:: always!( b. len( Interner ) == 0 ) ;
1490+
1491+ p. cast :: < Goal > ( Interner )
1492+ } ) ;
1493+
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 ,
1518+ }
15001519 }
1520+
1521+ for goal in goals {
1522+ if table. try_obligation ( goal) . is_none ( ) {
1523+ return IsValidCandidate :: No ;
1524+ }
1525+ }
1526+
1527+ IsValidCandidate :: Yes
15011528 } else {
15021529 // For `ItemContainerId::TraitId`, we check if `self_ty` implements the trait in
15031530 // `iterate_trait_method_candidates()`.
0 commit comments