Skip to content

Commit

Permalink
fix: parse Slice type in SSa (#6507)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Nov 12, 2024
1 parent 72e8de0 commit 34ad666
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 15 deletions.
31 changes: 31 additions & 0 deletions compiler/noirc_evaluator/src/ssa/opt/as_slice_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,34 @@ fn replace_known_slice_lengths(
func.dfg.set_value_from_id(original_slice_length, known_length);
});
}

#[cfg(test)]
mod test {
use crate::ssa::opt::assert_normalized_ssa_equals;

use super::Ssa;

#[test]
fn as_slice_length_optimization() {
// In this code we expect `return v2` to be replaced with `return u32 3` because
// that's the length of the v0 array.
let src = "
acir(inline) fn main f0 {
b0(v0: [Field; 3]):
v2, v3 = call as_slice(v0) -> (u32, [Field])
return v2
}
";
let ssa = Ssa::from_str(src).unwrap();

let expected = "
acir(inline) fn main f0 {
b0(v0: [Field; 3]):
v2, v3 = call as_slice(v0) -> (u32, [Field])
return u32 3
}
";
let ssa = ssa.as_slice_optimization();
assert_normalized_ssa_equals(ssa, expected);
}
}
32 changes: 18 additions & 14 deletions compiler/noirc_evaluator/src/ssa/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ impl Debug for SsaErrorWithSource {
pub(crate) enum SsaError {
#[error("{0}")]
ParserError(ParserError),
#[error("Unknown variable `{0}`")]
#[error("Unknown variable '{0}'")]
UnknownVariable(Identifier),
#[error("Unknown block `{0}`")]
#[error("Unknown block '{0}'")]
UnknownBlock(Identifier),
#[error("Unknown function `{0}`")]
#[error("Unknown function '{0}'")]
UnknownFunction(Identifier),
#[error("Mismatched return values")]
MismatchedReturnValues { returns: Vec<Identifier>, expected: usize },
#[error("Variable `{0}` already defined")]
#[error("Variable '{0}' already defined")]
VariableAlreadyDefined(Identifier),
}

Expand Down Expand Up @@ -647,10 +647,14 @@ impl<'a> Parser<'a> {

if self.eat(Token::LeftBracket)? {
let element_types = self.parse_types()?;
self.eat_or_error(Token::Semicolon)?;
let length = self.eat_int_or_error()?;
self.eat_or_error(Token::RightBracket)?;
return Ok(Type::Array(Arc::new(element_types), length.to_u128() as usize));
if self.eat(Token::Semicolon)? {
let length = self.eat_int_or_error()?;
self.eat_or_error(Token::RightBracket)?;
return Ok(Type::Array(Arc::new(element_types), length.to_u128() as usize));
} else {
self.eat_or_error(Token::RightBracket)?;
return Ok(Type::Slice(Arc::new(element_types)));
}
}

if let Some(typ) = self.parse_mutable_reference_type()? {
Expand Down Expand Up @@ -857,19 +861,19 @@ impl<'a> Parser<'a> {
pub(crate) enum ParserError {
#[error("{0}")]
LexerError(LexerError),
#[error("Expected {token}, found {token}")]
#[error("Expected '{token}', found '{found}'")]
ExpectedToken { token: Token, found: Token, span: Span },
#[error("Expected one of {tokens:?}, found {found}")]
ExpectedOneOfTokens { tokens: Vec<Token>, found: Token, span: Span },
#[error("Expected an identifier, found {found}")]
#[error("Expected an identifier, found '{found}'")]
ExpectedIdentifier { found: Token, span: Span },
#[error("Expected an int, found {found}")]
#[error("Expected an int, found '{found}'")]
ExpectedInt { found: Token, span: Span },
#[error("Expected a type, found {found}")]
#[error("Expected a type, found '{found}'")]
ExpectedType { found: Token, span: Span },
#[error("Expected an instruction or terminator, found {found}")]
#[error("Expected an instruction or terminator, found '{found}'")]
ExpectedInstructionOrTerminator { found: Token, span: Span },
#[error("Expected a value, found {found}")]
#[error("Expected a value, found '{found}'")]
ExpectedValue { found: Token, span: Span },
#[error("Multiple return values only allowed for call")]
MultipleReturnValuesOnlyAllowedForCall { second_target: Identifier },
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_evaluator/src/ssa/parser/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ type SpannedTokenResult = Result<SpannedToken, LexerError>;

#[derive(Debug, Error)]
pub(crate) enum LexerError {
#[error("Unexpected character: {char}")]
#[error("Unexpected character: {char:?}")]
UnexpectedCharacter { char: char, span: Span },
#[error("Invalid integer literal")]
InvalidIntegerLiteral { span: Span, found: String },
Expand Down
12 changes: 12 additions & 0 deletions compiler/noirc_evaluator/src/ssa/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,15 @@ fn test_parses_with_comments() {
let ssa = Ssa::from_str(src).unwrap();
assert_normalized_ssa_equals(ssa, expected);
}

#[test]
fn test_slice() {
let src = "
acir(inline) fn main f0 {
b0(v0: [Field; 3]):
v2, v3 = call as_slice(v0) -> (u32, [Field])
return
}
";
assert_ssa_roundtrip(src);
}

0 comments on commit 34ad666

Please sign in to comment.