Skip to content

Commit f53558e

Browse files
committed
A little bit of refactoring
1 parent 656be2d commit f53558e

File tree

2 files changed

+98
-85
lines changed

2 files changed

+98
-85
lines changed

chalk-solve/src/recursive.rs

Lines changed: 44 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ pub(crate) struct RecursiveContext<I: Interner> {
2626
caching_enabled: bool,
2727
}
2828

29+
trait Context<I: Interner> {
30+
fn instantiate_binders_universally(&mut self, interner: &I, arg: &Binders<Goal<I>>) -> Goal<I>;
31+
32+
fn instantiate_binders_existentially(
33+
&mut self,
34+
interner: &I,
35+
arg: &Binders<Goal<I>>,
36+
) -> Goal<I>;
37+
}
38+
2939
/// A Solver is the basic context in which you can propose goals for a given
3040
/// program. **All questions posed to the solver are in canonical, closed form,
3141
/// so that each question is answered with effectively a "clean slate"**. This
@@ -341,10 +351,10 @@ impl<'me, I: Interner> Solver<'me, I> {
341351
minimums: &mut Minimums,
342352
) -> (Fallible<Solution<I>>, ClausePriority) {
343353
debug_heading!("solve_via_simplification({:?})", canonical_goal);
344-
let (mut fulfill, subst, goal) = Fulfill::new(self, canonical_goal);
345-
if let Err(e) = fulfill.push_goal(&goal.environment, goal.goal) {
346-
return (Err(e), ClausePriority::High);
347-
}
354+
let (fulfill, subst) = match Fulfill::new_with_simplification(self, canonical_goal) {
355+
Ok(r) => r,
356+
Err(e) => return (Err(e), ClausePriority::High),
357+
};
348358
(fulfill.solve(subst, minimums), ClausePriority::High)
349359
}
350360

@@ -369,52 +379,34 @@ impl<'me, I: Interner> Solver<'me, I> {
369379
return (Ok(Solution::Ambig(Guidance::Unknown)), ClausePriority::High);
370380
}
371381

372-
match program_clause.data(self.program.interner()) {
373-
ProgramClauseData::Implies(implication) => {
374-
let res = self.solve_via_implication(
375-
canonical_goal,
376-
&Binders::new(
377-
VariableKinds::from(self.program.interner(), vec![]),
378-
implication.clone(),
379-
),
380-
minimums,
381-
);
382-
if let (Ok(solution), priority) = res {
383-
debug!("ok: solution={:?} prio={:?}", solution, priority);
384-
cur_solution = Some(match cur_solution {
385-
None => (solution, priority),
386-
Some((cur, cur_priority)) => combine_with_priorities(
387-
self.program.interner(),
388-
&canonical_goal.canonical.value.goal,
389-
cur,
390-
cur_priority,
391-
solution,
392-
priority,
393-
),
394-
});
395-
} else {
396-
debug!("error");
397-
}
398-
}
382+
let res = match program_clause.data(self.program.interner()) {
383+
ProgramClauseData::Implies(implication) => self.solve_via_implication(
384+
canonical_goal,
385+
&Binders::new(
386+
VariableKinds::from(self.program.interner(), vec![]),
387+
implication.clone(),
388+
),
389+
minimums,
390+
),
399391
ProgramClauseData::ForAll(implication) => {
400-
let res = self.solve_via_implication(canonical_goal, implication, minimums);
401-
if let (Ok(solution), priority) = res {
402-
debug!("ok: solution={:?} prio={:?}", solution, priority);
403-
cur_solution = Some(match cur_solution {
404-
None => (solution, priority),
405-
Some((cur, cur_priority)) => combine_with_priorities(
406-
self.program.interner(),
407-
&canonical_goal.canonical.value.goal,
408-
cur,
409-
cur_priority,
410-
solution,
411-
priority,
412-
),
413-
});
414-
} else {
415-
debug!("error");
416-
}
392+
self.solve_via_implication(canonical_goal, implication, minimums)
417393
}
394+
};
395+
if let (Ok(solution), priority) = res {
396+
debug!("ok: solution={:?} prio={:?}", solution, priority);
397+
cur_solution = Some(match cur_solution {
398+
None => (solution, priority),
399+
Some((cur, cur_priority)) => combine_with_priorities(
400+
self.program.interner(),
401+
&canonical_goal.canonical.value.goal,
402+
cur,
403+
cur_priority,
404+
solution,
405+
priority,
406+
),
407+
});
408+
} else {
409+
debug!("error");
418410
}
419411
}
420412
cur_solution.map_or((Err(NoSolution), ClausePriority::High), |(s, p)| (Ok(s), p))
@@ -434,28 +426,11 @@ impl<'me, I: Interner> Solver<'me, I> {
434426
canonical_goal,
435427
clause
436428
);
437-
let interner = self.program.interner();
438-
let (mut fulfill, subst, goal) = Fulfill::new(self, canonical_goal);
439-
let ProgramClauseImplication {
440-
consequence,
441-
conditions,
442-
priority: _,
443-
} = fulfill.instantiate_binders_existentially(clause);
444-
445-
debug!("the subst is {:?}", subst);
446-
447-
if let Err(e) = fulfill.unify(&goal.environment, &goal.goal, &consequence) {
448-
return (Err(e), ClausePriority::High);
449-
}
450-
451-
// if so, toss in all of its premises
452-
for condition in conditions.as_slice(interner) {
453-
if let Err(e) = fulfill.push_goal(&goal.environment, condition.clone()) {
454-
return (Err(e), ClausePriority::High);
455-
}
456-
}
429+
let (fulfill, subst) = match Fulfill::new_with_clause(self, canonical_goal, clause) {
430+
Ok(r) => r,
431+
Err(e) => return (Err(e), ClausePriority::High),
432+
};
457433

458-
// and then try to solve
459434
(
460435
fulfill.solve(subst, minimums),
461436
clause.skip_binders().priority,

chalk-solve/src/recursive/fulfill.rs

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::infer::{
2-
canonicalize::Canonicalized, instantiate::IntoBindersAndValue, ucanonicalize::UCanonicalized,
3-
unify::UnificationResult, InferenceTable, ParameterEnaVariable, ParameterEnaVariableExt,
2+
canonicalize::Canonicalized, ucanonicalize::UCanonicalized, unify::UnificationResult,
3+
InferenceTable, ParameterEnaVariable, ParameterEnaVariableExt,
44
};
55
use crate::recursive::{Minimums, Solver};
66
use crate::solve::{truncate, Guidance, Solution};
@@ -10,9 +10,9 @@ use chalk_ir::interner::{HasInterner, Interner};
1010
use chalk_ir::zip::Zip;
1111
use chalk_ir::{debug, debug_heading};
1212
use chalk_ir::{
13-
Canonical, ConstrainedSubst, Constraint, DomainGoal, Environment, EqGoal, Fallible, Goal,
14-
GoalData, InEnvironment, LifetimeOutlives, NoSolution, QuantifierKind, Substitution,
15-
UCanonical, UniverseMap, WhereClause,
13+
Binders, Canonical, ConstrainedSubst, Constraint, DomainGoal, Environment, EqGoal, Fallible,
14+
Goal, GoalData, InEnvironment, LifetimeOutlives, NoSolution, ProgramClauseImplication,
15+
QuantifierKind, Substitution, UCanonical, UniverseMap, WhereClause,
1616
};
1717
use rustc_hash::FxHashSet;
1818
use std::fmt::Debug;
@@ -88,7 +88,7 @@ pub(crate) struct Fulfill<'s, 'db, I: Interner> {
8888
}
8989

9090
impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I> {
91-
pub(crate) fn new<T: Fold<I, I, Result = T> + HasInterner<Interner = I> + Clone>(
91+
fn new<T: Fold<I, I, Result = T> + HasInterner<Interner = I> + Clone>(
9292
solver: &'s mut Solver<'db, I>,
9393
ucanonical_goal: &UCanonical<InEnvironment<T>>,
9494
) -> (Self, Substitution<I>, InEnvironment<T::Result>) {
@@ -104,19 +104,57 @@ impl<'s, 'db, I: Interner> Fulfill<'s, 'db, I> {
104104
constraints: FxHashSet::default(),
105105
cannot_prove: false,
106106
};
107+
107108
(fulfill, subst, canonical_goal)
108109
}
109110

110-
/// Wraps `InferenceTable::instantiate_in`
111-
pub(crate) fn instantiate_binders_existentially<T>(
112-
&mut self,
113-
arg: impl IntoBindersAndValue<'s, I, Value = T>,
114-
) -> T::Result
115-
where
116-
T: Fold<I, I>,
117-
{
118-
self.infer
119-
.instantiate_binders_existentially(self.solver.program.interner(), arg)
111+
pub(crate) fn new_with_clause(
112+
solver: &'s mut Solver<'db, I>,
113+
ucanonical_goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
114+
clause: &Binders<ProgramClauseImplication<I>>,
115+
) -> Fallible<(Self, Substitution<I>)> {
116+
let (mut fulfill, subst, canonical_goal) = Fulfill::new(solver, ucanonical_goal);
117+
118+
let ProgramClauseImplication {
119+
consequence,
120+
conditions,
121+
priority: _,
122+
} = fulfill
123+
.infer
124+
.instantiate_binders_existentially(fulfill.solver.program.interner(), clause);
125+
126+
debug!("the subst is {:?}", subst);
127+
128+
if let Err(e) = fulfill.unify(
129+
&canonical_goal.environment,
130+
&canonical_goal.goal,
131+
&consequence,
132+
) {
133+
return Err(e);
134+
}
135+
136+
// if so, toss in all of its premises
137+
for condition in conditions.as_slice(fulfill.solver.program.interner()) {
138+
if let Err(e) = fulfill.push_goal(&canonical_goal.environment, condition.clone()) {
139+
return Err(e);
140+
}
141+
}
142+
143+
Ok((fulfill, subst))
144+
}
145+
146+
pub(crate) fn new_with_simplification(
147+
solver: &'s mut Solver<'db, I>,
148+
ucanonical_goal: &UCanonical<InEnvironment<Goal<I>>>,
149+
) -> Fallible<(Self, Substitution<I>)> {
150+
let (mut fulfill, subst, canonical_goal) = Fulfill::new(solver, ucanonical_goal);
151+
152+
if let Err(e) = fulfill.push_goal(&canonical_goal.environment, canonical_goal.goal.clone())
153+
{
154+
return Err(e);
155+
}
156+
157+
Ok((fulfill, subst))
120158
}
121159

122160
fn push_obligation(&mut self, obligation: Obligation<I>) {

0 commit comments

Comments
 (0)