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
12 changes: 5 additions & 7 deletions compiler/noirc_frontend/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,11 @@ impl UnresolvedTypeExpression {

fn from_expr_helper(expr: Expression) -> Result<UnresolvedTypeExpression, Expression> {
match expr.kind {
ExpressionKind::Literal(Literal::Integer(int, sign)) => {
assert!(!sign, "Negative literal is not allowed here");
match int.try_to_u32() {
Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)),
None => Err(expr),
}
}
// TODO(https://github.com/noir-lang/noir/issues/5571): The `sign` bool from `Literal::Integer` should be used to construct the constant type expression.
ExpressionKind::Literal(Literal::Integer(int, _)) => match int.try_to_u32() {
Some(int) => Ok(UnresolvedTypeExpression::Constant(int, expr.span)),
None => Err(expr),
},
ExpressionKind::Variable(path, _) => Ok(UnresolvedTypeExpression::Variable(path)),
ExpressionKind::Prefix(prefix) if prefix.operator == UnaryOp::Minus => {
let lhs = Box::new(UnresolvedTypeExpression::Constant(0, expr.span));
Expand Down
4 changes: 4 additions & 0 deletions compiler/noirc_frontend/src/parser/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ pub enum ParserErrorReason {
InvalidBitSize(u32),
#[error("{0}")]
Lexer(LexerErrorKind),
// TODO(https://github.com/noir-lang/noir/issues/5571): This error can be removed once support is expanded for type-level integers.
// This error reason was added to prevent the panic outline in this issue: https://github.com/noir-lang/noir/issues/5552.
#[error("Only unsigned integers allowed for numeric generics")]
SignedNumericGeneric,
}

/// Represents a parsing error, or a parsing error in the making.
Expand Down
26 changes: 22 additions & 4 deletions compiler/noirc_frontend/src/parser/parser/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ use super::{
parameter_name_recovery, parameter_recovery, parenthesized, parse_type, pattern,
self_parameter, where_clause, NoirParser,
};
use crate::ast::{
FunctionDefinition, FunctionReturnType, ItemVisibility, NoirFunction, Param, Visibility,
};
use crate::parser::spanned;
use crate::token::{Keyword, Token};
use crate::{
ast::{UnresolvedGeneric, UnresolvedGenerics},
ast::{
FunctionDefinition, FunctionReturnType, ItemVisibility, NoirFunction, Param, Visibility,
},
macros_api::UnresolvedTypeData,
parser::{ParserError, ParserErrorReason},
};
use crate::{
ast::{Signedness, UnresolvedGeneric, UnresolvedGenerics},
parser::labels::ParsingRuleLabel,
};

Expand Down Expand Up @@ -85,6 +89,19 @@ pub(super) fn numeric_generic() -> impl NoirParser<UnresolvedGeneric> {
.then_ignore(just(Token::Colon))
.then(parse_type())
.map(|(ident, typ)| UnresolvedGeneric::Numeric { ident, typ })
.validate(|generic, span, emit| {
if let UnresolvedGeneric::Numeric { typ, .. } = &generic {
if let UnresolvedTypeData::Integer(signedness, _) = typ.typ {
if matches!(signedness, Signedness::Signed) {
emit(ParserError::with_reason(
ParserErrorReason::SignedNumericGeneric,
span,
));
}
}
}
generic
})
}

pub(super) fn generic_type() -> impl NoirParser<UnresolvedGeneric> {
Expand Down Expand Up @@ -233,6 +250,7 @@ mod test {
"fn func_name<let T:>(y: T) {}",
"fn func_name<T:>(y: T) {}",
"fn func_name<T: u64>(y: T) {}",
"fn func_name<let N: i8>() {}",
],
);
}
Expand Down