Skip to content

Commit f7c4c26

Browse files
committed
Replace WhereClauseAtom with WhereClause
1 parent 733f12f commit f7c4c26

File tree

10 files changed

+378
-360
lines changed

10 files changed

+378
-360
lines changed

chalk-parse/src/ast.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,19 +208,27 @@ pub struct Identifier {
208208

209209
pub enum WhereClause {
210210
Implemented { trait_ref: TraitRef },
211-
Normalize { projection: ProjectionTy, ty: Ty },
212211
ProjectionEq { projection: ProjectionTy, ty: Ty },
213-
TyWellFormed { ty: Ty },
212+
}
213+
214+
pub enum DomainGoal {
215+
Holds { where_clause: WhereClause },
216+
Normalize { projection: ProjectionTy, ty: Ty },
214217
TraitRefWellFormed { trait_ref: TraitRef },
218+
TyWellFormed { ty: Ty },
215219
TyFromEnv { ty: Ty },
216220
TraitRefFromEnv { trait_ref: TraitRef },
217-
UnifyTys { a: Ty, b: Ty },
218-
UnifyLifetimes { a: Lifetime, b: Lifetime },
219221
TraitInScope { trait_name: Identifier },
220222
Derefs { source: Ty, target: Ty },
221223
IsLocal { ty: Ty },
222224
}
223225

226+
pub enum LeafGoal {
227+
DomainGoal { goal: DomainGoal },
228+
UnifyTys { a: Ty, b: Ty },
229+
UnifyLifetimes { a: Lifetime, b: Lifetime },
230+
}
231+
224232
pub struct QuantifiedWhereClause {
225233
pub parameter_kinds: Vec<ParameterKind>,
226234
pub where_clause: WhereClause,
@@ -235,7 +243,7 @@ pub struct Field {
235243
/// logic; it has no equivalent in Rust, but it's useful for testing.
236244
pub struct Clause {
237245
pub parameter_kinds: Vec<ParameterKind>,
238-
pub consequence: WhereClause,
246+
pub consequence: DomainGoal,
239247
pub conditions: Vec<Box<Goal>>,
240248
}
241249

@@ -247,5 +255,5 @@ pub enum Goal {
247255
Not(Box<Goal>),
248256

249257
// Additional kinds of goals:
250-
Leaf(WhereClause),
258+
Leaf(LeafGoal),
251259
}

chalk-parse/src/parser.lalrpop

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ pub Goal: Box<Goal> = {
2929
Goal1: Box<Goal> = {
3030
"forall" "<" <p:Comma<ParameterKind>> ">" "{" <g:Goal> "}" => Box::new(Goal::ForAll(p, g)),
3131
"exists" "<" <p:Comma<ParameterKind>> ">" "{" <g:Goal> "}" => Box::new(Goal::Exists(p, g)),
32-
"if" "(" <w:SemiColon<InlineClause>> ")" "{" <g:Goal> "}" => Box::new(Goal::Implies(w, g)),
32+
"if" "(" <h:SemiColon<InlineClause>> ")" "{" <g:Goal> "}" => Box::new(Goal::Implies(h, g)),
3333
"not" "{" <g:Goal> "}" => Box::new(Goal::Not(g)),
34-
<w:WhereClause> => Box::new(Goal::Leaf(w)),
34+
<leaf:LeafGoal> => Box::new(Goal::Leaf(leaf)),
3535
"(" <Goal> ")",
3636
};
3737

@@ -199,29 +199,29 @@ Field: Field = {
199199
};
200200

201201
Clause: Clause = {
202-
"forall" <pk:Angle<ParameterKind>> "{" <wc:WhereClause> "if" <g:Comma<Goal1>> "}" => Clause {
202+
"forall" <pk:Angle<ParameterKind>> "{" <dg:DomainGoal> "if" <g:Comma<Goal1>> "}" => Clause {
203203
parameter_kinds: pk,
204-
consequence: wc,
204+
consequence: dg,
205205
conditions: g,
206206
},
207207

208-
"forall" <pk:Angle<ParameterKind>> "{" <wc:WhereClause> "}" => Clause {
208+
"forall" <pk:Angle<ParameterKind>> "{" <dg:DomainGoal> "}" => Clause {
209209
parameter_kinds: pk,
210-
consequence: wc,
210+
consequence: dg,
211211
conditions: vec![],
212212
},
213213
};
214214

215215
InlineClause1: Clause = {
216-
<wc:WhereClause> => Clause {
216+
<dg:DomainGoal> => Clause {
217217
parameter_kinds: vec![],
218-
consequence: wc,
218+
consequence: dg,
219219
conditions: vec![],
220220
},
221221

222-
<wc:WhereClause> ":" "-" <g:Comma<Goal1>> => Clause {
222+
<dg:DomainGoal> ":" "-" <g:Comma<Goal1>> => Clause {
223223
parameter_kinds: vec![],
224-
consequence: wc,
224+
consequence: dg,
225225
conditions: g,
226226
},
227227
};
@@ -236,29 +236,9 @@ InlineClause: Clause = {
236236
}
237237
};
238238

239-
QuantifiedWhereClauses: Vec<QuantifiedWhereClause> = {
240-
"where" <Comma<QuantifiedWhereClause>>,
241-
() => vec![],
242-
};
243-
244239
WhereClause: WhereClause = {
245240
<t:TraitRef<":">> => WhereClause::Implemented { trait_ref: t },
246241

247-
"WellFormed" "(" <t:Ty> ")" => WhereClause::TyWellFormed { ty: t },
248-
249-
"WellFormed" "(" <t:TraitRef<":">> ")" => WhereClause::TraitRefWellFormed { trait_ref: t },
250-
251-
"FromEnv" "(" <t:Ty> ")" => WhereClause::TyFromEnv { ty: t },
252-
253-
"FromEnv" "(" <t:TraitRef<":">> ")" => WhereClause::TraitRefFromEnv { trait_ref: t },
254-
255-
<a:Ty> "=" <b:Ty> => WhereClause::UnifyTys { a, b },
256-
257-
<a:Lifetime> "=" <b:Lifetime> => WhereClause::UnifyLifetimes { a, b },
258-
259-
// `<T as Foo>::U -> Bar` -- a normalization
260-
"Normalize" "(" <s:ProjectionTy> "->" <t:Ty> ")" => WhereClause::Normalize { projection: s, ty: t },
261-
262242
// `T: Foo<U = Bar>` -- projection equality
263243
<s:Ty> ":" <t:Id> "<" <a:(<Comma<Parameter>> ",")?> <name:Id> <a2:Angle<Parameter>>
264244
"=" <ty:Ty> ">" =>
@@ -269,11 +249,6 @@ WhereClause: WhereClause = {
269249
let projection = ProjectionTy { trait_ref, name, args: a2 };
270250
WhereClause::ProjectionEq { projection, ty }
271251
},
272-
273-
"InScope" "(" <t:Id> ")" => WhereClause::TraitInScope { trait_name: t },
274-
"Derefs" "(" <source:Ty> "," <target:Ty> ")" => WhereClause::Derefs { source, target },
275-
276-
"IsLocal" "(" <ty:Ty> ")" => WhereClause::IsLocal { ty },
277252
};
278253

279254
QuantifiedWhereClause: QuantifiedWhereClause = {
@@ -288,6 +263,40 @@ QuantifiedWhereClause: QuantifiedWhereClause = {
288263
},
289264
};
290265

266+
QuantifiedWhereClauses: Vec<QuantifiedWhereClause> = {
267+
"where" <Comma<QuantifiedWhereClause>>,
268+
() => vec![],
269+
};
270+
271+
DomainGoal: DomainGoal = {
272+
<wc: WhereClause> => DomainGoal::Holds { where_clause: wc },
273+
274+
"WellFormed" "(" <t:Ty> ")" => DomainGoal::TyWellFormed { ty: t },
275+
276+
"WellFormed" "(" <t:TraitRef<":">> ")" => DomainGoal::TraitRefWellFormed { trait_ref: t },
277+
278+
"FromEnv" "(" <t:Ty> ")" => DomainGoal::TyFromEnv { ty: t },
279+
280+
"FromEnv" "(" <t:TraitRef<":">> ")" => DomainGoal::TraitRefFromEnv { trait_ref: t },
281+
282+
// `<T as Foo>::U -> Bar` -- a normalization
283+
"Normalize" "(" <s:ProjectionTy> "->" <t:Ty> ")" => DomainGoal::Normalize { projection: s, ty: t },
284+
285+
"InScope" "(" <t:Id> ")" => DomainGoal::TraitInScope { trait_name: t },
286+
287+
"Derefs" "(" <source:Ty> "," <target:Ty> ")" => DomainGoal::Derefs { source, target },
288+
289+
"IsLocal" "(" <ty:Ty> ")" => DomainGoal::IsLocal { ty },
290+
};
291+
292+
LeafGoal: LeafGoal = {
293+
<dg: DomainGoal> => LeafGoal::DomainGoal { goal: dg },
294+
295+
<a:Ty> "=" <b:Ty> => LeafGoal::UnifyTys { a, b },
296+
297+
<a:Lifetime> "=" <b:Lifetime> => LeafGoal::UnifyLifetimes { a, b },
298+
};
299+
291300
TraitRef<S>: TraitRef = {
292301
<s:Ty> S <t:Id> <a:Angle<Parameter>> => {
293302
let mut args = vec![Parameter::Ty(s)];

src/cast.rs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,21 @@ macro_rules! reflexive_impl {
5050
reflexive_impl!(TraitRef);
5151
reflexive_impl!(LeafGoal);
5252
reflexive_impl!(DomainGoal);
53-
reflexive_impl!(WhereClauseAtom);
53+
reflexive_impl!(WhereClause);
5454

55-
impl Cast<WhereClauseAtom> for TraitRef {
56-
fn cast(self) -> WhereClauseAtom {
57-
WhereClauseAtom::Implemented(self)
55+
impl Cast<WhereClause> for TraitRef {
56+
fn cast(self) -> WhereClause {
57+
WhereClause::Implemented(self)
5858
}
5959
}
6060

61-
impl Cast<WhereClauseAtom> for ProjectionEq {
62-
fn cast(self) -> WhereClauseAtom {
63-
WhereClauseAtom::ProjectionEq(self)
61+
impl Cast<WhereClause> for ProjectionEq {
62+
fn cast(self) -> WhereClause {
63+
WhereClause::ProjectionEq(self)
6464
}
6565
}
6666

67-
impl<T> Cast<DomainGoal> for T where T: Cast<WhereClauseAtom> {
67+
impl<T> Cast<DomainGoal> for T where T: Cast<WhereClause> {
6868
fn cast(self) -> DomainGoal {
6969
DomainGoal::Holds(self.cast())
7070
}
@@ -94,13 +94,25 @@ impl Cast<DomainGoal> for UnselectedNormalize {
9494
}
9595
}
9696

97+
impl Cast<DomainGoal> for WellFormed {
98+
fn cast(self) -> DomainGoal {
99+
DomainGoal::WellFormed(self)
100+
}
101+
}
102+
103+
impl Cast<DomainGoal> for FromEnv {
104+
fn cast(self) -> DomainGoal {
105+
DomainGoal::FromEnv(self)
106+
}
107+
}
108+
97109
impl Cast<LeafGoal> for EqGoal {
98110
fn cast(self) -> LeafGoal {
99111
LeafGoal::EqGoal(self)
100112
}
101113
}
102114

103-
impl Cast<Goal> for QuantifiedDomainGoal {
115+
impl<T: Cast<Goal>> Cast<Goal> for Binders<T> {
104116
fn cast(self) -> Goal {
105117
if self.binders.is_empty() {
106118
self.value.cast()
@@ -113,21 +125,6 @@ impl Cast<Goal> for QuantifiedDomainGoal {
113125
}
114126
}
115127

116-
impl Cast<ProgramClause> for QuantifiedDomainGoal {
117-
fn cast(self) -> ProgramClause {
118-
if self.binders.is_empty() {
119-
self.value.cast()
120-
} else {
121-
ProgramClause::ForAll(
122-
self.map(|bound| ProgramClauseImplication {
123-
consequence: bound,
124-
conditions: vec![],
125-
})
126-
)
127-
}
128-
}
129-
}
130-
131128
impl Cast<Ty> for ApplicationTy {
132129
fn cast(self) -> Ty {
133130
Ty::Apply(self)
@@ -152,15 +149,30 @@ impl Cast<Parameter> for Lifetime {
152149
}
153150
}
154151

155-
impl Cast<ProgramClause> for DomainGoal {
152+
impl<T> Cast<ProgramClause> for T where T: Cast<DomainGoal> {
156153
fn cast(self) -> ProgramClause {
157154
ProgramClause::Implies(ProgramClauseImplication {
158-
consequence: self,
155+
consequence: self.cast(),
159156
conditions: vec![],
160157
})
161158
}
162159
}
163160

161+
impl<T: Cast<DomainGoal>> Cast<ProgramClause> for Binders<T> {
162+
fn cast(self) -> ProgramClause {
163+
if self.binders.is_empty() {
164+
Cast::<ProgramClause>::cast(self.value)
165+
} else {
166+
ProgramClause::ForAll(
167+
self.map(|bound| ProgramClauseImplication {
168+
consequence: bound.cast(),
169+
conditions: vec![],
170+
})
171+
)
172+
}
173+
}
174+
}
175+
164176
impl Cast<ProgramClause> for ProgramClauseImplication {
165177
fn cast(self) -> ProgramClause {
166178
ProgramClause::Implies(self)

src/fold.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,11 @@ macro_rules! enum_fold {
423423

424424
enum_fold!(PolarizedTraitRef[] { Positive(a), Negative(a) });
425425
enum_fold!(ParameterKind[T,L] { Ty(a), Lifetime(a) } where T: Fold, L: Fold);
426-
enum_fold!(WhereClauseAtom[] { Implemented(a), ProjectionEq(a) });
426+
enum_fold!(WhereClause[] { Implemented(a), ProjectionEq(a) });
427+
enum_fold!(WellFormed[] { Trait(a), Ty(a) });
428+
enum_fold!(FromEnv[] { Trait(a), Ty(a) });
427429
enum_fold!(DomainGoal[] { Holds(a), WellFormed(a), FromEnv(a), Normalize(a), UnselectedNormalize(a),
428-
WellFormedTy(a), FromEnvTy(a), InScope(a), Derefs(a), IsLocal(a), LocalImplAllowed(a) });
430+
InScope(a), Derefs(a), IsLocal(a), LocalImplAllowed(a) });
429431
enum_fold!(LeafGoal[] { EqGoal(a), DomainGoal(a) });
430432
enum_fold!(Constraint[] { LifetimeEq(a, b) });
431433
enum_fold!(Goal[] { Quantified(qkind, subgoal), Implies(wc, subgoal), And(g1, g2), Not(g),

0 commit comments

Comments
 (0)