Skip to content

Commit 8d371a2

Browse files
committed
alias eq goals
1 parent e361b5c commit 8d371a2

File tree

3 files changed

+65
-62
lines changed

3 files changed

+65
-62
lines changed

chalk-solve/src/clauses/builder.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ impl<'me, I: Interner> ClauseBuilder<'me, I> {
8080
let clause = if self.binders.len() == 0 {
8181
ProgramClauseData::Implies(clause).intern(interner)
8282
} else {
83-
ProgramClauseData::ForAll(Binders::new(ParameterKinds::from(interner, self.binders.clone()), clause)).intern(interner)
83+
ProgramClauseData::ForAll(Binders::new(
84+
ParameterKinds::from(interner, self.binders.clone()),
85+
clause,
86+
))
87+
.intern(interner)
8488
};
8589

8690
self.clauses.push(syn_eq_lower(interner, &clause));

chalk-solve/src/clauses/program_clauses.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
735735

736736
// add new type parameter U
737737
builder.push_bound_ty(|builder, ty| {
738+
let alias = AliasTy::Projection(projection.clone());
738739
// `Normalize(<T as Foo>::Assoc -> U)`
739740
let normalize = Normalize {
740741
alias: AliasTy::Projection(projection.clone()),
@@ -743,8 +744,8 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
743744

744745
// `AliasEq(<T as Foo>::Assoc = U)`
745746
let projection_eq = AliasEq {
746-
alias: AliasTy::Projection(projection),
747-
ty,
747+
alias: alias.clone(),
748+
ty: ty.clone(),
748749
};
749750

750751
// Projection equality rule from above.
@@ -753,7 +754,7 @@ impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
753754
// AliasEq(<T as Foo>::Assoc = U) :-
754755
// Normalize(<T as Foo>::Assoc -> U).
755756
// }
756-
builder.push_clause(projection_eq, Some(normalize));
757+
builder.push_clause(projection_eq.clone(), Some(normalize));
757758
});
758759
});
759760
}

chalk-solve/src/clauses/syntactic_eq.rs

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,34 @@ use std::{iter, mem::replace};
22

33
use chalk_engine::fallible::Fallible;
44
use chalk_ir::{
5+
cast::Cast,
56
fold::{shift::Shift, Fold, Folder, SuperFold},
67
interner::Interner,
7-
Binders, BoundVar, DebruijnIndex, EqGoal, Goal, GoalData, Goals, Parameter, ProgramClause,
8-
ProgramClauseData, ProgramClauseImplication, QuantifierKind, Ty, TyData, ParameterKind, ApplicationTy, TypeName,
9-
ParameterKinds,
8+
AliasEq, Binders, BoundVar, DebruijnIndex, Goal, GoalData, Goals, ParameterKind,
9+
ParameterKinds, ProgramClause, ProgramClauseData, ProgramClauseImplication, QuantifierKind, Ty,
10+
TyData,
1011
};
1112

1213
pub fn syn_eq_lower<I: Interner>(interner: &I, clause: &ProgramClause<I>) -> ProgramClause<I> {
1314
let mut folder = SynEqFolder {
1415
interner,
1516
new_params: vec![],
17+
new_goals: vec![],
1618
binders_len: 0,
1719
};
1820

19-
clause.fold_with(&mut folder, DebruijnIndex::INNERMOST).unwrap()
21+
clause
22+
.fold_with(&mut folder, DebruijnIndex::INNERMOST)
23+
.unwrap()
2024
}
2125

2226
struct SynEqFolder<'i, I: Interner> {
2327
interner: &'i I,
24-
new_params: Vec<Parameter<I>>,
28+
new_params: Vec<ParameterKind<()>>,
29+
new_goals: Vec<Goal<I>>,
2530
binders_len: usize,
2631
}
2732

28-
impl<'i, I: Interner> SynEqFolder<'i, I>
29-
where
30-
I: 'i,
31-
{
32-
fn to_eq_goals(&self, new_params: Vec<Parameter<I>>, old_len: usize) -> impl Iterator<Item = Goal<I>> + 'i {
33-
let interner = self.interner;
34-
new_params.into_iter().enumerate().map(move |(i, p)| {
35-
let var = BoundVar {
36-
debruijn: DebruijnIndex::INNERMOST,
37-
index: i + old_len,
38-
};
39-
GoalData::EqGoal(EqGoal {
40-
a: p.replace_bound(var, interner),
41-
b: p,
42-
})
43-
.intern(interner)
44-
})
45-
}
46-
}
47-
4833
impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
4934
fn as_dyn(&mut self) -> &mut dyn Folder<'i, I> {
5035
self
@@ -54,14 +39,22 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
5439
let interner = self.interner;
5540
let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, self.binders_len);
5641

42+
let new_ty = TyData::BoundVar(bound_var).intern(interner);
5743
let folded = ty.super_fold_with(self, outer_binder)?;
5844
match folded.data(interner) {
59-
TyData::Apply(ApplicationTy { name: TypeName::AssociatedType(_), .. }) => {
60-
self.new_params.push(ParameterKind::Ty(ty.clone()).intern(interner));
45+
TyData::Alias(alias) => {
46+
self.new_params.push(ParameterKind::Ty(()));
47+
self.new_goals.push(
48+
AliasEq {
49+
alias: alias.clone(),
50+
ty: new_ty.clone(),
51+
}
52+
.cast(interner),
53+
);
6154
self.binders_len += 1;
62-
Ok(TyData::BoundVar(bound_var).intern(interner))
55+
Ok(new_ty)
6356
}
64-
_ => ty.super_fold_with(self, outer_binder),
57+
_ => Ok(folded),
6558
}
6659
}
6760

@@ -73,42 +66,46 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
7366
let interner = self.interner;
7467

7568
let ((binders, implication), in_binders) = match clause.data(interner) {
76-
ProgramClauseData::ForAll(for_all) => {
77-
(for_all.clone().into(), true)
78-
}
69+
ProgramClauseData::ForAll(for_all) => (for_all.clone().into(), true),
7970
// introduce a dummy binder and shift implication through it
80-
ProgramClauseData::Implies(implication) => ((ParameterKinds::new(interner), implication.shifted_in(interner)), false),
71+
ProgramClauseData::Implies(implication) => (
72+
(
73+
ParameterKinds::new(interner),
74+
implication.shifted_in(interner),
75+
),
76+
false,
77+
),
8178
};
8279
let mut binders: Vec<_> = binders.as_slice(interner).clone().into();
83-
80+
8481
let outer_binder = outer_binder.shifted_in();
8582

8683
self.binders_len = binders.len();
8784
let consequence = implication.consequence.fold_with(self, outer_binder)?;
8885
// Immediately move `new_params` out of of the folder struct so it's safe
8986
// to call `.fold_with` again
9087
let new_params = replace(&mut self.new_params, vec![]);
91-
88+
let new_goals = replace(&mut self.new_goals, vec![]);
89+
9290
let mut conditions = implication.conditions.fold_with(self, outer_binder)?;
9391
if new_params.is_empty() && !in_binders {
9492
// shift the clause out since we didn't use the dummy binder
95-
return Ok(ProgramClauseData::Implies(ProgramClauseImplication {
96-
consequence,
97-
conditions,
98-
priority: implication.priority,
99-
}.shifted_out(interner)?)
93+
return Ok(ProgramClauseData::Implies(
94+
ProgramClauseImplication {
95+
consequence,
96+
conditions,
97+
priority: implication.priority,
98+
}
99+
.shifted_out(interner)?,
100+
)
100101
.intern(interner));
101102
}
102103

103-
let old_len = binders.len();
104-
binders.extend(new_params.iter().map(|p| p.data(interner).anonymize()));
104+
binders.extend(new_params.into_iter());
105105

106106
conditions = Goals::from(
107107
interner,
108-
conditions
109-
.iter(interner)
110-
.cloned()
111-
.chain(self.to_eq_goals(new_params, old_len)),
108+
conditions.iter(interner).cloned().chain(new_goals),
112109
);
113110

114111
Ok(ProgramClauseData::ForAll(Binders::new(
@@ -134,29 +131,30 @@ impl<'i, I: Interner> Folder<'i, I> for SynEqFolder<'i, I> {
134131
self.binders_len = 0;
135132
// shifted in because we introduce a new binder
136133
let outer_binder = outer_binder.shifted_in();
137-
let domain_goal =
138-
GoalData::DomainGoal(domain_goal.shifted_in(interner).fold_with(self, outer_binder)?).intern(interner);
134+
let domain_goal = GoalData::DomainGoal(
135+
domain_goal
136+
.shifted_in(interner)
137+
.fold_with(self, outer_binder)?,
138+
)
139+
.intern(interner);
139140
let new_params = replace(&mut self.new_params, vec![]);
141+
let new_goals = replace(&mut self.new_goals, vec![]);
140142

141-
let binders: Vec<_> = new_params
142-
.iter()
143-
.map(|p| p.data(interner).anonymize())
144-
.collect();
145-
146-
if binders.is_empty() {
143+
if new_params.is_empty() {
147144
return Ok(goal.clone());
148145
}
149146

150147
let goal = GoalData::All(Goals::from(
151148
interner,
152-
iter::once(domain_goal).chain(self.to_eq_goals(new_params, 0)),
149+
iter::once(domain_goal).chain(new_goals),
153150
))
154151
.intern(interner);
155152

156-
Ok(
157-
GoalData::Quantified(QuantifierKind::Exists, Binders::new(ParameterKinds::from(interner, binders), goal))
158-
.intern(interner),
153+
Ok(GoalData::Quantified(
154+
QuantifierKind::Exists,
155+
Binders::new(ParameterKinds::from(interner, new_params), goal),
159156
)
157+
.intern(interner))
160158
}
161159

162160
fn interner(&self) -> &'i I {

0 commit comments

Comments
 (0)