Skip to content

Commit

Permalink
feat: add Expr::as_cast and UnresolvedType::is_field (#5801)
Browse files Browse the repository at this point in the history
# Description

## Problem

Part of #5668

## Summary

Introduces `UnresolvedType` from one of Expr variants (cast) and adds
`UnresolvedType::is_field` just to assert something about the returned
type.

## Additional Context

None.

## Documentation

Check one:
- [ ] No documentation needed.
- [ ] Documentation included in this PR.
- [x] **[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 Aug 22, 2024
1 parent 619fa5c commit c9aa50d
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 11 deletions.
18 changes: 18 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"expr_as_binary_op" => expr_as_binary_op(arguments, return_type, location),
"expr_as_block" => expr_as_block(arguments, return_type, location),
"expr_as_bool" => expr_as_bool(arguments, return_type, location),
"expr_as_cast" => expr_as_cast(arguments, return_type, location),
"expr_as_comptime" => expr_as_comptime(arguments, return_type, location),
"expr_as_function_call" => expr_as_function_call(arguments, return_type, location),
"expr_as_if" => expr_as_if(arguments, return_type, location),
Expand Down Expand Up @@ -860,6 +861,23 @@ fn expr_as_bool(
})
}

// fn as_cast(self) -> Option<(Expr, UnresolvedType)>
fn expr_as_cast(
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
) -> IResult<Value> {
expr_as(arguments, return_type, location, |expr| {
if let ExprValue::Expression(ExpressionKind::Cast(cast)) = expr {
let lhs = Value::expression(cast.lhs.kind);
let typ = Value::UnresolvedType(cast.r#type.typ);
Some(Value::Tuple(vec![lhs, typ]))
} else {
None
}
})
}

// fn as_comptime(self) -> Option<[Expr]>
fn expr_as_comptime(
arguments: Vec<(Value, Location)>,
Expand Down
7 changes: 6 additions & 1 deletion compiler/noirc_frontend/src/hir/comptime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use strum_macros::Display;
use crate::{
ast::{
ArrayLiteral, BlockExpression, ConstructorExpression, Ident, IntegerBitSize, Signedness,
Statement, StatementKind,
Statement, StatementKind, UnresolvedTypeData,
},
hir::def_map::ModuleId,
hir_def::{
Expand Down Expand Up @@ -66,6 +66,7 @@ pub enum Value {
Type(Type),
Zeroed(Type),
Expr(ExprValue),
UnresolvedType(UnresolvedTypeData),
}

#[derive(Debug, Clone, PartialEq, Eq, Display)]
Expand Down Expand Up @@ -128,6 +129,7 @@ impl Value {
Value::Type(_) => Type::Quoted(QuotedType::Type),
Value::Zeroed(typ) => return Cow::Borrowed(typ),
Value::Expr(_) => Type::Quoted(QuotedType::Expr),
Value::UnresolvedType(_) => Type::Quoted(QuotedType::UnresolvedType),
})
}

Expand Down Expand Up @@ -262,6 +264,7 @@ impl Value {
| Value::FunctionDefinition(_)
| Value::Zeroed(_)
| Value::Type(_)
| Value::UnresolvedType(_)
| Value::ModuleDefinition(_) => {
let typ = self.get_type().into_owned();
let value = self.display(interner).to_string();
Expand Down Expand Up @@ -386,6 +389,7 @@ impl Value {
| Value::FunctionDefinition(_)
| Value::Zeroed(_)
| Value::Type(_)
| Value::UnresolvedType(_)
| Value::ModuleDefinition(_) => {
let typ = self.get_type().into_owned();
let value = self.display(interner).to_string();
Expand Down Expand Up @@ -588,6 +592,7 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> {
Value::Type(typ) => write!(f, "{}", typ),
Value::Expr(ExprValue::Expression(expr)) => write!(f, "{}", expr),
Value::Expr(ExprValue::Statement(statement)) => write!(f, "{}", statement),
Value::UnresolvedType(typ) => write!(f, "{}", typ),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ pub enum QuotedType {
TraitConstraint,
TraitDefinition,
TraitImpl,
UnresolvedType,
FunctionDefinition,
Module,
}
Expand Down Expand Up @@ -744,6 +745,7 @@ impl std::fmt::Display for QuotedType {
QuotedType::TraitDefinition => write!(f, "TraitDefinition"),
QuotedType::TraitConstraint => write!(f, "TraitConstraint"),
QuotedType::TraitImpl => write!(f, "TraitImpl"),
QuotedType::UnresolvedType => write!(f, "UnresolvedType"),
QuotedType::FunctionDefinition => write!(f, "FunctionDefinition"),
QuotedType::Module => write!(f, "Module"),
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/noirc_frontend/src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,7 @@ pub enum Keyword {
TypeType,
Unchecked,
Unconstrained,
UnresolvedType,
Unsafe,
Use,
Where,
Expand Down Expand Up @@ -984,6 +985,7 @@ impl fmt::Display for Keyword {
Keyword::TypeType => write!(f, "Type"),
Keyword::Unchecked => write!(f, "unchecked"),
Keyword::Unconstrained => write!(f, "unconstrained"),
Keyword::UnresolvedType => write!(f, "UnresolvedType"),
Keyword::Unsafe => write!(f, "unsafe"),
Keyword::Use => write!(f, "use"),
Keyword::Where => write!(f, "where"),
Expand Down Expand Up @@ -1041,6 +1043,7 @@ impl Keyword {
"StructDefinition" => Keyword::StructDefinition,
"unchecked" => Keyword::Unchecked,
"unconstrained" => Keyword::Unconstrained,
"UnresolvedType" => Keyword::UnresolvedType,
"unsafe" => Keyword::Unsafe,
"use" => Keyword::Use,
"where" => Keyword::Where,
Expand Down
33 changes: 23 additions & 10 deletions compiler/noirc_frontend/src/parser/parser/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,7 @@ pub(super) fn parse_type_inner<'a>(
int_type(),
bool_type(),
string_type(),
expr_type(),
struct_definition_type(),
trait_constraint_type(),
trait_definition_type(),
trait_impl_type(),
function_definition_type(),
module_type(),
top_level_item_type(),
type_of_quoted_types(),
quoted_type(),
comptime_type(),
resolved_type(),
format_string_type(recursive_type_parser.clone()),
named_type(recursive_type_parser.clone()),
Expand Down Expand Up @@ -82,6 +73,22 @@ pub(super) fn bool_type() -> impl NoirParser<UnresolvedType> {
keyword(Keyword::Bool).map_with_span(|_, span| UnresolvedTypeData::Bool.with_span(span))
}

pub(super) fn comptime_type() -> impl NoirParser<UnresolvedType> {
choice((
expr_type(),
struct_definition_type(),
trait_constraint_type(),
trait_definition_type(),
trait_impl_type(),
unresolved_type_type(),
function_definition_type(),
module_type(),
type_of_quoted_types(),
top_level_item_type(),
quoted_type(),
))
}

/// This is the type `Expr` - the type of a quoted, untyped expression object used for macros
pub(super) fn expr_type() -> impl NoirParser<UnresolvedType> {
keyword(Keyword::Expr)
Expand Down Expand Up @@ -113,6 +120,12 @@ pub(super) fn trait_impl_type() -> impl NoirParser<UnresolvedType> {
.map_with_span(|_, span| UnresolvedTypeData::Quoted(QuotedType::TraitImpl).with_span(span))
}

pub(super) fn unresolved_type_type() -> impl NoirParser<UnresolvedType> {
keyword(Keyword::UnresolvedType).map_with_span(|_, span| {
UnresolvedTypeData::Quoted(QuotedType::UnresolvedType).with_span(span)
})
}

pub(super) fn function_definition_type() -> impl NoirParser<UnresolvedType> {
keyword(Keyword::FunctionDefinition).map_with_span(|_, span| {
UnresolvedTypeData::Quoted(QuotedType::FunctionDefinition).with_span(span)
Expand Down
13 changes: 13 additions & 0 deletions noir_stdlib/src/meta/expr.nr
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ impl Expr {
#[builtin(expr_as_bool)]
fn as_bool(self) -> Option<bool> {}

#[builtin(expr_as_cast)]
fn as_cast(self) -> Option<(Expr, UnresolvedType)> {}

#[builtin(expr_as_comptime)]
fn as_comptime(self) -> Option<[Expr]> {}

Expand Down Expand Up @@ -140,6 +143,16 @@ mod tests {
}
}

#[test]
fn test_expr_as_cast() {
comptime
{
let expr = quote { 1 as Field }.as_expr().unwrap();
let (expr, _typ) = expr.as_cast().unwrap();
assert_eq(expr.as_integer().unwrap(), (1, false));
}
}

#[test]
fn test_expr_as_comptime() {
comptime
Expand Down
2 changes: 2 additions & 0 deletions tooling/lsp/src/requests/completion/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub(super) fn keyword_builtin_type(keyword: &Keyword) -> Option<&'static str> {
Keyword::TraitDefinition => Some("TraitDefinition"),
Keyword::TraitImpl => Some("TraitImpl"),
Keyword::TypeType => Some("Type"),
Keyword::UnresolvedType => Some("UnresolvedType"),

Keyword::As
| Keyword::Assert
Expand Down Expand Up @@ -183,6 +184,7 @@ pub(super) fn keyword_builtin_function(keyword: &Keyword) -> Option<BuiltInFunct
| Keyword::TypeType
| Keyword::Unchecked
| Keyword::Unconstrained
| Keyword::UnresolvedType
| Keyword::Unsafe
| Keyword::Use
| Keyword::Where
Expand Down

0 comments on commit c9aa50d

Please sign in to comment.