Skip to content

Commit

Permalink
Trait bounds on associated types
Browse files Browse the repository at this point in the history
  • Loading branch information
shepmaster committed May 19, 2020
1 parent 043ce98 commit 2824424
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
22 changes: 21 additions & 1 deletion src/ast.rs
Expand Up @@ -615,15 +615,35 @@ pub enum TypeGenericsAngleMember {
/// fn a() -> impl Iterator<Item = bool> {}
/// // ^^^^^^^^^^^
/// ```
// TODO: add "type" to the name?
// TODO: prefix the name with "type"?
#[derive(Debug, HasExtent, ExtentIndex, Visit)]
pub struct AssociatedType {
pub extent: Extent,
pub name: Ident,
pub value: AssociatedTypeValue,
pub whitespace: Vec<Whitespace>,
}

#[derive(Debug, HasExtent, ExtentIndex, Visit, Decompose)]
pub enum AssociatedTypeValue {
Equal(AssociatedTypeValueEqual),
Bound(AssociatedTypeValueBound),
}

#[derive(Debug, HasExtent, ExtentIndex, Visit)]
pub struct AssociatedTypeValueEqual {
pub extent: Extent,
pub value: Type,
pub whitespace: Vec<Whitespace>,
}

#[derive(Debug, HasExtent, ExtentIndex, Visit)]
pub struct AssociatedTypeValueBound {
pub extent: Extent,
pub bounds: TraitBounds,
pub whitespace: Vec<Whitespace>,
}

/// A function pointer as a type
///
/// ### Example Source
Expand Down
34 changes: 32 additions & 2 deletions src/parser/mod.rs
Expand Up @@ -2446,9 +2446,33 @@ fn associated_type<'s>(pm: &mut Master<'s>, pt: Point<'s>) -> Progress<'s, Assoc
sequence!(pm, pt, {
spt = point;
name = ident;
value = associated_type_value;
}, |pm: &mut Master, pt| AssociatedType { extent: pm.state.ex(spt, pt), name, value, whitespace: Vec::new() })
}

fn associated_type_value<'s>(pm: &mut Master<'s>, pt: Point<'s>) ->
Progress<'s, AssociatedTypeValue>
{
pm.alternate(pt)
.one(map(associated_type_value_equal, AssociatedTypeValue::Equal))
.one(map(associated_type_value_bound, AssociatedTypeValue::Bound))
.finish()
}

fn associated_type_value_equal<'s>(pm: &mut Master<'s>, pt: Point<'s>) -> Progress<'s, AssociatedTypeValueEqual> {
sequence!(pm, pt, {
spt = point;
_ = equals;
value = typ;
}, |pm: &mut Master, pt| AssociatedType { extent: pm.state.ex(spt, pt), name, value, whitespace: Vec::new() })
}, |pm: &mut Master, pt| AssociatedTypeValueEqual { extent: pm.state.ex(spt, pt), value, whitespace: Vec::new() })
}

fn associated_type_value_bound<'s>(pm: &mut Master<'s>, pt: Point<'s>) -> Progress<'s, AssociatedTypeValueBound> {
sequence!(pm, pt, {
spt = point;
_ = colon;
bounds = trait_bounds;
}, |pm: &mut Master, pt| AssociatedTypeValueBound { extent: pm.state.ex(spt, pt), bounds, whitespace: Vec::new() })
}

fn typ_function<'s>(pm: &mut Master<'s>, pt: Point<'s>) -> Progress<'s, TypeFunction> {
Expand Down Expand Up @@ -4141,11 +4165,17 @@ mod test {
}

#[test]
fn trait_bounds_with_associated_types() {
fn trait_bounds_with_associated_type_equality() {
let p = qp(trait_bounds, "A<B, C = D>");
assert_extent!(p, (0, 11))
}

#[test]
fn trait_bounds_with_associated_type_bounds() {
let p = qp(trait_bounds, "A<B, C: D>");
assert_extent!(p, (0, 10))
}

#[test]
fn visibility_self() {
let p = qp(visibility, "pub(self)");
Expand Down
12 changes: 12 additions & 0 deletions src/visit.rs
Expand Up @@ -125,6 +125,9 @@ pub trait Visitor<'ast> {
fn visit_as_type(&mut self, _: &'ast AsType) -> Control { Control::Continue }
fn visit_ascription(&mut self, _: &'ast Ascription) -> Control { Control::Continue }
fn visit_associated_type(&mut self, _: &'ast AssociatedType) -> Control { Control::Continue }
fn visit_associated_type_value(&mut self, _: &'ast AssociatedTypeValue) -> Control { Control::Continue }
fn visit_associated_type_value_equal(&mut self, _: &'ast AssociatedTypeValueEqual) -> Control { Control::Continue }
fn visit_associated_type_value_bound(&mut self, _: &'ast AssociatedTypeValueBound) -> Control { Control::Continue }
fn visit_async_block(&mut self, _: &'ast AsyncBlock) -> Control { Control::Continue }
fn visit_attribute(&mut self, _: &'ast Attribute) -> Control { Control::Continue }
fn visit_attribute_literal(&mut self, _: &'ast AttributeLiteral) -> Control { Control::Continue }
Expand Down Expand Up @@ -323,6 +326,9 @@ pub trait Visitor<'ast> {
fn exit_as_type(&mut self, _: &'ast AsType) {}
fn exit_ascription(&mut self, _: &'ast Ascription) {}
fn exit_associated_type(&mut self, _: &'ast AssociatedType) {}
fn exit_associated_type_value(&mut self, _: &'ast AssociatedTypeValue) {}
fn exit_associated_type_value_equal(&mut self, _: &'ast AssociatedTypeValueEqual) {}
fn exit_associated_type_value_bound(&mut self, _: &'ast AssociatedTypeValueBound) {}
fn exit_async_block(&mut self, _: &'ast AsyncBlock) {}
fn exit_attribute(&mut self, _: &'ast Attribute) {}
fn exit_attribute_literal(&mut self, _: &'ast AttributeLiteral) {}
Expand Down Expand Up @@ -530,6 +536,9 @@ pub trait VisitorMut {
fn visit_as_type(&mut self, _: &mut AsType) -> Control { Control::Continue }
fn visit_ascription(&mut self, _: &mut Ascription) -> Control { Control::Continue }
fn visit_associated_type(&mut self, _: &mut AssociatedType) -> Control { Control::Continue }
fn visit_associated_type_value(&mut self, _: &mut AssociatedTypeValue) -> Control { Control::Continue }
fn visit_associated_type_value_equal(&mut self, _: &mut AssociatedTypeValueEqual) -> Control { Control::Continue }
fn visit_associated_type_value_bound(&mut self, _: &mut AssociatedTypeValueBound) -> Control { Control::Continue }
fn visit_async_block(&mut self, _: &mut AsyncBlock) -> Control { Control::Continue }
fn visit_attribute(&mut self, _: &mut Attribute) -> Control { Control::Continue }
fn visit_attribute_literal(&mut self, _: &mut AttributeLiteral) -> Control { Control::Continue }
Expand Down Expand Up @@ -728,6 +737,9 @@ pub trait VisitorMut {
fn exit_as_type(&mut self, _: &mut AsType) {}
fn exit_ascription(&mut self, _: &mut Ascription) {}
fn exit_associated_type(&mut self, _: &mut AssociatedType) {}
fn exit_associated_type_value(&mut self, _: &mut AssociatedTypeValue) {}
fn exit_associated_type_value_equal(&mut self, _: &mut AssociatedTypeValueEqual) {}
fn exit_associated_type_value_bound(&mut self, _: &mut AssociatedTypeValueBound) {}
fn exit_async_block(&mut self, _: &mut AsyncBlock) {}
fn exit_attribute(&mut self, _: &mut Attribute) {}
fn exit_attribute_literal(&mut self, _: &mut AttributeLiteral) {}
Expand Down

0 comments on commit 2824424

Please sign in to comment.