Skip to content

Commit 879e4f8

Browse files
use an enum in matches_projection_projection
1 parent 784c7a6 commit 879e4f8

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

compiler/rustc_trait_selection/src/traits/project.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
1919
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
2020
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
2121
use crate::traits::error_reporting::InferCtxtExt as _;
22+
use crate::traits::select::ProjectionMatchesProjection;
2223
use rustc_data_structures::sso::SsoHashSet;
2324
use rustc_data_structures::stack::ensure_sufficient_stack;
2425
use rustc_errors::ErrorReported;
@@ -1248,7 +1249,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
12481249
});
12491250

12501251
match is_match {
1251-
Some(true) => {
1252+
ProjectionMatchesProjection::Yes => {
12521253
candidate_set.push_candidate(ctor(data));
12531254

12541255
if potentially_unnormalized_candidates
@@ -1260,10 +1261,10 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
12601261
return;
12611262
}
12621263
}
1263-
Some(false) => {}
1264-
None => {
1264+
ProjectionMatchesProjection::Ambiguous => {
12651265
candidate_set.mark_ambiguous();
12661266
}
1267+
ProjectionMatchesProjection::No => {}
12671268
}
12681269
}
12691270
}

compiler/rustc_trait_selection/src/traits/select/mod.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)