@@ -27,8 +27,9 @@ use crate::{
27
27
primitive:: { FloatTy , IntTy , UintTy } ,
28
28
static_lifetime, to_chalk_trait_id,
29
29
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 ,
32
33
} ;
33
34
34
35
/// This is used as a key for indexing impls.
@@ -1478,26 +1479,52 @@ fn is_valid_fn_candidate(
1478
1479
// We need to consider the bounds on the impl to distinguish functions of the same name
1479
1480
// for a type.
1480
1481
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
+ }
1500
1519
}
1520
+
1521
+ for goal in goals {
1522
+ if table. try_obligation ( goal) . is_none ( ) {
1523
+ return IsValidCandidate :: No ;
1524
+ }
1525
+ }
1526
+
1527
+ IsValidCandidate :: Yes
1501
1528
} else {
1502
1529
// For `ItemContainerId::TraitId`, we check if `self_ty` implements the trait in
1503
1530
// `iterate_trait_method_candidates()`.
0 commit comments