@@ -1508,15 +1508,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1508
1508
} )
1509
1509
}
1510
1510
1511
- /// Return Some(true) if the obligation's predicate type applies to the env_predicate, and
1512
- /// Some(false) if it does not. Returns None in the case that the projection type is a GAT,
1511
+ /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and
1512
+ /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT,
1513
1513
/// and applying this env_predicate constrains any of the obligation's GAT substitutions.
1514
+ ///
1515
+ /// This behavior is a somewhat of a hack to prevent overconstraining inference variables
1516
+ /// in cases like #91762.
1514
1517
pub ( super ) fn match_projection_projections (
1515
1518
& mut self ,
1516
1519
obligation : & ProjectionTyObligation < ' tcx > ,
1517
1520
env_predicate : PolyProjectionPredicate < ' tcx > ,
1518
1521
potentially_unnormalized_candidates : bool ,
1519
- ) -> Option < bool > {
1522
+ ) -> ProjectionMatchesProjection {
1520
1523
let mut nested_obligations = Vec :: new ( ) ;
1521
1524
let ( infer_predicate, _) = self . infcx . replace_bound_vars_with_fresh_vars (
1522
1525
obligation. cause . span ,
@@ -1553,20 +1556,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1553
1556
1554
1557
if is_match {
1555
1558
let generics = self . tcx ( ) . generics_of ( obligation. predicate . item_def_id ) ;
1556
- if !generics. params . is_empty ( ) {
1557
- // If any of the obligation's predicate substs shallow-resolve to
1558
- // something new, that means that we must have newly inferred something
1559
- // about the GAT. We should give up with ambiguity in that case.
1560
- if obligation. predicate . substs [ generics. parent_count ..]
1559
+ // FIXME(generic-associated-types): Addresses aggressive inference in #92917.
1560
+ // If this type is a GAT, and of the GAT substs resolve to something new,
1561
+ // that means that we must have newly inferred something about the GAT.
1562
+ // We should give up in that case.
1563
+ if !generics. params . is_empty ( )
1564
+ && obligation. predicate . substs [ generics. parent_count ..]
1561
1565
. iter ( )
1562
1566
. any ( |& p| p. has_infer_types_or_consts ( ) && self . infcx . shallow_resolve ( p) != p)
1563
- {
1564
- return None ;
1565
- }
1567
+ {
1568
+ ProjectionMatchesProjection :: Ambiguous
1569
+ } else {
1570
+ ProjectionMatchesProjection :: Yes
1566
1571
}
1572
+ } else {
1573
+ ProjectionMatchesProjection :: No
1567
1574
}
1568
-
1569
- Some ( is_match)
1570
1575
}
1571
1576
1572
1577
///////////////////////////////////////////////////////////////////////////
@@ -2766,3 +2771,9 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> {
2766
2771
write ! ( f, "TraitObligationStack({:?})" , self . obligation)
2767
2772
}
2768
2773
}
2774
+
2775
+ pub enum ProjectionMatchesProjection {
2776
+ Yes ,
2777
+ Ambiguous ,
2778
+ No ,
2779
+ }
0 commit comments