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.rs40
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>,