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 | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs index 51cf5be137..a6377243ed 100644 --- a/crates/hir-ty/src/traits.rs +++ b/crates/hir-ty/src/traits.rs @@ -1,6 +1,7 @@ //! Trait solving using Chalk. use core::fmt; +use std::hash::Hash; use chalk_ir::{DebruijnIndex, GoalData, fold::TypeFoldable}; use chalk_solve::rust_ir; @@ -25,7 +26,7 @@ use crate::{ db::HirDatabase, infer::unify::InferenceTable, next_solver::{ - DbInterner, GenericArg, SolverContext, Span, + DbInterner, GenericArg, Predicate, SolverContext, Span, infer::{DbInternerInferExt, InferCtxt}, mapping::{ChalkToNextSolver, convert_canonical_args_for_result}, util::mini_canonicalize, @@ -231,7 +232,6 @@ impl NextTraitSolveResult { } } -/// Solve a trait goal using Chalk. pub fn next_trait_solve( db: &dyn HirDatabase, krate: Crate, @@ -290,6 +290,42 @@ pub fn next_trait_solve( } } +pub fn next_trait_solve_canonical_in_ctxt<'db>( + infer_ctxt: &InferCtxt<'db>, + goal: crate::next_solver::Canonical<'db, crate::next_solver::Goal<'db, Predicate<'db>>>, +) -> NextTraitSolveResult { + let context = SolverContext(infer_ctxt.clone()); + + tracing::info!(?goal); + + let (goal, var_values) = context.instantiate_canonical(&goal); + tracing::info!(?var_values); + + let res = context.evaluate_root_goal(goal, Span::dummy(), None); + + let vars = + var_values.var_values.iter().map(|g| context.0.resolve_vars_if_possible(g)).collect(); + let canonical_var_values = mini_canonicalize(context, vars); + + let res = res.map(|r| (r.has_changed, r.certainty, canonical_var_values)); + + tracing::debug!("solve_nextsolver({:?}) => {:?}", goal, res); + + match res { + Err(_) => NextTraitSolveResult::NoSolution, + Ok((_, Certainty::Yes, args)) => NextTraitSolveResult::Certain( + convert_canonical_args_for_result(infer_ctxt.interner, args), + ), + Ok((_, Certainty::Maybe(_), args)) => { + let subst = convert_canonical_args_for_result(infer_ctxt.interner, args); + NextTraitSolveResult::Uncertain(chalk_ir::Canonical { + binders: subst.binders, + value: subst.value.subst, + }) + } + } +} + /// Solve a trait goal using Chalk. pub fn next_trait_solve_in_ctxt<'db, 'a>( infer_ctxt: &'a InferCtxt<'db>, |