Skip to content

Commit 0db2be9

Browse files
committed
Tweak inline bounds on associated types in the grammar
1 parent 52c171e commit 0db2be9

File tree

6 files changed

+86
-39
lines changed

6 files changed

+86
-39
lines changed

chalk-parse/src/ast.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub struct TraitFlags {
5454
pub struct AssocTyDefn {
5555
pub name: Identifier,
5656
pub parameter_kinds: Vec<ParameterKind>,
57-
pub bounds: Vec<TraitBound>,
57+
pub bounds: Vec<InlineBound>,
5858
pub where_clauses: Vec<QuantifiedWhereClause>,
5959
}
6060

@@ -68,20 +68,23 @@ pub enum Parameter {
6868
Lifetime(Lifetime),
6969
}
7070

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+
7177
/// Represents a trait bound on e.g. a type or type parameter.
7278
/// Does not know anything about what it's binding.
7379
pub struct TraitBound {
7480
pub trait_name: Identifier,
75-
pub args_no_self: Vec<TraitBoundParameter>,
76-
}
77-
78-
pub enum TraitBoundParameter {
79-
Ty(Ty),
80-
Lifetime(Lifetime),
81-
ProjectionEq(ProjectionEqBound),
81+
pub args_no_self: Vec<Parameter>,
8282
}
8383

84+
/// Represents a projection equality bound on e.g. a type or type parameter.
85+
/// Does not know anything about what it's binding.
8486
pub struct ProjectionEqBound {
87+
pub trait_bound: TraitBound,
8588
pub name: Identifier,
8689
pub parameters: Vec<Parameter>,
8790
pub value: Ty,

chalk-parse/src/parser.lalrpop

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ TraitDefn: TraitDefn = {
7272
};
7373

7474
AssocTyDefn: AssocTyDefn = {
75-
"type" <name:Id> <p:Angle<ParameterKind>> <b:(":" <Plus<TraitBound>>)?>
75+
"type" <name:Id> <p:Angle<ParameterKind>> <b:(":" <Plus<InlineBound>>)?>
7676
<w:QuantifiedWhereClauses> ";" =>
7777
{
7878
AssocTyDefn {
@@ -84,25 +84,32 @@ AssocTyDefn: AssocTyDefn = {
8484
}
8585
};
8686

87+
InlineBound: InlineBound = {
88+
TraitBound => InlineBound::TraitBound(<>),
89+
ProjectionEqBound => InlineBound::ProjectionEqBound(<>),
90+
};
91+
8792
TraitBound: TraitBound = {
88-
<t:Id> <a:Angle<TraitBoundParameter>> => {
93+
<t:Id> <a:Angle<Parameter>> => {
8994
TraitBound {
9095
trait_name: t,
9196
args_no_self: a,
9297
}
9398
}
9499
};
95100

96-
TraitBoundParameter: TraitBoundParameter = {
97-
Ty => TraitBoundParameter::Ty(<>),
98-
Lifetime => TraitBoundParameter::Lifetime(<>),
99-
ProjectionEqBound => TraitBoundParameter::ProjectionEq(<>),
100-
};
101-
102101
ProjectionEqBound: ProjectionEqBound = {
103-
<name:Id> <parameters:Angle<Parameter>> "=" <value:Ty> => ProjectionEqBound {
104-
name, parameters, value
105-
},
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,
112+
}
106113
};
107114

108115
Impl: Impl = {

src/ir/lowering/mod.rs

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

9194
fn in_binders<I, T, OP>(&self, binders: I, op: OP) -> Result<ir::Binders<T>>
@@ -95,7 +98,7 @@ impl<'k> Env<'k> {
9598
OP: FnOnce(&Self) -> Result<T>,
9699
{
97100
let binders: Vec<_> = binders.into_iter().collect();
98-
let env = self.introduce(binders.iter().cloned());
101+
let env = self.introduce(binders.iter().cloned())?;
99102
Ok(ir::Binders {
100103
binders: binders.anonymize(),
101104
value: op(&env)?,
@@ -178,6 +181,7 @@ impl LowerProgram for Program {
178181

179182
let mut parameter_kinds = defn.all_parameters();
180183
parameter_kinds.extend(d.all_parameters());
184+
let env = empty_env.introduce(parameter_kinds.clone())?;
181185

182186
associated_ty_data.insert(
183187
info.id,
@@ -186,7 +190,7 @@ impl LowerProgram for Program {
186190
id: info.id,
187191
name: defn.name.str,
188192
parameter_kinds: parameter_kinds,
189-
where_clauses: vec![],
193+
where_clauses: defn.where_clauses.lower(&env)?,
190194
},
191195
);
192196
}
@@ -757,7 +761,7 @@ impl LowerTy for Ty {
757761
lifetime_names
758762
.iter()
759763
.map(|id| ir::ParameterKind::Lifetime(id.str)),
760-
);
764+
)?;
761765

762766
let ty = ty.lower(&quantified_env)?;
763767
let quantified_ty = ir::QuantifiedTy {

src/ir/lowering/test.rs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,8 @@ fn check_parameter_kinds() {
305305

306306
#[test]
307307
fn gat_parse() {
308-
let program = Arc::new(
309-
parse_and_lower_program(
310-
"
308+
lowering_success! {
309+
program {
311310
trait Sized {}
312311

313312
trait Foo {
@@ -323,17 +322,51 @@ fn gat_parse() {
323322
}
324323

325324
trait Baz {
326-
type Item<'a, 'b, T>: Foo<Item<'b, T> = Containter<T>> + Clone;
325+
type Item<'a, 'b, T>: Foo<Item<'b, T> = Container<T>> + Clone;
327326
}
328327

329328
trait Quux {
330329
type Item<'a, T>;
331330
}
332-
",
333-
SolverChoice::slg()
334-
).unwrap()
335-
);
336-
tls::set_current_program(&program, || {
337-
println!("{:#?}", program.associated_ty_data.values());
338-
});
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+
}
339372
}

src/ir/mod.rs

Lines changed: 3 additions & 1 deletion
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)]

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
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)]
109
#![feature(specialization)]
1110
#![feature(step_trait)]
12-
#![feature(underscore_lifetimes)]
1311

1412
extern crate chalk_parse;
1513
#[macro_use]

0 commit comments

Comments
 (0)