Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/infer/traits.rs')
| -rw-r--r-- | crates/hir-ty/src/next_solver/infer/traits.rs | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/crates/hir-ty/src/next_solver/infer/traits.rs b/crates/hir-ty/src/next_solver/infer/traits.rs index 68aa12d7bb..bc905c2e0b 100644 --- a/crates/hir-ty/src/next_solver/infer/traits.rs +++ b/crates/hir-ty/src/next_solver/infer/traits.rs @@ -7,16 +7,19 @@ use std::{ hash::{Hash, Hasher}, }; +use hir_def::TraitId; +use macros::{TypeFoldable, TypeVisitable}; use rustc_type_ir::elaborate::Elaboratable; use rustc_type_ir::{ PredicatePolarity, Upcast, solve::{Certainty, NoSolution}, }; use rustc_type_ir::{TypeFoldable, TypeVisitable}; +use tracing::debug; use crate::next_solver::{ Binder, Clause, DbInterner, Goal, ParamEnv, PolyTraitPredicate, Predicate, SolverDefId, Span, - TraitPredicate, Ty, + TraitPredicate, TraitRef, Ty, }; use super::InferCtxt; @@ -63,8 +66,10 @@ impl ObligationCause { /// either identifying an `impl` (e.g., `impl Eq for i32`) that /// satisfies the obligation, or else finding a bound that is in /// scope. The eventual result is usually a `Selection` (defined below). -#[derive(Clone, Debug)] +#[derive(Clone, Debug, TypeVisitable, TypeFoldable)] pub struct Obligation<'db, T> { + #[type_foldable(identity)] + #[type_visitable(ignore)] /// The reason we have to prove this thing. pub cause: ObligationCause, @@ -115,39 +120,6 @@ impl<'db> Elaboratable<DbInterner<'db>> for PredicateObligation<'db> { } } -impl<'db, T: TypeVisitable<DbInterner<'db>>> TypeVisitable<DbInterner<'db>> for Obligation<'db, T> { - fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>( - &self, - visitor: &mut V, - ) -> V::Result { - rustc_ast_ir::try_visit!(self.param_env.visit_with(visitor)); - self.predicate.visit_with(visitor) - } -} - -impl<'db, T: TypeFoldable<DbInterner<'db>>> TypeFoldable<DbInterner<'db>> for Obligation<'db, T> { - fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>( - self, - folder: &mut F, - ) -> Result<Self, F::Error> { - Ok(Obligation { - cause: self.cause.clone(), - param_env: self.param_env.try_fold_with(folder)?, - predicate: self.predicate.try_fold_with(folder)?, - recursion_depth: self.recursion_depth, - }) - } - - fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self { - Obligation { - cause: self.cause.clone(), - param_env: self.param_env.fold_with(folder), - predicate: self.predicate.fold_with(folder), - recursion_depth: self.recursion_depth, - } - } -} - impl<'db, T: Copy> Obligation<'db, T> { pub fn as_goal(&self) -> Goal<'db, T> { Goal { param_env: self.param_env, predicate: self.predicate } @@ -237,3 +209,35 @@ impl<'db, O> Obligation<'db, O> { Obligation::with_depth(tcx, self.cause.clone(), self.recursion_depth, self.param_env, value) } } + +/// Determines whether the type `ty` is known to meet `bound` and +/// returns true if so. Returns false if `ty` either does not meet +/// `bound` or is not known to meet bound (note that this is +/// conservative towards *no impl*, which is the opposite of the +/// `evaluate` methods). +pub fn type_known_to_meet_bound_modulo_regions<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ty: Ty<'tcx>, + def_id: TraitId, +) -> bool { + let trait_ref = TraitRef::new(infcx.interner, def_id.into(), [ty]); + pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref) +} + +/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist? +/// +/// Ping me on zulip if you want to use this method and need help with finding +/// an appropriate replacement. +fn pred_known_to_hold_modulo_regions<'db>( + infcx: &InferCtxt<'db>, + param_env: ParamEnv<'db>, + pred: impl Upcast<DbInterner<'db>, Predicate<'db>>, +) -> bool { + let obligation = Obligation::new(infcx.interner, ObligationCause::dummy(), param_env, pred); + + let result = infcx.evaluate_obligation(&obligation); + debug!(?result); + + result.must_apply_modulo_regions() +} |