Skip to content

Commit d67e569

Browse files
authored
Merge pull request #142 from scalexm/wc-atom
Refactor `WhereClauseAtom` into `WhereClause`.
2 parents 733f12f + 5607fc9 commit d67e569

File tree

11 files changed

+448
-419
lines changed

11 files changed

+448
-419
lines changed

chalk-parse/src/ast.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use lalrpop_intern::InternedString;
22
use std::fmt;
33

4-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
4+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
55
pub struct Span {
66
pub lo: usize,
77
pub hi: usize,
@@ -13,17 +13,20 @@ impl Span {
1313
}
1414
}
1515

16+
#[derive(Clone, PartialEq, Eq, Debug)]
1617
pub struct Program {
1718
pub items: Vec<Item>
1819
}
1920

21+
#[derive(Clone, PartialEq, Eq, Debug)]
2022
pub enum Item {
2123
StructDefn(StructDefn),
2224
TraitDefn(TraitDefn),
2325
Impl(Impl),
2426
Clause(Clause),
2527
}
2628

29+
#[derive(Clone, PartialEq, Eq, Debug)]
2730
pub struct StructDefn {
2831
pub name: Identifier,
2932
pub parameter_kinds: Vec<ParameterKind>,
@@ -32,11 +35,13 @@ pub struct StructDefn {
3235
pub flags: StructFlags,
3336
}
3437

38+
#[derive(Clone, PartialEq, Eq, Debug)]
3539
pub struct StructFlags {
3640
pub external: bool,
3741
pub fundamental: bool,
3842
}
3943

44+
#[derive(Clone, PartialEq, Eq, Debug)]
4045
pub struct TraitDefn {
4146
pub name: Identifier,
4247
pub parameter_kinds: Vec<ParameterKind>,
@@ -45,43 +50,50 @@ pub struct TraitDefn {
4550
pub flags: TraitFlags,
4651
}
4752

53+
#[derive(Clone, PartialEq, Eq, Debug)]
4854
pub struct TraitFlags {
4955
pub auto: bool,
5056
pub marker: bool,
5157
pub external: bool,
5258
pub deref: bool,
5359
}
5460

61+
#[derive(Clone, PartialEq, Eq, Debug)]
5562
pub struct AssocTyDefn {
5663
pub name: Identifier,
5764
pub parameter_kinds: Vec<ParameterKind>,
5865
pub bounds: Vec<InlineBound>,
5966
pub where_clauses: Vec<QuantifiedWhereClause>,
6067
}
6168

69+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
6270
pub enum ParameterKind {
6371
Ty(Identifier),
6472
Lifetime(Identifier),
6573
}
6674

75+
#[derive(Clone, PartialEq, Eq, Debug)]
6776
pub enum Parameter {
6877
Ty(Ty),
6978
Lifetime(Lifetime),
7079
}
7180

81+
#[derive(Clone, PartialEq, Eq, Debug)]
7282
/// An inline bound, e.g. `: Foo<K>` in `impl<K, T: Foo<K>> SomeType<T>`.
7383
pub enum InlineBound {
7484
TraitBound(TraitBound),
7585
ProjectionEqBound(ProjectionEqBound),
7686
}
7787

88+
#[derive(Clone, PartialEq, Eq, Debug)]
7889
/// Represents a trait bound on e.g. a type or type parameter.
7990
/// Does not know anything about what it's binding.
8091
pub struct TraitBound {
8192
pub trait_name: Identifier,
8293
pub args_no_self: Vec<Parameter>,
8394
}
8495

96+
#[derive(Clone, PartialEq, Eq, Debug)]
8597
/// Represents a projection equality bound on e.g. a type or type parameter.
8698
/// Does not know anything about what it's binding.
8799
pub struct ProjectionEqBound {
@@ -91,7 +103,7 @@ pub struct ProjectionEqBound {
91103
pub value: Ty,
92104
}
93105

94-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
106+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
95107
pub enum Kind {
96108
Ty,
97109
Lifetime,
@@ -130,19 +142,22 @@ impl Kinded for Parameter {
130142
}
131143
}
132144

145+
#[derive(Clone, PartialEq, Eq, Debug)]
133146
pub struct Impl {
134147
pub parameter_kinds: Vec<ParameterKind>,
135148
pub trait_ref: PolarizedTraitRef,
136149
pub where_clauses: Vec<QuantifiedWhereClause>,
137150
pub assoc_ty_values: Vec<AssocTyValue>,
138151
}
139152

153+
#[derive(Clone, PartialEq, Eq, Debug)]
140154
pub struct AssocTyValue {
141155
pub name: Identifier,
142156
pub parameter_kinds: Vec<ParameterKind>,
143157
pub value: Ty,
144158
}
145159

160+
#[derive(Clone, PartialEq, Eq, Debug)]
146161
pub enum Ty {
147162
Id {
148163
name: Identifier,
@@ -163,28 +178,33 @@ pub enum Ty {
163178
}
164179
}
165180

181+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
166182
pub enum Lifetime {
167183
Id {
168184
name: Identifier,
169185
}
170186
}
171187

188+
#[derive(Clone, PartialEq, Eq, Debug)]
172189
pub struct ProjectionTy {
173190
pub trait_ref: TraitRef,
174191
pub name: Identifier,
175192
pub args: Vec<Parameter>,
176193
}
177194

195+
#[derive(Clone, PartialEq, Eq, Debug)]
178196
pub struct UnselectedProjectionTy {
179197
pub name: Identifier,
180198
pub args: Vec<Parameter>,
181199
}
182200

201+
#[derive(Clone, PartialEq, Eq, Debug)]
183202
pub struct TraitRef {
184203
pub trait_name: Identifier,
185204
pub args: Vec<Parameter>,
186205
}
187206

207+
#[derive(Clone, PartialEq, Eq, Debug)]
188208
pub enum PolarizedTraitRef {
189209
Positive(TraitRef),
190210
Negative(TraitRef),
@@ -200,45 +220,60 @@ impl PolarizedTraitRef {
200220
}
201221
}
202222

203-
#[derive(Copy, Clone, Debug)]
223+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
204224
pub struct Identifier {
205225
pub str: InternedString,
206226
pub span: Span,
207227
}
208228

229+
#[derive(Clone, PartialEq, Eq, Debug)]
209230
pub enum WhereClause {
210231
Implemented { trait_ref: TraitRef },
211-
Normalize { projection: ProjectionTy, ty: Ty },
212232
ProjectionEq { projection: ProjectionTy, ty: Ty },
213-
TyWellFormed { ty: Ty },
233+
}
234+
235+
#[derive(Clone, PartialEq, Eq, Debug)]
236+
pub enum DomainGoal {
237+
Holds { where_clause: WhereClause },
238+
Normalize { projection: ProjectionTy, ty: Ty },
214239
TraitRefWellFormed { trait_ref: TraitRef },
240+
TyWellFormed { ty: Ty },
215241
TyFromEnv { ty: Ty },
216242
TraitRefFromEnv { trait_ref: TraitRef },
217-
UnifyTys { a: Ty, b: Ty },
218-
UnifyLifetimes { a: Lifetime, b: Lifetime },
219243
TraitInScope { trait_name: Identifier },
220244
Derefs { source: Ty, target: Ty },
221245
IsLocal { ty: Ty },
222246
}
223247

248+
#[derive(Clone, PartialEq, Eq, Debug)]
249+
pub enum LeafGoal {
250+
DomainGoal { goal: DomainGoal },
251+
UnifyTys { a: Ty, b: Ty },
252+
UnifyLifetimes { a: Lifetime, b: Lifetime },
253+
}
254+
255+
#[derive(Clone, PartialEq, Eq, Debug)]
224256
pub struct QuantifiedWhereClause {
225257
pub parameter_kinds: Vec<ParameterKind>,
226258
pub where_clause: WhereClause,
227259
}
228260

261+
#[derive(Clone, PartialEq, Eq, Debug)]
229262
pub struct Field {
230263
pub name: Identifier,
231264
pub ty: Ty,
232265
}
233266

267+
#[derive(Clone, PartialEq, Eq, Debug)]
234268
/// This allows users to add arbitrary `A :- B` clauses into the
235269
/// logic; it has no equivalent in Rust, but it's useful for testing.
236270
pub struct Clause {
237271
pub parameter_kinds: Vec<ParameterKind>,
238-
pub consequence: WhereClause,
272+
pub consequence: DomainGoal,
239273
pub conditions: Vec<Box<Goal>>,
240274
}
241275

276+
#[derive(Clone, PartialEq, Eq, Debug)]
242277
pub enum Goal {
243278
ForAll(Vec<ParameterKind>, Box<Goal>),
244279
Exists(Vec<ParameterKind>, Box<Goal>),
@@ -247,5 +282,5 @@ pub enum Goal {
247282
Not(Box<Goal>),
248283

249284
// Additional kinds of goals:
250-
Leaf(WhereClause),
285+
Leaf(LeafGoal),
251286
}

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)];

0 commit comments

Comments
 (0)