Skip to content

Commit 72953f4

Browse files
committed
Add associated functions to the AST and parser
1 parent cbd5ba0 commit 72953f4

File tree

2 files changed

+108
-28
lines changed

2 files changed

+108
-28
lines changed

chalk-parse/src/ast.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ pub struct TraitDefn {
143143
pub assoc_ty_defns: Vec<AssocTyDefn>,
144144
pub flags: TraitFlags,
145145
pub well_known: Option<WellKnownTrait>,
146+
pub fn_defs: Vec<FnDefn>,
146147
}
147148

148149
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -259,12 +260,26 @@ impl fmt::Display for Kind {
259260
}
260261
}
261262

263+
#[derive(Clone, PartialEq, Eq, Debug)]
264+
pub enum ImplItem {
265+
Assoc(AssocTyValue),
266+
FnDefn(FnDefn),
267+
}
268+
269+
#[derive(Clone, PartialEq, Eq, Debug)]
270+
pub enum TraitItem {
271+
Assoc(AssocTyDefn),
272+
FnDefn(FnDefn),
273+
}
274+
262275
#[derive(Clone, PartialEq, Eq, Debug)]
263276
pub struct Impl {
277+
pub id: Option<Identifier>,
264278
pub variable_kinds: Vec<VariableKind>,
265279
pub trait_ref: TraitRef,
266280
pub polarity: Polarity,
267281
pub where_clauses: Vec<QuantifiedWhereClause>,
282+
pub fn_defs: Vec<FnDefn>,
268283
pub assoc_ty_values: Vec<AssocTyValue>,
269284
pub impl_type: ImplType,
270285
}
@@ -296,8 +311,11 @@ pub enum Ty {
296311
name: Identifier,
297312
args: Vec<GenericArg>,
298313
},
314+
ImplFn {
315+
func: ImplFnRef,
316+
},
299317
Projection {
300-
proj: ProjectionTy,
318+
proj: Projection,
301319
},
302320
ForAll {
303321
lifetime_names: Vec<Identifier>,
@@ -392,12 +410,19 @@ pub enum Lifetime {
392410
}
393411

394412
#[derive(Clone, PartialEq, Eq, Debug)]
395-
pub struct ProjectionTy {
413+
pub struct Projection {
396414
pub trait_ref: TraitRef,
397415
pub name: Identifier,
398416
pub args: Vec<GenericArg>,
399417
}
400418

419+
#[derive(Clone, PartialEq, Eq, Debug)]
420+
pub struct ImplFnRef {
421+
pub impl_name: Identifier,
422+
pub fn_name: Identifier,
423+
pub args: Vec<GenericArg>,
424+
}
425+
401426
#[derive(Clone, PartialEq, Eq, Debug)]
402427
pub struct TraitRef {
403428
pub trait_name: Identifier,
@@ -438,15 +463,16 @@ impl fmt::Display for Identifier {
438463
#[derive(Clone, PartialEq, Eq, Debug)]
439464
pub enum WhereClause {
440465
Implemented { trait_ref: TraitRef },
441-
ProjectionEq { projection: ProjectionTy, ty: Ty },
466+
ProjectionEq { projection: Projection, ty: Ty },
442467
LifetimeOutlives { a: Lifetime, b: Lifetime },
443468
TypeOutlives { ty: Ty, lifetime: Lifetime },
444469
}
445470

446471
#[derive(Clone, PartialEq, Eq, Debug)]
447472
pub enum DomainGoal {
448473
Holds { where_clause: WhereClause },
449-
Normalize { projection: ProjectionTy, ty: Ty },
474+
Normalize { projection: Projection, ty: Ty },
475+
NormalizeFn { projection: Projection, ty: Ty },
450476
TraitRefWellFormed { trait_ref: TraitRef },
451477
TyWellFormed { ty: Ty },
452478
TyFromEnv { ty: Ty },

chalk-parse/src/parser.lalrpop

+78-24
Original file line numberDiff line numberDiff line change
@@ -250,24 +250,40 @@ ClosureArgs: Vec<Ty> = {
250250
"," <args:FnArgs> => args.to_tys(),
251251
}
252252

253+
TraitItem: TraitItem = {
254+
<assoc:AssocTyDefn> => TraitItem::Assoc(assoc),
255+
<fndef:FnDefn> => TraitItem::FnDefn(fndef),
256+
};
257+
253258
TraitDefn: TraitDefn = {
254259
<auto:AutoKeyword?> <marker:MarkerKeyword?> <upstream:UpstreamKeyword?> <fundamental:FundamentalKeyword?> <non_enumerable:NonEnumerableKeyword?> <coinductive:CoinductiveKeyword?> <object_safe:ObjectSafeKeyword?> <well_known:WellKnownTrait?> "trait" <n:Id><p:Angle<VariableKind>>
255-
<w:QuantifiedWhereClauses> "{" <a:AssocTyDefn*> "}" => TraitDefn
256-
{
257-
name: n,
258-
variable_kinds: p,
259-
where_clauses: w,
260-
assoc_ty_defns: a,
261-
well_known,
262-
flags: TraitFlags {
263-
auto: auto.is_some(),
264-
marker: marker.is_some(),
265-
upstream: upstream.is_some(),
266-
fundamental: fundamental.is_some(),
267-
non_enumerable: non_enumerable.is_some(),
268-
coinductive: coinductive.is_some(),
269-
object_safe: object_safe.is_some(),
270-
},
260+
<w:QuantifiedWhereClauses> "{" <t:TraitItem*> "}" => {
261+
let mut assoc = vec![];
262+
let mut fn_defs = vec![];
263+
for item in t {
264+
match item {
265+
TraitItem::Assoc(v) => assoc.push(v),
266+
TraitItem::FnDefn(v) => fn_defs.push(v),
267+
}
268+
}
269+
270+
TraitDefn {
271+
name: n,
272+
variable_kinds: p,
273+
where_clauses: w,
274+
assoc_ty_defns: assoc,
275+
fn_defs,
276+
well_known,
277+
flags: TraitFlags {
278+
auto: auto.is_some(),
279+
marker: marker.is_some(),
280+
upstream: upstream.is_some(),
281+
fundamental: fundamental.is_some(),
282+
non_enumerable: non_enumerable.is_some(),
283+
coinductive: coinductive.is_some(),
284+
object_safe: object_safe.is_some(),
285+
},
286+
}
271287
}
272288
};
273289

@@ -337,13 +353,30 @@ QuantifiedInlineBound: QuantifiedInlineBound = {
337353
},
338354
};
339355

356+
ImplItem: ImplItem = {
357+
<assoc:AssocTyValue> => ImplItem::Assoc(assoc),
358+
<fndef:FnDefn> => ImplItem::FnDefn(fndef),
359+
};
360+
361+
340362
Impl: Impl = {
341-
<external:UpstreamKeyword?> "impl" <p:Angle<VariableKind>> <mark:"!"?> <t:Id> <a:Angle<GenericArg>> "for" <s:Ty>
342-
<w:QuantifiedWhereClauses> "{" <assoc:AssocTyValue*> "}" =>
363+
<external:UpstreamKeyword?> "impl" <id:ImplId?> <p:Angle<VariableKind>>
364+
<mark:"!"?> <t:Id> <a:Angle<GenericArg>> "for" <s:Ty>
365+
<w:QuantifiedWhereClauses> "{" <items:ImplItem*> "}" =>
343366
{
344367
let mut args = vec![GenericArg::Ty(s)];
345368
args.extend(a);
369+
let mut assoc = vec![];
370+
let mut fn_defs = vec![];
371+
for item in items {
372+
match item {
373+
ImplItem::Assoc(v) => assoc.push(v),
374+
ImplItem::FnDefn(v) => fn_defs.push(v),
375+
}
376+
}
377+
346378
Impl {
379+
id,
347380
variable_kinds: p,
348381
polarity: Polarity::from_bool(mark.is_none()),
349382
trait_ref: TraitRef {
@@ -352,6 +385,7 @@ Impl: Impl = {
352385
},
353386
where_clauses: w,
354387
assoc_ty_values: assoc,
388+
fn_defs,
355389
impl_type: external.map(|_| ImplType::External).unwrap_or(ImplType::Local),
356390
}
357391
},
@@ -424,7 +458,8 @@ TyWithoutId: Ty = {
424458
lifetime: l,
425459
},
426460
<n:Id> "<" <a:Comma<GenericArg>> ">" => Ty::Apply { name: n, args: a },
427-
<p:ProjectionTy> => Ty::Projection { proj: p },
461+
<p:Projection> => Ty::Projection { proj: p },
462+
<f:ImplFnRef> => Ty::ImplFn { func: f },
428463
"(" <t:TupleOrParensInner> ")" => t,
429464
"*" <m: RawMutability> <t:Ty> => Ty::Raw{ mutability: m, ty: Box::new(t) },
430465
"&" <l: Lifetime> "mut" <t:Ty> => Ty::Ref{ mutability: Mutability::Mut, lifetime: l, ty: Box::new(t) },
@@ -462,7 +497,7 @@ FloatTy: FloatTy = {
462497
ScalarType: ScalarType = {
463498
<i:IntTy> => ScalarType::Int(i),
464499
<u:UintTy> => ScalarType::Uint(u),
465-
<f:FloatTy> => ScalarType::Float(f),
500+
<f:FloatTy> => ScalarType::Float(f),
466501
"bool" => ScalarType::Bool,
467502
"char" => ScalarType::Char,
468503
};
@@ -506,8 +541,8 @@ GenericArg: GenericArg = {
506541
ConstWithoutId => GenericArg::Const(<>),
507542
};
508543

509-
ProjectionTy: ProjectionTy = {
510-
"<" <t:TraitRef<"as">> ">" "::" <n:Id> <a:Angle<GenericArg>> => ProjectionTy {
544+
Projection: Projection = {
545+
"<" <t:TraitRef<"as">> ">" "::" <n:Id> <a:Angle<GenericArg>> => Projection {
511546
trait_ref: t, name: n, args: a
512547
},
513548
};
@@ -571,7 +606,7 @@ WhereClause: WhereClause = {
571606
let mut args = vec![GenericArg::Ty(s)];
572607
if let Some(a) = a { args.extend(a); }
573608
let trait_ref = TraitRef { trait_name: t, args: args };
574-
let projection = ProjectionTy { trait_ref, name, args: a2 };
609+
let projection = Projection { trait_ref, name, args: a2 };
575610
WhereClause::ProjectionEq { projection, ty }
576611
},
577612

@@ -615,7 +650,10 @@ DomainGoal: DomainGoal = {
615650
"FromEnv" "(" <t:TraitRef<":">> ")" => DomainGoal::TraitRefFromEnv { trait_ref: t },
616651

617652
// `<T as Foo>::U -> Bar` -- a normalization
618-
"Normalize" "(" <s:ProjectionTy> "->" <t:Ty> ")" => DomainGoal::Normalize { projection: s, ty: t },
653+
"Normalize" "(" <s:Projection> "->" <t:Ty> ")" => DomainGoal::Normalize { projection: s, ty: t },
654+
655+
// `<T as Foo>::some_func -> @SomeImpl::some_func` -- a normalization
656+
"NormalizeFn" "(" <s:Projection> "->" <t:Ty> ")" => DomainGoal::NormalizeFn { projection: s, ty: t },
619657

620658
"IsLocal" "(" <ty:Ty> ")" => DomainGoal::IsLocal { ty },
621659
"IsUpstream" "(" <ty:Ty> ")" => DomainGoal::IsUpstream { ty },
@@ -639,6 +677,15 @@ LeafGoal: LeafGoal = {
639677
"Subtype" "(" <a:Ty> "," <b:Ty> ")" => LeafGoal::SubtypeGenericArgs { a, b },
640678
};
641679

680+
// @ImplName::f<A, B>
681+
ImplFnRef: ImplFnRef = {
682+
<imp:ImplId> "::" <f:Id> <a:Angle<GenericArg>> => ImplFnRef {
683+
impl_name: imp,
684+
fn_name: f,
685+
args: a,
686+
},
687+
}
688+
642689
TraitRef<S>: TraitRef = {
643690
<s:Ty> S <t:Id> <a:Angle<GenericArg>> => {
644691
let mut args = vec![GenericArg::Ty(s)];
@@ -698,4 +745,11 @@ LifetimeId: Identifier = {
698745
}
699746
};
700747

748+
ImplId: Identifier = {
749+
<l:@L> "@" <s:r"([A-Za-z]|_)([A-Za-z0-9]|_)*"> <r:@R> => Identifier {
750+
str: Atom::from(s),
751+
span: Span::new(l, r),
752+
}
753+
};
754+
701755
ConstValue: u32 = <s:r"[0-9]+"> => u32::from_str_radix(s, 10).unwrap();

0 commit comments

Comments
 (0)