]>
git.proxmox.com Git - rustc.git/blob - vendor/chalk-engine/src/simplify.rs
1 use fallible
::Fallible
;
2 use {ExClause, Literal}
;
5 use context
::prelude
::*;
7 impl<C
: Context
, CO
: ContextOps
<C
>> Forest
<C
, CO
> {
8 /// Simplifies an HH goal into a series of positive domain goals
9 /// and negative HH goals. This operation may fail if the HH goal
10 /// includes unifications that cannot be completed.
11 pub(super) fn simplify_hh_goal
<I
: Context
>(
12 infer
: &mut dyn InferenceTable
<C
, I
>,
13 subst
: I
::Substitution
,
14 initial_environment
: &I
::Environment
,
15 initial_hh_goal
: HhGoal
<I
>,
16 ) -> Fallible
<ExClause
<I
>> {
17 let mut ex_clause
= ExClause
{
19 delayed_literals
: vec
![],
24 // A stack of higher-level goals to process.
25 let mut pending_goals
= vec
![(initial_environment
.clone(), initial_hh_goal
)];
27 while let Some((environment
, hh_goal
)) = pending_goals
.pop() {
29 HhGoal
::ForAll(subgoal
) => {
30 let subgoal
= infer
.instantiate_binders_universally(&subgoal
);
31 pending_goals
.push((environment
, infer
.into_hh_goal(subgoal
)));
33 HhGoal
::Exists(subgoal
) => {
34 let subgoal
= infer
.instantiate_binders_existentially(&subgoal
);
35 pending_goals
.push((environment
, infer
.into_hh_goal(subgoal
)))
37 HhGoal
::Implies(wc
, subgoal
) => {
38 let new_environment
= infer
.add_clauses(&environment
, wc
);
39 pending_goals
.push((new_environment
, infer
.into_hh_goal(subgoal
)));
41 HhGoal
::And(subgoal1
, subgoal2
) => {
42 pending_goals
.push((environment
.clone(), infer
.into_hh_goal(subgoal1
)));
43 pending_goals
.push((environment
, infer
.into_hh_goal(subgoal2
)));
45 HhGoal
::Not(subgoal
) => {
48 .push(Literal
::Negative(I
::goal_in_environment(&environment
, subgoal
)));
50 HhGoal
::Unify(variance
, a
, b
) => {
51 let result
= infer
.unify_parameters(&environment
, variance
, &a
, &b
)?
;
52 infer
.into_ex_clause(result
, &mut ex_clause
)
54 HhGoal
::DomainGoal(domain_goal
) => {
57 .push(Literal
::Positive(I
::goal_in_environment(
59 infer
.into_goal(domain_goal
),
62 HhGoal
::CannotProve
=> {
63 // You can think of `CannotProve` as a special
64 // goal that is only provable if `not {
65 // CannotProve }`. Trying to prove this, of
66 // course, will always create a negative cycle and
67 // hence a delayed literal that cannot be
69 let goal
= infer
.cannot_prove();
72 .push(Literal
::Negative(I
::goal_in_environment(&environment
, goal
)));