@@ -1508,15 +1508,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15081508 } )
15091509 }
15101510
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,
15131513 /// 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.
15141517 pub ( super ) fn match_projection_projections (
15151518 & mut self ,
15161519 obligation : & ProjectionTyObligation < ' tcx > ,
15171520 env_predicate : PolyProjectionPredicate < ' tcx > ,
15181521 potentially_unnormalized_candidates : bool ,
1519- ) -> Option < bool > {
1522+ ) -> ProjectionMatchesProjection {
15201523 let mut nested_obligations = Vec :: new ( ) ;
15211524 let ( infer_predicate, _) = self . infcx . replace_bound_vars_with_fresh_vars (
15221525 obligation. cause . span ,
@@ -1553,20 +1556,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15531556
15541557 if is_match {
15551558 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 ..]
15611565 . iter ( )
15621566 . 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
15661571 }
1572+ } else {
1573+ ProjectionMatchesProjection :: No
15671574 }
1568-
1569- Some ( is_match)
15701575 }
15711576
15721577 ///////////////////////////////////////////////////////////////////////////
@@ -2766,3 +2771,9 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> {
27662771 write ! ( f, "TraitObligationStack({:?})" , self . obligation)
27672772 }
27682773}
2774+
2775+ pub enum ProjectionMatchesProjection {
2776+ Yes ,
2777+ Ambiguous ,
2778+ No ,
2779+ }
0 commit comments