Skip to content

Commit

Permalink
feat: unquote some value as tokens, not as unquote markers (#5924)
Browse files Browse the repository at this point in the history
# Description

## Problem

Resolves #5916

## Summary

## Additional Context

I think there might be other `Value`s that we could convert into tokens,
like `String`, but I didn't want to handle those in this PR (should it
be `Str` or `RawStr`? etc.). And it's possible that we only need this
special logic for integers anyway.

## Documentation

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
asterite authored Sep 4, 2024
1 parent 91f693d commit 70ebb90
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
37 changes: 37 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ impl Value {
location: Location,
) -> IResult<Vec<Token>> {
let token = match self {
Value::Unit => {
return Ok(vec![Token::LeftParen, Token::RightParen]);
}
Value::Quoted(tokens) => return Ok(unwrap_rc(tokens)),
Value::Type(typ) => Token::QuotedType(interner.push_quoted_type(typ)),
Value::Expr(ExprValue::Expression(expr)) => {
Expand All @@ -443,6 +446,40 @@ impl Value {
Value::UnresolvedType(typ) => {
Token::InternedUnresolvedTypeData(interner.push_unresolved_type_data(typ))
}
Value::U1(bool) => Token::Bool(bool),
Value::U8(value) => Token::Int((value as u128).into()),
Value::U16(value) => Token::Int((value as u128).into()),
Value::U32(value) => Token::Int((value as u128).into()),
Value::U64(value) => Token::Int((value as u128).into()),
Value::I8(value) => {
if value < 0 {
return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]);
} else {
Token::Int((value as u128).into())
}
}
Value::I16(value) => {
if value < 0 {
return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]);
} else {
Token::Int((value as u128).into())
}
}
Value::I32(value) => {
if value < 0 {
return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]);
} else {
Token::Int((value as u128).into())
}
}
Value::I64(value) => {
if value < 0 {
return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]);
} else {
Token::Int((value as u128).into())
}
}
Value::Field(value) => Token::Int(value),
other => Token::UnquoteMarker(other.into_hir_expression(interner, location)?),
};
Ok(vec![token])
Expand Down
28 changes: 28 additions & 0 deletions compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3341,3 +3341,31 @@ fn warns_on_re_export_of_item_with_less_visibility() {
)
));
}

#[test]
fn unoquted_integer_as_integer_token() {
let src = r#"
trait Serialize<let N: u32> {
fn serialize() {}
}
#[attr]
fn foobar() {}
fn attr(_f: FunctionDefinition) -> Quoted {
let serialized_len = 1;
// We are testing that when we unoqute $serialized_len, it's unquoted
// as the token `1` and not as something else that later won't be parsed correctly
// in the context of a generic argument.
quote {
impl Serialize<$serialized_len> for Field {
fn serialize() { }
}
}
}
fn main() {}
"#;

assert_no_errors(src);
}

0 comments on commit 70ebb90

Please sign in to comment.