Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/traits.rs')
| -rw-r--r-- | crates/hir-ty/src/traits.rs | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs index a8e42b9a91..446226c355 100644 --- a/crates/hir-ty/src/traits.rs +++ b/crates/hir-ty/src/traits.rs @@ -31,6 +31,7 @@ use crate::{ DbInterner, GenericArgs, ParamEnv, StoredClauses, Ty, TyKind, infer::{ DbInternerInferExt, InferCtxt, + select::EvaluationResult, traits::{Obligation, ObligationCause}, }, obligation_ctxt::ObligationCtxt, @@ -205,19 +206,39 @@ pub fn where_predicate_must_hold<'db>( }; } - for clause in clauses { - let obligation = Obligation::new( - interner, - ObligationCause::dummy(), - env.param_env, - clause.as_predicate(), - ); - if !infcx.predicate_must_hold_modulo_regions(&obligation) { - return WherePredicateEvaluation::NotProven; + let result = infcx.probe(|snapshot| { + let mut ocx = ObligationCtxt::new(&infcx); + for clause in clauses { + let obligation = Obligation::new( + interner, + ObligationCause::dummy(), + env.param_env, + clause.as_predicate(), + ); + ocx.register_obligation(obligation); } - } - WherePredicateEvaluation::Holds + let mut result = EvaluationResult::EvaluatedToOk; + for error in ocx.evaluate_obligations_error_on_ambiguity() { + if error.is_true_error() { + return EvaluationResult::EvaluatedToErr; + } + result = result.max(EvaluationResult::EvaluatedToAmbig); + } + if infcx.opaque_types_added_in_snapshot(snapshot) { + result.max(EvaluationResult::EvaluatedToOkModuloOpaqueTypes) + } else if infcx.region_constraints_added_in_snapshot(snapshot) { + result.max(EvaluationResult::EvaluatedToOkModuloRegions) + } else { + result + } + }); + + if result.must_apply_modulo_regions() { + WherePredicateEvaluation::Holds + } else { + WherePredicateEvaluation::NotProven + } } pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id: ImplId) -> bool { |