Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 3 additions & 39 deletions compiler/noirc_frontend/src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::ast::{
BinaryOp, BinaryOpKind, BlockExpression, ForLoopStatement, ForRange, Ident, IfExpression,
InfixExpression, LValue, Literal, ModuleDeclaration, NoirTypeAlias, Param, Path, Pattern,
Recoverable, Statement, TraitBound, TypeImpl, UnaryRhsMemberAccess, UnaryRhsMethodCall,
UnresolvedTraitConstraint, UseTree, UseTreeKind, Visibility,
UseTree, UseTreeKind, Visibility,
};
use crate::ast::{
Expression, ExpressionKind, LetStatement, StatementKind, UnresolvedType, UnresolvedTypeData,
Expand Down Expand Up @@ -71,6 +71,7 @@ mod test_helpers;
use literals::literal;
use path::{maybe_empty_path, path};
use primitives::{dereference, ident, negation, not, nothing, right_shift_operator, token_kind};
use traits::where_clause;

/// Entry function for the parser - also handles lexing internally.
///
Expand Down Expand Up @@ -365,45 +366,8 @@ fn function_declaration_parameters() -> impl NoirParser<Vec<(Ident, UnresolvedTy
.labelled(ParsingRuleLabel::Parameter)
}

fn where_clause() -> impl NoirParser<Vec<UnresolvedTraitConstraint>> {
struct MultiTraitConstraint {
typ: UnresolvedType,
trait_bounds: Vec<TraitBound>,
}

let constraints = parse_type()
.then_ignore(just(Token::Colon))
.then(trait_bounds())
.map(|(typ, trait_bounds)| MultiTraitConstraint { typ, trait_bounds });

keyword(Keyword::Where)
.ignore_then(constraints.separated_by(just(Token::Comma)))
.or_not()
.map(|option| option.unwrap_or_default())
.map(|x: Vec<MultiTraitConstraint>| {
let mut result: Vec<UnresolvedTraitConstraint> = Vec::new();
for constraint in x {
for bound in constraint.trait_bounds {
result.push(UnresolvedTraitConstraint {
typ: constraint.typ.clone(),
trait_bound: bound,
});
}
}
result
})
}

fn trait_bounds() -> impl NoirParser<Vec<TraitBound>> {
trait_bound().separated_by(just(Token::Plus)).at_least(1).allow_trailing()
}

pub fn trait_bound() -> impl NoirParser<TraitBound> {
path().then(generic_type_args(parse_type())).map(|(trait_path, trait_generics)| TraitBound {
trait_path,
trait_generics,
trait_id: None,
})
traits::trait_bound()
}

fn block_expr<'a>(
Expand Down
7 changes: 4 additions & 3 deletions compiler/noirc_frontend/src/parser/parser/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ fn trait_implementation_body() -> impl NoirParser<Vec<TraitImplItem>> {
function.or(alias).repeated()
}

fn where_clause() -> impl NoirParser<Vec<UnresolvedTraitConstraint>> {
pub(super) fn where_clause() -> impl NoirParser<Vec<UnresolvedTraitConstraint>> {
struct MultiTraitConstraint {
typ: UnresolvedType,
trait_bounds: Vec<TraitBound>,
Expand All @@ -163,7 +163,7 @@ fn where_clause() -> impl NoirParser<Vec<UnresolvedTraitConstraint>> {
.map(|(typ, trait_bounds)| MultiTraitConstraint { typ, trait_bounds });

keyword(Keyword::Where)
.ignore_then(constraints.separated_by(just(Token::Comma)))
.ignore_then(constraints.separated_by(just(Token::Comma)).allow_trailing())
.or_not()
.map(|option| option.unwrap_or_default())
.map(|x: Vec<MultiTraitConstraint>| {
Expand All @@ -184,7 +184,7 @@ fn trait_bounds() -> impl NoirParser<Vec<TraitBound>> {
trait_bound().separated_by(just(Token::Plus)).at_least(1).allow_trailing()
}

fn trait_bound() -> impl NoirParser<TraitBound> {
pub(super) fn trait_bound() -> impl NoirParser<TraitBound> {
path().then(generic_type_args(parse_type())).map(|(trait_path, trait_generics)| TraitBound {
trait_path,
trait_generics,
Expand Down Expand Up @@ -215,6 +215,7 @@ mod test {
"trait GenericTrait<T> { fn elem(&mut self, index: Field) -> T; }",
"trait GenericTraitWithConstraints<T> where T: SomeTrait { fn elem(self, index: Field) -> T; }",
"trait TraitWithMultipleGenericParams<A, B, C> where A: SomeTrait, B: AnotherTrait<C> { let Size: Field; fn zero() -> Self; }",
"trait TraitWithMultipleGenericParams<A, B, C> where A: SomeTrait, B: AnotherTrait<C>, { let Size: Field; fn zero() -> Self; }",
],
);

Expand Down