@@ -1073,16 +1073,6 @@ fn project<'cx, 'tcx>(
1073
1073
return Ok ( Projected :: Progress ( Progress :: error ( selcx. tcx ( ) ) ) ) ;
1074
1074
}
1075
1075
1076
- // If the obligation contains any inference types or consts in associated
1077
- // type substs, then we don't assemble any candidates.
1078
- // This isn't really correct, but otherwise we can end up in a case where
1079
- // we constrain inference variables by selecting a single predicate, when
1080
- // we need to stay general. See issue #91762.
1081
- let ( _, predicate_own_substs) = obligation. predicate . trait_ref_and_own_substs ( selcx. tcx ( ) ) ;
1082
- if predicate_own_substs. iter ( ) . any ( |g| g. has_infer_types_or_consts ( ) ) {
1083
- return Err ( ProjectionError :: TooManyCandidates ) ;
1084
- }
1085
-
1086
1076
let mut candidates = ProjectionCandidateSet :: None ;
1087
1077
1088
1078
// Make sure that the following procedures are kept in order. ParamEnv
@@ -1180,7 +1170,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
1180
1170
ProjectionCandidate :: TraitDef ,
1181
1171
bounds. iter ( ) ,
1182
1172
true ,
1183
- )
1173
+ ) ;
1184
1174
}
1185
1175
1186
1176
/// In the case of a trait object like
@@ -1245,27 +1235,34 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
1245
1235
let bound_predicate = predicate. kind ( ) ;
1246
1236
if let ty:: PredicateKind :: Projection ( data) = predicate. kind ( ) . skip_binder ( ) {
1247
1237
let data = bound_predicate. rebind ( data) ;
1248
- let same_def_id = data. projection_def_id ( ) == obligation. predicate . item_def_id ;
1249
-
1250
- let is_match = same_def_id
1251
- && infcx. probe ( |_| {
1252
- selcx. match_projection_projections (
1253
- obligation,
1254
- data,
1255
- potentially_unnormalized_candidates,
1256
- )
1257
- } ) ;
1238
+ if data. projection_def_id ( ) != obligation. predicate . item_def_id {
1239
+ continue ;
1240
+ }
1258
1241
1259
- if is_match {
1260
- candidate_set. push_candidate ( ctor ( data) ) ;
1242
+ let is_match = infcx. probe ( |_| {
1243
+ selcx. match_projection_projections (
1244
+ obligation,
1245
+ data,
1246
+ potentially_unnormalized_candidates,
1247
+ )
1248
+ } ) ;
1261
1249
1262
- if potentially_unnormalized_candidates
1263
- && !obligation. predicate . has_infer_types_or_consts ( )
1264
- {
1265
- // HACK: Pick the first trait def candidate for a fully
1266
- // inferred predicate. This is to allow duplicates that
1267
- // differ only in normalization.
1268
- return ;
1250
+ match is_match {
1251
+ Some ( true ) => {
1252
+ candidate_set. push_candidate ( ctor ( data) ) ;
1253
+
1254
+ if potentially_unnormalized_candidates
1255
+ && !obligation. predicate . has_infer_types_or_consts ( )
1256
+ {
1257
+ // HACK: Pick the first trait def candidate for a fully
1258
+ // inferred predicate. This is to allow duplicates that
1259
+ // differ only in normalization.
1260
+ return ;
1261
+ }
1262
+ }
1263
+ Some ( false ) => { }
1264
+ None => {
1265
+ candidate_set. mark_ambiguous ( ) ;
1269
1266
}
1270
1267
}
1271
1268
}
0 commit comments