Skip to content

Commit 601568f

Browse files
committed
Move inference table creation to Solver and store free vars as GenericArgs
1 parent 66500fe commit 601568f

File tree

2 files changed

+59
-38
lines changed

2 files changed

+59
-38
lines changed

chalk-solve/src/recursive.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use self::fulfill::{Fulfill, RecursiveInferenceTable};
66
use self::search_graph::{DepthFirstNumber, SearchGraph};
77
use self::stack::{Stack, StackDepth};
88
use crate::clauses::program_clauses_for_goal;
9-
use crate::infer::{InferenceTable, ParameterEnaVariable};
9+
use crate::infer::{InferenceTable, ParameterEnaVariableExt};
1010
use crate::solve::truncate;
1111
use crate::{Guidance, RustIrDatabase, Solution};
1212
use chalk_ir::fold::Fold;
@@ -17,7 +17,8 @@ use chalk_ir::{debug, debug_heading, info, info_heading};
1717
use chalk_ir::{
1818
Binders, Canonical, ClausePriority, ConstrainedSubst, Constraint, DomainGoal, Environment,
1919
Fallible, Floundered, GenericArg, Goal, GoalData, InEnvironment, NoSolution, ProgramClause,
20-
ProgramClauseData, ProgramClauseImplication, UCanonical, UniverseMap, VariableKinds,
20+
ProgramClauseData, ProgramClauseImplication, Substitution, UCanonical, UniverseMap,
21+
VariableKinds,
2122
};
2223
use rustc_hash::FxHashMap;
2324
use std::fmt::Debug;
@@ -63,13 +64,18 @@ impl<I: Interner> RecursiveInferenceTable<I> for RecursiveInferenceTableImpl<I>
6364
&mut self,
6465
interner: &I,
6566
value: &T,
66-
) -> (Canonical<T::Result>, Vec<ParameterEnaVariable<I>>)
67+
) -> (Canonical<T::Result>, Vec<GenericArg<I>>)
6768
where
6869
T: Fold<I>,
6970
T::Result: HasInterner<Interner = I>,
7071
{
7172
let res = self.infer.canonicalize(interner, value);
72-
(res.quantified, res.free_vars)
73+
let free_vars = res
74+
.free_vars
75+
.into_iter()
76+
.map(|free_var| free_var.to_generic_arg(interner))
77+
.collect();
78+
(res.quantified, free_vars)
7379
}
7480

7581
fn u_canonicalize<T>(
@@ -184,6 +190,25 @@ impl<I: Interner> RecursiveContext<I> {
184190
}
185191

186192
impl<'me, I: Interner> Solver<'me, I> {
193+
pub(crate) fn new_inference_table<
194+
T: Fold<I, I, Result = T> + HasInterner<Interner = I> + Clone,
195+
>(
196+
&self,
197+
ucanonical_goal: &UCanonical<InEnvironment<T>>,
198+
) -> (
199+
RecursiveInferenceTableImpl<I>,
200+
Substitution<I>,
201+
InEnvironment<T::Result>,
202+
) {
203+
let (infer, subst, canonical_goal) = InferenceTable::from_canonical(
204+
self.program.interner(),
205+
ucanonical_goal.universes,
206+
&ucanonical_goal.canonical,
207+
);
208+
let infer = crate::recursive::RecursiveInferenceTableImpl { infer };
209+
(infer, subst, canonical_goal)
210+
}
211+
187212
/// Solves a canonical goal. The substitution returned in the
188213
/// solution will be for the fully decomposed goal. For example, given the
189214
/// program
@@ -440,7 +465,8 @@ impl<'me, I: Interner> Solver<'me, I> {
440465
minimums: &mut Minimums,
441466
) -> (Fallible<Solution<I>>, ClausePriority) {
442467
debug_heading!("solve_via_simplification({:?})", canonical_goal);
443-
match Fulfill::new_with_simplification(self, canonical_goal) {
468+
let (infer, subst, goal) = self.new_inference_table(canonical_goal);
469+
match Fulfill::new_with_simplification(self, infer, subst, goal) {
444470
Ok(fulfill) => (fulfill.solve(minimums), ClausePriority::High),
445471
Err(e) => (Err(e), ClausePriority::High),
446472
}
@@ -515,7 +541,8 @@ impl<'me, I: Interner> Solver<'me, I> {
515541
clause
516542
);
517543

518-
match Fulfill::new_with_clause(self, canonical_goal, clause) {
544+
let (infer, subst, goal) = self.new_inference_table(canonical_goal);
545+
match Fulfill::new_with_clause(self, infer, subst, goal, clause) {
519546
Ok(fulfill) => (fulfill.solve(minimums), clause.skip_binders().priority),
520547
Err(e) => (Err(e), ClausePriority::High),
521548
}

chalk-solve/src/recursive/fulfill.rs

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::infer::{InferenceTable, ParameterEnaVariable, ParameterEnaVariableExt};
2-
use crate::recursive::{Minimums, RecursiveInferenceTableImpl, Solver};
1+
use crate::recursive::{Minimums, Solver};
32
use crate::solve::{Guidance, Solution};
43
use chalk_ir::cast::Cast;
54
use chalk_ir::fold::Fold;
@@ -9,8 +8,8 @@ use chalk_ir::zip::Zip;
98
use chalk_ir::{debug, debug_heading};
109
use chalk_ir::{
1110
Binders, Canonical, ConstrainedSubst, Constraint, DomainGoal, Environment, EqGoal, Fallible,
12-
Goal, GoalData, InEnvironment, LifetimeOutlives, NoSolution, ProgramClauseImplication,
13-
QuantifierKind, Substitution, UCanonical, UniverseMap, WhereClause,
11+
GenericArg, Goal, GoalData, InEnvironment, LifetimeOutlives, NoSolution,
12+
ProgramClauseImplication, QuantifierKind, Substitution, UCanonical, UniverseMap, WhereClause,
1413
};
1514
use rustc_hash::FxHashSet;
1615
use std::fmt::Debug;
@@ -46,7 +45,7 @@ enum Obligation<I: Interner> {
4645
/// so that we can update inference state accordingly.
4746
#[derive(Clone, Debug)]
4847
struct PositiveSolution<I: Interner> {
49-
free_vars: Vec<ParameterEnaVariable<I>>,
48+
free_vars: Vec<GenericArg<I>>,
5049
universes: UniverseMap,
5150
solution: Solution<I>,
5251
}
@@ -79,7 +78,7 @@ pub(crate) trait RecursiveInferenceTable<I: Interner> {
7978
&mut self,
8079
interner: &I,
8180
value: &T,
82-
) -> (Canonical<T::Result>, Vec<ParameterEnaVariable<I>>)
81+
) -> (Canonical<T::Result>, Vec<GenericArg<I>>)
8382
where
8483
T: Fold<I>,
8584
T::Result: HasInterner<Interner = I>;
@@ -149,18 +148,15 @@ pub(crate) struct Fulfill<'s, 'db, I: Interner, Infer: RecursiveInferenceTable<I
149148
cannot_prove: bool,
150149
}
151150

152-
impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I, RecursiveInferenceTableImpl<I>> {
153-
fn new<T: Fold<I, I, Result = T> + HasInterner<Interner = I> + Clone>(
151+
impl<'s, 'db, I: Interner, Infer: RecursiveInferenceTable<I>> Fulfill<'s, 'db, I, Infer> {
152+
pub(crate) fn new_with_clause(
154153
solver: &'s mut Solver<'db, I>,
155-
ucanonical_goal: &UCanonical<InEnvironment<T>>,
156-
) -> (Self, InEnvironment<T::Result>) {
157-
let (infer, subst, canonical_goal) = InferenceTable::from_canonical(
158-
solver.program.interner(),
159-
ucanonical_goal.universes,
160-
&ucanonical_goal.canonical,
161-
);
162-
let infer = crate::recursive::RecursiveInferenceTableImpl { infer };
163-
let fulfill = Fulfill {
154+
infer: Infer,
155+
subst: Substitution<I>,
156+
canonical_goal: InEnvironment<DomainGoal<I>>,
157+
clause: &Binders<ProgramClauseImplication<I>>,
158+
) -> Fallible<Self> {
159+
let mut fulfill = Fulfill {
164160
solver,
165161
infer,
166162
subst,
@@ -169,16 +165,6 @@ impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I, RecursiveInferenceTableImpl<I>> {
169165
cannot_prove: false,
170166
};
171167

172-
(fulfill, canonical_goal)
173-
}
174-
175-
pub(crate) fn new_with_clause(
176-
solver: &'s mut Solver<'db, I>,
177-
ucanonical_goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
178-
clause: &Binders<ProgramClauseImplication<I>>,
179-
) -> Fallible<Self> {
180-
let (mut fulfill, canonical_goal) = Fulfill::new(solver, ucanonical_goal);
181-
182168
let ProgramClauseImplication {
183169
consequence,
184170
conditions,
@@ -209,9 +195,18 @@ impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I, RecursiveInferenceTableImpl<I>> {
209195

210196
pub(crate) fn new_with_simplification(
211197
solver: &'s mut Solver<'db, I>,
212-
ucanonical_goal: &UCanonical<InEnvironment<Goal<I>>>,
198+
infer: Infer,
199+
subst: Substitution<I>,
200+
canonical_goal: InEnvironment<Goal<I>>,
213201
) -> Fallible<Self> {
214-
let (mut fulfill, canonical_goal) = Fulfill::new(solver, ucanonical_goal);
202+
let mut fulfill = Fulfill {
203+
solver,
204+
infer,
205+
subst,
206+
obligations: vec![],
207+
constraints: FxHashSet::default(),
208+
cannot_prove: false,
209+
};
215210

216211
if let Err(e) = fulfill.push_goal(&canonical_goal.environment, canonical_goal.goal.clone())
217212
{
@@ -383,7 +378,7 @@ impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I, RecursiveInferenceTableImpl<I>> {
383378
/// be mapped into our variables with `free_vars`.
384379
fn apply_solution(
385380
&mut self,
386-
free_vars: Vec<ParameterEnaVariable<I>>,
381+
free_vars: Vec<GenericArg<I>>,
387382
universes: UniverseMap,
388383
subst: Canonical<ConstrainedSubst<I>>,
389384
) {
@@ -406,8 +401,7 @@ impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I, RecursiveInferenceTableImpl<I>> {
406401

407402
for (i, free_var) in free_vars.into_iter().enumerate() {
408403
let subst_value = subst.at(self.interner(), i);
409-
let free_value = free_var.to_generic_arg(self.interner());
410-
self.unify(empty_env, &free_value, subst_value)
404+
self.unify(empty_env, &free_var, subst_value)
411405
.unwrap_or_else(|err| {
412406
panic!(
413407
"apply_solution failed with free_var={:?}, subst_value={:?}: {:?}",

0 commit comments

Comments
 (0)