diff options
| author | Michael Goulet <michael@errs.io> | 2022-02-12 13:30:30 -0800 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2022-02-14 20:01:52 -0800 |
| commit | 879e4f8131b71050b00407befd6f1669389fe9ed (patch) | |
| tree | 2dfeb88034a1045b9c8effa799a209088751a23e | |
| parent | 784c7a6cadf218b518734c4f21690334401ff83a (diff) | |
| download | rust-879e4f8131b71050b00407befd6f1669389fe9ed.tar.gz rust-879e4f8131b71050b00407befd6f1669389fe9ed.zip | |
use an enum in matches_projection_projection
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 37 |
2 files changed, 28 insertions, 16 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a8d15d98eea..584e412b8a2 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -19,6 +19,7 @@ use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::traits::error_reporting::InferCtxtExt as _; +use crate::traits::select::ProjectionMatchesProjection; use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorReported; @@ -1248,7 +1249,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( }); match is_match { - Some(true) => { + ProjectionMatchesProjection::Yes => { candidate_set.push_candidate(ctor(data)); if potentially_unnormalized_candidates @@ -1260,10 +1261,10 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( return; } } - Some(false) => {} - None => { + ProjectionMatchesProjection::Ambiguous => { candidate_set.mark_ambiguous(); } + ProjectionMatchesProjection::No => {} } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4ca60a65485..2f85417a5b6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1508,15 +1508,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) } - /// Return Some(true) if the obligation's predicate type applies to the env_predicate, and - /// Some(false) if it does not. Returns None in the case that the projection type is a GAT, + /// Return `Yes` if the obligation's predicate type applies to the env_predicate, and + /// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT, /// and applying this env_predicate constrains any of the obligation's GAT substitutions. + /// + /// This behavior is a somewhat of a hack to prevent overconstraining inference variables + /// in cases like #91762. pub(super) fn match_projection_projections( &mut self, obligation: &ProjectionTyObligation<'tcx>, env_predicate: PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidates: bool, - ) -> Option<bool> { + ) -> ProjectionMatchesProjection { let mut nested_obligations = Vec::new(); let (infer_predicate, _) = self.infcx.replace_bound_vars_with_fresh_vars( obligation.cause.span, @@ -1553,20 +1556,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if is_match { let generics = self.tcx().generics_of(obligation.predicate.item_def_id); - if !generics.params.is_empty() { - // If any of the obligation's predicate substs shallow-resolve to - // something new, that means that we must have newly inferred something - // about the GAT. We should give up with ambiguity in that case. - if obligation.predicate.substs[generics.parent_count..] + // FIXME(generic-associated-types): Addresses aggressive inference in #92917. + // If this type is a GAT, and of the GAT substs resolve to something new, + // that means that we must have newly inferred something about the GAT. + // We should give up in that case. + if !generics.params.is_empty() + && obligation.predicate.substs[generics.parent_count..] .iter() .any(|&p| p.has_infer_types_or_consts() && self.infcx.shallow_resolve(p) != p) - { - return None; - } + { + ProjectionMatchesProjection::Ambiguous + } else { + ProjectionMatchesProjection::Yes } + } else { + ProjectionMatchesProjection::No } - - Some(is_match) } /////////////////////////////////////////////////////////////////////////// @@ -2766,3 +2771,9 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> { write!(f, "TraitObligationStack({:?})", self.obligation) } } + +pub enum ProjectionMatchesProjection { + Yes, + Ambiguous, + No, +} |
