Skip to content

Commit

Permalink
feat: add more Type and UnresolvedType methods (noir-lang/noir#5994)
Browse files Browse the repository at this point in the history
fix: Panic on composite types within databus (noir-lang/noir#6225)
feat(perf): Follow array sets backwards in array set from get optimization (noir-lang/noir#6208)
fix: check for Schnorr null signature (noir-lang/noir#6226)
  • Loading branch information
AztecBot committed Oct 7, 2024
2 parents dfc1444 + d67386c commit a256d70
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
999071b80e61a37cb994a4e359eabbac27cd53f1
8236cbdff60c1aaf41fc53142b6f0f9ea2fc2fa8
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,18 @@ impl FunctionBuilder {
databus.index += 1;
}
Type::Array(typ, len) => {
assert!(typ.len() == 1, "unsupported composite type");
databus.map.insert(value, databus.index);
for i in 0..len {
// load each element of the array
let index = self
.current_function
.dfg
.make_constant(FieldElement::from(i as i128), Type::length_type());
let element = self.insert_array_get(value, index, typ[0].clone());
self.add_to_data_bus(element, databus);
for (subitem_index, subitem_typ) in typ.iter().enumerate() {
let index = i * typ.len() + subitem_index;
// load each element of the array
let index = self
.current_function
.dfg
.make_constant(FieldElement::from(index as i128), Type::length_type());
let element = self.insert_array_get(value, index, subitem_typ.clone());
self.add_to_data_bus(element, databus);
}
}
}
Type::Reference(_) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"type_as_array" => type_as_array(arguments, return_type, location),
"type_as_constant" => type_as_constant(arguments, return_type, location),
"type_as_integer" => type_as_integer(arguments, return_type, location),
"type_as_mutable_reference" => {
type_as_mutable_reference(arguments, return_type, location)
}
"type_as_slice" => type_as_slice(arguments, return_type, location),
"type_as_str" => type_as_str(arguments, return_type, location),
"type_as_struct" => type_as_struct(arguments, return_type, location),
Expand All @@ -205,14 +208,23 @@ impl<'local, 'context> Interpreter<'local, 'context> {
"type_implements" => type_implements(interner, arguments, location),
"type_is_bool" => type_is_bool(arguments, location),
"type_is_field" => type_is_field(arguments, location),
"type_is_unit" => type_is_unit(arguments, location),
"type_of" => type_of(arguments, location),
"typed_expr_as_function_definition" => {
typed_expr_as_function_definition(interner, arguments, return_type, location)
}
"typed_expr_get_type" => {
typed_expr_get_type(interner, arguments, return_type, location)
}
"unresolved_type_as_mutable_reference" => {
unresolved_type_as_mutable_reference(interner, arguments, return_type, location)
}
"unresolved_type_as_slice" => {
unresolved_type_as_slice(interner, arguments, return_type, location)
}
"unresolved_type_is_bool" => unresolved_type_is_bool(interner, arguments, location),
"unresolved_type_is_field" => unresolved_type_is_field(interner, arguments, location),
"unresolved_type_is_unit" => unresolved_type_is_unit(interner, arguments, location),
"zeroed" => zeroed(return_type),
_ => {
let item = format!("Comptime evaluation for builtin function {name}");
Expand Down Expand Up @@ -855,6 +867,21 @@ fn type_as_integer(
})
}

// fn as_mutable_reference(self) -> Option<Type>
fn type_as_mutable_reference(
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
) -> IResult<Value> {
type_as(arguments, return_type, location, |typ| {
if let Type::MutableReference(typ) = typ {
Some(Value::Type(*typ))
} else {
None
}
})
}

// fn as_slice(self) -> Option<Type>
fn type_as_slice(
arguments: Vec<(Value, Location)>,
Expand Down Expand Up @@ -1013,6 +1040,14 @@ fn type_is_field(arguments: Vec<(Value, Location)>, location: Location) -> IResu
Ok(Value::Bool(matches!(typ, Type::FieldElement)))
}

// fn is_unit(self) -> bool
fn type_is_unit(arguments: Vec<(Value, Location)>, location: Location) -> IResult<Value> {
let value = check_one_argument(arguments, location)?;
let typ = get_type(value)?;

Ok(Value::Bool(matches!(typ, Type::Unit)))
}

// fn type_of<T>(x: T) -> Type
fn type_of(arguments: Vec<(Value, Location)>, location: Location) -> IResult<Value> {
let (value, _) = check_one_argument(arguments, location)?;
Expand Down Expand Up @@ -1115,6 +1150,49 @@ fn typed_expr_get_type(
option(return_type, option_value)
}

// fn as_mutable_reference(self) -> Option<UnresolvedType>
fn unresolved_type_as_mutable_reference(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
) -> IResult<Value> {
unresolved_type_as(interner, arguments, return_type, location, |typ| {
if let UnresolvedTypeData::MutableReference(typ) = typ {
Some(Value::UnresolvedType(typ.typ))
} else {
None
}
})
}

// fn as_slice(self) -> Option<UnresolvedType>
fn unresolved_type_as_slice(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
) -> IResult<Value> {
unresolved_type_as(interner, arguments, return_type, location, |typ| {
if let UnresolvedTypeData::Slice(typ) = typ {
Some(Value::UnresolvedType(typ.typ))
} else {
None
}
})
}

// fn is_bool(self) -> bool
fn unresolved_type_is_bool(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
let self_argument = check_one_argument(arguments, location)?;
let typ = get_unresolved_type(interner, self_argument)?;
Ok(Value::Bool(matches!(typ, UnresolvedTypeData::Bool)))
}

// fn is_field(self) -> bool
fn unresolved_type_is_field(
interner: &NodeInterner,
Expand All @@ -1126,6 +1204,36 @@ fn unresolved_type_is_field(
Ok(Value::Bool(matches!(typ, UnresolvedTypeData::FieldElement)))
}

// fn is_unit(self) -> bool
fn unresolved_type_is_unit(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
location: Location,
) -> IResult<Value> {
let self_argument = check_one_argument(arguments, location)?;
let typ = get_unresolved_type(interner, self_argument)?;
Ok(Value::Bool(matches!(typ, UnresolvedTypeData::Unit)))
}

// Helper function for implementing the `unresolved_type_as_...` functions.
fn unresolved_type_as<F>(
interner: &NodeInterner,
arguments: Vec<(Value, Location)>,
return_type: Type,
location: Location,
f: F,
) -> IResult<Value>
where
F: FnOnce(UnresolvedTypeData) -> Option<Value>,
{
let value = check_one_argument(arguments, location)?;
let typ = get_unresolved_type(interner, value)?;

let option_value = f(typ);

option(return_type, option_value)
}

// fn zeroed<T>() -> T
fn zeroed(return_type: Type) -> IResult<Value> {
match return_type {
Expand Down
12 changes: 12 additions & 0 deletions noir/noir-repo/docs/docs/noir/standard_library/meta/typ.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ return the numeric constant.
If this is an integer type, return a boolean which is `true`
if the type is signed, as well as the number of bits of this integer type.

### as_mutable_reference

#include_code as_mutable_reference noir_stdlib/src/meta/typ.nr rust

If this is a mutable reference type `&mut T`, returns the mutable type `T`.

### as_slice

#include_code as_slice noir_stdlib/src/meta/typ.nr rust
Expand Down Expand Up @@ -146,6 +152,12 @@ fn foo<T>() where T: Default {

`true` if this type is `Field`.

### is_unit

#include_code is_unit noir_stdlib/src/meta/typ.nr rust

`true` if this type is the unit `()` type.

## Trait Implementations

```rust
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,32 @@ title: UnresolvedType

## Methods

### as_mutable_reference

#include_code as_mutable_reference noir_stdlib/src/meta/unresolved_type.nr rust

If this is a mutable reference type `&mut T`, returns the mutable type `T`.

### as_slice

#include_code as_slice noir_stdlib/src/meta/unresolved_type.nr rust

If this is a slice `&[T]`, returns the element type `T`.

### is_bool

#include_code is_bool noir_stdlib/src/meta/unresolved_type.nr rust

Returns `true` if this type is `bool`.

### is_field

#include_code is_field noir_stdlib/src/meta/unresolved_type.nr rust

Returns true if this type refers to the Field type.

### is_unit

#include_code is_unit noir_stdlib/src/meta/unresolved_type.nr rust

Returns true if this type is the unit `()` type.
Loading

0 comments on commit a256d70

Please sign in to comment.