Skip to content

Commit 17abbab

Browse files
authored
Merge pull request #118 from tmandry/GAT-step1
Implement GATs, step 1
2 parents 062df6c + 0db2be9 commit 17abbab

File tree

8 files changed

+151
-31
lines changed

8 files changed

+151
-31
lines changed

chalk-parse/src/ast.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ pub struct TraitFlags {
5454
pub struct AssocTyDefn {
5555
pub name: Identifier,
5656
pub parameter_kinds: Vec<ParameterKind>,
57+
pub bounds: Vec<InlineBound>,
58+
pub where_clauses: Vec<QuantifiedWhereClause>,
5759
}
5860

5961
pub enum ParameterKind {
@@ -66,6 +68,28 @@ pub enum Parameter {
6668
Lifetime(Lifetime),
6769
}
6870

71+
/// An inline bound, e.g. `: Foo<K>` in `impl<K, T: Foo<K>> SomeType<T>`.
72+
pub enum InlineBound {
73+
TraitBound(TraitBound),
74+
ProjectionEqBound(ProjectionEqBound),
75+
}
76+
77+
/// Represents a trait bound on e.g. a type or type parameter.
78+
/// Does not know anything about what it's binding.
79+
pub struct TraitBound {
80+
pub trait_name: Identifier,
81+
pub args_no_self: Vec<Parameter>,
82+
}
83+
84+
/// Represents a projection equality bound on e.g. a type or type parameter.
85+
/// Does not know anything about what it's binding.
86+
pub struct ProjectionEqBound {
87+
pub trait_bound: TraitBound,
88+
pub name: Identifier,
89+
pub parameters: Vec<Parameter>,
90+
pub value: Ty,
91+
}
92+
6993
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
7094
pub enum Kind {
7195
Ty,
@@ -115,7 +139,6 @@ pub struct Impl {
115139
pub struct AssocTyValue {
116140
pub name: Identifier,
117141
pub parameter_kinds: Vec<ParameterKind>,
118-
pub where_clauses: Vec<WhereClause>,
119142
pub value: Ty,
120143
}
121144

chalk-parse/src/parser.lalrpop

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,43 @@ TraitDefn: TraitDefn = {
7272
};
7373

7474
AssocTyDefn: AssocTyDefn = {
75-
"type" <name:Id> <p:Angle<ParameterKind>> ";" => AssocTyDefn {
76-
name: name,
77-
parameter_kinds: p
75+
"type" <name:Id> <p:Angle<ParameterKind>> <b:(":" <Plus<InlineBound>>)?>
76+
<w:QuantifiedWhereClauses> ";" =>
77+
{
78+
AssocTyDefn {
79+
name: name,
80+
parameter_kinds: p,
81+
where_clauses: w,
82+
bounds: b.unwrap_or(vec![]),
83+
}
84+
}
85+
};
86+
87+
InlineBound: InlineBound = {
88+
TraitBound => InlineBound::TraitBound(<>),
89+
ProjectionEqBound => InlineBound::ProjectionEqBound(<>),
90+
};
91+
92+
TraitBound: TraitBound = {
93+
<t:Id> <a:Angle<Parameter>> => {
94+
TraitBound {
95+
trait_name: t,
96+
args_no_self: a,
97+
}
98+
}
99+
};
100+
101+
ProjectionEqBound: ProjectionEqBound = {
102+
<t:Id> "<" <a:(<Comma<Parameter>> ",")?> <name:Id> <a2:Angle<Parameter>>
103+
"=" <ty:Ty> ">" => ProjectionEqBound
104+
{
105+
trait_bound: TraitBound {
106+
trait_name: t,
107+
args_no_self: a.unwrap_or(vec![]),
108+
},
109+
name,
110+
parameters: a2,
111+
value: ty,
78112
}
79113
};
80114

@@ -102,11 +136,10 @@ ParameterKind: ParameterKind = {
102136
};
103137

104138
AssocTyValue: AssocTyValue = {
105-
"type" <n:Id> <a:Angle<ParameterKind>> <wc:WhereClauses> "=" <v:Ty> ";" => AssocTyValue {
139+
"type" <n:Id> <a:Angle<ParameterKind>> "=" <v:Ty> ";" => AssocTyValue {
106140
name: n,
107141
parameter_kinds: a,
108142
value: v,
109-
where_clauses: wc,
110143
},
111144
};
112145

@@ -201,11 +234,6 @@ InlineClause: Clause = {
201234
}
202235
};
203236

204-
WhereClauses: Vec<WhereClause> = {
205-
"where" <Comma<WhereClause>>,
206-
() => vec![],
207-
};
208-
209237
QuantifiedWhereClauses: Vec<QuantifiedWhereClause> = {
210238
"where" <Comma<QuantifiedWhereClause>>,
211239
() => vec![],
@@ -290,6 +318,11 @@ SemiColon<T>: Vec<T> = {
290318
<Separator<";", T>>
291319
};
292320

321+
#[inline]
322+
Plus<T>: Vec<T> = {
323+
<Separator<"+", T>>
324+
};
325+
293326
Angle<T>: Vec<T> = {
294327
"<" <Comma<T>> ">",
295328
() => vec![],

src/fold/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ struct_fold!(AssociatedTyValue {
567567
associated_ty_id,
568568
value,
569569
});
570-
struct_fold!(AssociatedTyValueBound { ty, where_clauses });
570+
struct_fold!(AssociatedTyValueBound { ty });
571571
struct_fold!(Environment { clauses });
572572
struct_fold!(InEnvironment[F] { environment, goal } where F: Fold<Result = F>);
573573
struct_fold!(EqGoal { a, b });

src/ir/lowering/mod.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl<'k> Env<'k> {
7171
/// Introduces new parameters, shifting the indices of existing
7272
/// parameters to accommodate them. The indices of the new binders
7373
/// will be assigned in order as they are iterated.
74-
fn introduce<I>(&self, binders: I) -> Self
74+
fn introduce<I>(&self, binders: I) -> Result<Self>
7575
where
7676
I: IntoIterator<Item = ir::ParameterKind<ir::Identifier>>,
7777
I::IntoIter: ExactSizeIterator,
@@ -83,10 +83,13 @@ impl<'k> Env<'k> {
8383
.map(|(&k, &v)| (k, v + len))
8484
.chain(binders)
8585
.collect();
86-
Env {
86+
if parameter_map.len() != self.parameter_map.len() + len {
87+
bail!("duplicate parameters");
88+
}
89+
Ok(Env {
8790
parameter_map,
8891
..*self
89-
}
92+
})
9093
}
9194

9295
fn in_binders<I, T, OP>(&self, binders: I, op: OP) -> Result<ir::Binders<T>>
@@ -96,7 +99,7 @@ impl<'k> Env<'k> {
9699
OP: FnOnce(&Self) -> Result<T>,
97100
{
98101
let binders: Vec<_> = binders.into_iter().collect();
99-
let env = self.introduce(binders.iter().cloned());
102+
let env = self.introduce(binders.iter().cloned())?;
100103
Ok(ir::Binders {
101104
binders: binders.anonymize(),
102105
value: op(&env)?,
@@ -179,6 +182,7 @@ impl LowerProgram for Program {
179182

180183
let mut parameter_kinds = defn.all_parameters();
181184
parameter_kinds.extend(d.all_parameters());
185+
let env = empty_env.introduce(parameter_kinds.clone())?;
182186

183187
associated_ty_data.insert(
184188
info.id,
@@ -187,7 +191,7 @@ impl LowerProgram for Program {
187191
id: info.id,
188192
name: defn.name.str,
189193
parameter_kinds: parameter_kinds,
190-
where_clauses: vec![],
194+
where_clauses: defn.where_clauses.lower(&env)?,
191195
},
192196
);
193197
}
@@ -764,7 +768,7 @@ impl LowerTy for Ty {
764768
lifetime_names
765769
.iter()
766770
.map(|id| ir::ParameterKind::Lifetime(id.str)),
767-
);
771+
)?;
768772

769773
let ty = ty.lower(&quantified_env)?;
770774
let quantified_ty = ir::QuantifiedTy {
@@ -890,7 +894,6 @@ impl LowerAssocTyValue for AssocTyValue {
890894
let value = env.in_binders(self.all_parameters(), |env| {
891895
Ok(ir::AssociatedTyValueBound {
892896
ty: self.value.lower(env)?,
893-
where_clauses: self.where_clauses.lower(env)?,
894897
})
895898
})?;
896899
Ok(ir::AssociatedTyValue {

src/ir/lowering/test.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,7 @@ fn atc_accounting() {
211211
AssociatedTyValue {
212212
associated_ty_id: (Iterable::Iter),
213213
value: for<lifetime> AssociatedTyValueBound {
214-
ty: Iter<'?0, ?1>,
215-
where_clauses: []
214+
ty: Iter<'?0, ?1>
216215
}
217216
}
218217
],
@@ -303,3 +302,71 @@ fn check_parameter_kinds() {
303302
}
304303
}
305304
}
305+
306+
#[test]
307+
fn gat_parse() {
308+
lowering_success! {
309+
program {
310+
trait Sized {}
311+
312+
trait Foo {
313+
type Item<'a, T>: Sized + Clone where Self: Sized;
314+
}
315+
316+
trait Bar {
317+
type Item<'a, T> where Self: Sized;
318+
}
319+
320+
struct Container<T> {
321+
value: T
322+
}
323+
324+
trait Baz {
325+
type Item<'a, 'b, T>: Foo<Item<'b, T> = Container<T>> + Clone;
326+
}
327+
328+
trait Quux {
329+
type Item<'a, T>;
330+
}
331+
}
332+
}
333+
334+
lowering_error! {
335+
program {
336+
trait Sized { }
337+
338+
trait Foo {
339+
type Item where K: Sized;
340+
}
341+
}
342+
343+
error_msg {
344+
"invalid type name `K`"
345+
}
346+
}
347+
}
348+
349+
#[test]
350+
fn duplicate_parameters() {
351+
lowering_error! {
352+
program {
353+
trait Foo<T, T> { }
354+
}
355+
356+
error_msg {
357+
"duplicate parameters"
358+
}
359+
}
360+
361+
lowering_error! {
362+
program {
363+
trait Foo<T> {
364+
type Item<T>;
365+
}
366+
}
367+
368+
error_msg {
369+
"duplicate parameters"
370+
}
371+
}
372+
}

src/ir/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,10 @@ pub struct AssociatedTyDatum {
273273
/// but possibly including more.
274274
crate parameter_kinds: Vec<ParameterKind<Identifier>>,
275275

276+
// FIXME: inline bounds on the associated ty need to be implemented
277+
276278
/// Where clauses that must hold for the projection be well-formed.
277-
crate where_clauses: Vec<DomainGoal>,
279+
crate where_clauses: Vec<QuantifiedDomainGoal>,
278280
}
279281

280282
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -289,10 +291,6 @@ pub struct AssociatedTyValue {
289291
pub struct AssociatedTyValueBound {
290292
/// Type that we normalize to. The X in `type Foo<'a> = X`.
291293
crate ty: Ty,
292-
293-
/// Where-clauses that must hold for projection to be valid. The
294-
/// WC in `type Foo<'a> = X where WC`.
295-
crate where_clauses: Vec<DomainGoal>,
296294
}
297295

298296
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#![feature(catch_expr)]
44
#![feature(crate_in_paths)]
55
#![feature(crate_visibility_modifier)]
6-
#![feature(dyn_trait)]
76
#![feature(in_band_lifetimes)]
87
#![feature(macro_at_most_once_rep)]
98
#![feature(macro_vis_matcher)]

src/rules/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,7 @@ impl ir::AssociatedTyValue {
200200
.trait_ref
201201
.trait_ref()
202202
.up_shift(self.value.len());
203-
let conditions: Vec<ir::Goal> = Some(impl_trait_ref.clone().cast())
204-
.into_iter()
205-
.chain(self.value.value.where_clauses.clone().cast())
206-
.collect();
203+
let conditions: Vec<ir::Goal> = vec![impl_trait_ref.clone().cast()];
207204

208205
// Bound parameters + `Self` type of the trait-ref
209206
let parameters: Vec<_> = {

0 commit comments

Comments
 (0)