From 93b2ad9932e6526170e71f535acfcbc8c0445978 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Thu, 22 Aug 2024 16:25:52 -0500 Subject: [PATCH 01/21] Add docs for each comptime method --- docs/docs/noir/standard_library/meta/expr.md | 149 ++++++++++++++++++ .../standard_library/meta/function_def.md | 55 +++++++ docs/docs/noir/standard_library/meta/mod.md | 136 ++++++++++++++++ .../docs/noir/standard_library/meta/module.md | 27 ++++ docs/docs/noir/standard_library/meta/op.md | 134 ++++++++++++++++ .../docs/noir/standard_library/meta/quoted.md | 85 ++++++++++ .../noir/standard_library/meta/struct_def.md | 45 ++++++ .../standard_library/meta/trait_constraint.md | 17 ++ .../noir/standard_library/meta/trait_def.md | 22 +++ .../noir/standard_library/meta/trait_impl.md | 52 ++++++ docs/docs/noir/standard_library/meta/typ.md | 126 +++++++++++++++ noir_stdlib/src/cmp.nr | 4 + noir_stdlib/src/hash/mod.nr | 2 + noir_stdlib/src/meta/expr.nr | 38 +++++ noir_stdlib/src/meta/function_def.nr | 12 ++ noir_stdlib/src/meta/mod.nr | 10 ++ noir_stdlib/src/meta/module.nr | 6 + noir_stdlib/src/meta/op.nr | 40 ++--- noir_stdlib/src/meta/quoted.nr | 8 + noir_stdlib/src/meta/struct_def.nr | 6 + noir_stdlib/src/meta/trait_def.nr | 2 + noir_stdlib/src/meta/trait_impl.nr | 4 + noir_stdlib/src/meta/typ.nr | 20 +++ 23 files changed, 980 insertions(+), 20 deletions(-) create mode 100644 docs/docs/noir/standard_library/meta/expr.md create mode 100644 docs/docs/noir/standard_library/meta/function_def.md create mode 100644 docs/docs/noir/standard_library/meta/mod.md create mode 100644 docs/docs/noir/standard_library/meta/module.md create mode 100644 docs/docs/noir/standard_library/meta/op.md create mode 100644 docs/docs/noir/standard_library/meta/quoted.md create mode 100644 docs/docs/noir/standard_library/meta/struct_def.md create mode 100644 docs/docs/noir/standard_library/meta/trait_constraint.md create mode 100644 docs/docs/noir/standard_library/meta/trait_def.md create mode 100644 docs/docs/noir/standard_library/meta/trait_impl.md create mode 100644 docs/docs/noir/standard_library/meta/typ.md diff --git a/docs/docs/noir/standard_library/meta/expr.md b/docs/docs/noir/standard_library/meta/expr.md new file mode 100644 index 00000000000..26e9ab896c3 --- /dev/null +++ b/docs/docs/noir/standard_library/meta/expr.md @@ -0,0 +1,149 @@ +--- +title: Expr Methods +--- + +This module contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. + +## Methods + +### as_array + +#include_code as_array noir_stdlib/src/meta/expr.nr rust + +If this expression is an array, this returns a slice of each element in the array. + +### as_integer + +#include_code as_integer noir_stdlib/src/meta/expr.nr rust + +If this element is an integer literal, return the integer as a field +as well as whether the integer is negative (true) or not (false). + +### as_binary_op + +#include_code as_binary_op noir_stdlib/src/meta/expr.nr rust + +If this expression is a binary operator operation ` `, +return the left-hand side, operator, and the right-hand side of the operation. + +### as_block + +#include_code as_block noir_stdlib/src/meta/expr.nr rust + +If this expression is a block `{ stmt1; stmt2; ...; stmtN }`, return +a slice containing each statement. + +### as_bool + +#include_code as_bool noir_stdlib/src/meta/expr.nr rust + +If this expression is a boolean literal, return that literal. + +### as_comptime + +#include_code as_comptime noir_stdlib/src/meta/expr.nr rust + +If this expression is a `comptime { stmt1; stmt2; ...; stmtN }` block, +return each statement in the block. + +### as_function_call + +#include_code as_function_call noir_stdlib/src/meta/expr.nr rust + +If this expression is a function call `foo(arg1, ..., argN)`, return +the function and a slice of each argument. + +### as_if + +#include_code as_if noir_stdlib/src/meta/expr.nr rust + +If this expression is an `if condition { then_branch } else { else_branch }`, +return the condition, then branch, and else branch. If there is no else branch, +`None` is returned for that branch instead. + +### as_index + +#include_code as_index noir_stdlib/src/meta/expr.nr rust + +If this expression is an index into an array `array[index]`, return the +array and the index. + +### as_member_access + +#include_code as_member_access noir_stdlib/src/meta/expr.nr rust + +If this expression is a member access `foo.bar`, return the struct/tuple +expression and the field. The field will be represented as a quoted value. + +### as_repeated_element_array + +#include_code as_repeated_element_array noir_stdlib/src/meta/expr.nr rust + +If this expression is a repated element array `[elem; length]`, return +the repeated element and the length expressions. + +### as_repeated_element_slice + +#include_code as_repeated_element_slice noir_stdlib/src/meta/expr.nr rust + +If this expression is a repated element slice `[elem; length]`, return +the repeated element and the length expressions. + +### as_slice + +#include_code as_slice noir_stdlib/src/meta/expr.nr rust + +If this expression is a slice literal `&[elem1, ..., elemN]`, +return each element of the slice. + +### as_tuple + +#include_code as_tuple noir_stdlib/src/meta/expr.nr rust + +If this expression is a tuple `(field1, ..., fieldN)`, +return each element of the tuple. + +### as_unary + +#include_code as_unary noir_stdlib/src/meta/expr.nr rust + +If this expression is a unary operation ` `, +return the unary operator as well as the right-hand side expression. + +### as_unsafe + +#include_code as_unsafe noir_stdlib/src/meta/expr.nr rust + +If this expression is an `unsafe { stmt1; ...; stmtN }` block, +return each statement inside in a slice. + +### has_semicolon + +#include_code has_semicolon noir_stdlib/src/meta/expr.nr rust + +`true` if this expression is trailed by a semicolon. E.g. + +``` +comptime { + let expr1 = quote { 1 + 2 }.as_expr().unwrap(); + let expr2 = quote { 1 + 2; }.as_expr().unwrap(); + + assert(expr1.as_binary_op().is_some()); + assert(expr2.as_binary_op().is_some()); + + assert(!expr1.has_semicolon()); + assert(expr2.has_semicolon()); +} +``` + +### is_break + +#include_code is_break noir_stdlib/src/meta/expr.nr rust + +`true` if this expression is `break`. + +### is_continue + +#include_code is_continue noir_stdlib/src/meta/expr.nr rust + +`true` if this expression is `continue`. diff --git a/docs/docs/noir/standard_library/meta/function_def.md b/docs/docs/noir/standard_library/meta/function_def.md new file mode 100644 index 00000000000..45378c0bc99 --- /dev/null +++ b/docs/docs/noir/standard_library/meta/function_def.md @@ -0,0 +1,55 @@ +--- +title: FunctionDefinition Methods +--- + +This module contains methods on the built-in `FunctionDefinition` type representing +a function definition in the source program. + +## Methods + +### name + +#include_code name noir_stdlib/src/meta/function_def.nr rust + +Returns the name of the function + +### parameters + +#include_code parameters noir_stdlib/src/meta/function_def.nr rust + +Returns each parameter of the function as a tuple of (parameter pattern, parameter type). + +### return_type + +#include_code return_type noir_stdlib/src/meta/function_def.nr rust + +The return type of the function. + +### set_body + +#include_code set_body noir_stdlib/src/meta/function_def.nr rust + +Mutate the function body to a new expression. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +Requires the new body to be a valid expression. + +### set_parameters + +#include_code set_parameters noir_stdlib/src/meta/function_def.nr rust + +Mutates the function's parameters to a new set of parameters. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. + +Expects a slice of (parameter pattern, parameter type) for each parameter. Requires +each parameter pattern to be a syntactically valid parameter. + +### set_return_type + +#include_code set_return_type noir_stdlib/src/meta/function_def.nr rust + +Mutates the function's return type to a new type. This is only valid +on functions in the current crate which have not yet been resolved. +This means any functions called at compile-time are invalid targets for this method. diff --git a/docs/docs/noir/standard_library/meta/mod.md b/docs/docs/noir/standard_library/meta/mod.md new file mode 100644 index 00000000000..1ee826474df --- /dev/null +++ b/docs/docs/noir/standard_library/meta/mod.md @@ -0,0 +1,136 @@ +--- +title: Metaprogramming Module +--- + +## Functions + +### type_of + +#include_code type_of noir_stdlib/src/meta/mod.nr rust + +Returns the type of a variable at compile-time. + +Example: +```rs +comptime { + let x: i32 = 1; + let x_type: Type = std::meta::type_of(x); + + assert_eq(x_type, quote { i32 }.as_type()); +} +``` + +### unquote + +#include_code unquote noir_stdlib/src/meta/mod.nr rust + +Unquotes the passed-in token stream where this function was called. + +Example: +```rs +comptime { + let code = quote { 1 + 2 }; + + // let x = 1 + 2; + let x = unquote!(code); +} +``` + +### derive + +#include_code derive noir_stdlib/src/meta/mod.nr rust + +Attribute placed on struct definitions. + +Creates a trait impl for each trait passed in as an argument. +To do this, the trait must have a derive handler registered +with `derive_via` beforehand. The traits in the stdlib that +can be derived this way are `Eq`, `Ord`, `Default`, and `Hash`. + +Example: +```rs +#[derive(Eq, Default)] +struct Foo { + x: i32, + y: T, +} + +fn main() { + let foo1 = Foo::default(); + let foo2 = Foo { x: 0, y: &[0] }; + assert_eq(foo1, foo2); +} +``` + +### derive_via + +#include_code derive_via noir_stdlib/src/meta/mod.nr rust + +Attribute placed on trait definitions. + +Registers a function to create impls for the given trait +when the trait is used in a `derive` call. Users may use +this to register their own functions to enable their traits +to be derived by `derive`. + +Because this function requires a function as an argument which +should produce a trait impl for any given struct, users may find +it helpful to use a function like `std::meta::make_trait_impl` to +help creating these impls. + +Example: +```rs +#[derive_via(derive_do_nothing)] +trait DoNothing { + fn do_nothing(self); +} + +comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { + let typ = s.as_type(); + quote { + impl DoNothing for $typ { + fn do_nothing(self) { + println("Nothing"); + } + } + } +} +``` + +As another example, `derive_eq` in the stdlib is used to derive the `Eq` +trait for any struct. It makes use of `make_trait_impl` to do this: + +#include_code derive_eq noir_stdlib/src/cmp.nr rust + +### make_trait_impl + +#include_code make_trait_impl noir_stdlib/src/meta/mod.nr rust + +A helper function to more easily create trait impls while deriving traits. + +Note that this function only works for traits which: +1. Have only one method +2. Have no generics on the trait itself. + - E.g. Using this on a trait such as `trait Foo { ... }` will result in the + generated impl incorrectly missing the `T` generic. + +If your trait fits these criteria then `make_trait_impl` is likely the easiest +way to write your derive handler. The arguments are as follows: + +- `s`: The struct to make the impl for +- `trait_name`: The name of the trait to derive. E.g. `quote { Eq }`. +- `function_signature`: The signature of the trait method to derive. E.g. `fn eq(self, other: Self) -> bool`. +- `for_each_field`: An operation to be performed on each field. E.g. `|name| quote { (self.$name == other.$name) }`. +- `join_fields_with`: A separator to join each result of `for_each_field` with. + E.g. `quote { & }`. You can also use an empty `quote {}` for no separator. +- `body`: The result of the field operations are passed into this function for any final processing. + This is the place to insert any setup/teardown code the trait requires. If the trait doesn't require + any such code, you can return the body as-is: `|body| body`. + +Example deriving `Hash`: + +#include_code derive_hash noir_stdlib/src/hash/mod.nr rust + +Example deriving `Ord`: + +#include_code derive_ord noir_stdlib/src/cmp.nr rust diff --git a/docs/docs/noir/standard_library/meta/module.md b/docs/docs/noir/standard_library/meta/module.md new file mode 100644 index 00000000000..541c8a46c1c --- /dev/null +++ b/docs/docs/noir/standard_library/meta/module.md @@ -0,0 +1,27 @@ +--- +title: Module Methods +--- + +This module contains methods on the built-in `Module` type which represents a module in the source program. +Note that this type represents a module generally, it isn't limited to only `mod my_submodule { ... }` +declarations in the source program. + +## Methods + +### name + +#include_code name noir_stdlib/src/meta/module.nr rust + +Returns the name of the module + +### functions + +#include_code functions noir_stdlib/src/meta/module.nr rust + +Returns each function in the module + +### is_contract + +#include_code is_contract noir_stdlib/src/meta/module.nr rust + +`true` if this module is a contract module (was declared via `contract foo { ... }`). diff --git a/docs/docs/noir/standard_library/meta/op.md b/docs/docs/noir/standard_library/meta/op.md new file mode 100644 index 00000000000..f42b5d8dd7e --- /dev/null +++ b/docs/docs/noir/standard_library/meta/op.md @@ -0,0 +1,134 @@ +--- +title: UnaryOp and BinaryOp Methods +--- + +This module contains the `UnaryOp` and `BinaryOp` types as well as methods on them. +These types are used to represent a unary or binary operator respectively in Noir source code. + +## Types + +### UnaryOp + +Represents a unary operator. One of `-`, `!`, `&mut`, or `*`. + +### Methods + +#### is_minus + +#include_code is_minus noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `-` + +#### is_not + +#include_code is_not noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `!` + +#### is_mutable_reference + +#include_code is_mutable_reference noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `&mut` + +#### is_dereference + +#include_code is_dereference noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `*` + +### BinaryOp + +Represents a binary operator. One of `+`, `-`, `*`, `/`, `%`, `==`, `!=`, `<`, `<=`, `>`, `>=`, `&`, `|`, `^`, `>>`, or `<<`. + +### Methods + +#### is_add + +#include_code is_add noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `+` + +#### is_subtract + +#include_code is_subtract noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `-` + +#### is_multiply + +#include_code is_multiply noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `*` + +#### is_divide + +#include_code is_divide noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `/` + +#### is_modulo + +#include_code is_modulo noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `%` + +#### is_equal + +#include_code is_equal noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `==` + +#### is_not_equal + +#include_code is_not_equal noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `!=` + +#### is_less + +#include_code is_less noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `<` + +#### is_less_equal + +#include_code is_less_equal noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `<=` + +#### is_greater + +#include_code is_greater noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `>` + +#### is_greater_equal + +#include_code is_greater_or_equal noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `>=` + +#### is_and + +#include_code is_and noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `&` + +#### is_or + +#include_code is_or noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `|` + +#### is_shift_right + +#include_code is_shift_right noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `>>` + +#### is_shift_left + +#include_code is_shift_right noir_stdlib/src/meta/expr.nr rust + +`true` if this operator is `<<` diff --git a/docs/docs/noir/standard_library/meta/quoted.md b/docs/docs/noir/standard_library/meta/quoted.md new file mode 100644 index 00000000000..776e7fc4dbe --- /dev/null +++ b/docs/docs/noir/standard_library/meta/quoted.md @@ -0,0 +1,85 @@ +--- +title: Quoted Methods +--- + +This module contains methods on the built-in `Quoted` type which represents +quoted token streams and is the result of the `quote { ... }` expression. + +## Methods + +### as_expr + +#include_code as_expr noir_stdlib/src/meta/quoted.nr rust + +Parses the quoted token stream as an expression. Returns `None` if +the expression failed to parse. + +Example: + +```rust +comptime { + let add: Expr = quote { 1 + 2 }.as_expr().unwrap(); + + let (_one, op, _two) = add.as_binary_op().unwrap(); + assert(op.is_add()); +} +``` + +### as_module + +#include_code as_module noir_stdlib/src/meta/quoted.nr rust + +Interprets this token stream as a module path leading to the name of a module. +Returns `None` if the module isn't found or this cannot be parsed as a path. + +Example: + +```rust +mod foo { + mod bar { ... } +} + +comptime { + let my_mod = quote { foo::bar }.as_module().unwrap(); + assert_eq(my_mod.name(), quote { bar }); +} +``` + +### as_trait_constraint + +#include_code as_trait_constraint noir_stdlib/src/meta/quoted.nr rust + +Interprets this token stream as a trait constraint (without an object type). +Note that this function panics instead of returning None if the token +stream does not parse and resolve to a valid trait constraint. + +Example: + +```rust +comptime { + let eq = quote { Eq }.as_trait_constraint(); + let i32_type = quote { i32 }.as_type(); + assert(i32_type.implements(eq)); +} +``` + +### as_type + +#include_code as_type noir_stdlib/src/meta/quoted.nr rust + +Interprets this token stream as a resolved type. Panics if the token +stream doesn't parse to a type or if the type isn't a valid type in scope. + +```rust +comptime { + let eq = quote { Eq }.as_trait_constraint(); + let i32_type = quote { i32 }.as_type(); + assert(i32_type.implements(eq)); +} +``` + +## Trait Implementations + +```rust +impl Eq for Quoted +``` diff --git a/docs/docs/noir/standard_library/meta/struct_def.md b/docs/docs/noir/standard_library/meta/struct_def.md new file mode 100644 index 00000000000..ba19ebe009c --- /dev/null +++ b/docs/docs/noir/standard_library/meta/struct_def.md @@ -0,0 +1,45 @@ +--- +title: StructDefinition Methods +--- + +This module contains methods on the built-in `StructDefinition` type. +This type corresponds to `struct Name { field1: Type1, ... }` items in the source program. + +## Methods + +### as_type + +#include_code as_type noir_stdlib/src/meta/struct_def.nr rust + +Returns this struct as a type in the source program. If this struct has +any generics, the generics are also included as-is. + +### generics + +#include_code generics noir_stdlib/src/meta/struct_def.nr rust + +Returns each generic on this struct. + +Example: + +``` +#[example] +struct Foo { + bar: [T; 2], + baz: Baz, +} + +comptime fn example(foo: StructDefinition) { + assert_eq(foo.generics().len(), 2); + + // Fails because `T` isn't in scope + // let t = quote { T }.as_type(); + // assert_eq(foo.generics()[0], t); +} +``` + +### fields + +#include_code fields noir_stdlib/src/meta/struct_def.nr rust + +Returns each field of this struct as a pair of (field name, field type) diff --git a/docs/docs/noir/standard_library/meta/trait_constraint.md b/docs/docs/noir/standard_library/meta/trait_constraint.md new file mode 100644 index 00000000000..dca9a41f43f --- /dev/null +++ b/docs/docs/noir/standard_library/meta/trait_constraint.md @@ -0,0 +1,17 @@ +--- +title: TraitConstraint Methods +--- + +This module contains methods on the built-in `TraitConstraint` type which represents +a trait constraint that can be used to search for a trait implementation. This is similar +syntactically to just the trait itself, but can also contain generic arguments. E.g. `Eq`, `Default`, +`BuildHasher`. + +This type currently has no methods but it can be used alongside `Type` in `implements` or `get_trait_impl`. + +## Trait Implementations + +```rust +impl Eq for TraitConstraint +impl Hash for TraitConstraint +``` diff --git a/docs/docs/noir/standard_library/meta/trait_def.md b/docs/docs/noir/standard_library/meta/trait_def.md new file mode 100644 index 00000000000..98eba9ff905 --- /dev/null +++ b/docs/docs/noir/standard_library/meta/trait_def.md @@ -0,0 +1,22 @@ +--- +title: TraitDefinition Methods +--- + +This module contains methods on the built-in `TraitDefinition` type. This type +represents trait definitions such as `trait Foo { .. }` at the top-level of a program. + +## Methods + +### as_trait_constraint + +#include_code as_trait_constraint noir_stdlib/src/meta/trait_def.nr rust + +Converts this trait into a trait constraint. If there are any generics on this +trait, they will be kept as-is without instantiating or replacing them. + +## Trait Implementations + +```rust +impl Eq for TraitDefinition +impl Hash for TraitDefinition +``` diff --git a/docs/docs/noir/standard_library/meta/trait_impl.md b/docs/docs/noir/standard_library/meta/trait_impl.md new file mode 100644 index 00000000000..d0c6086f4ca --- /dev/null +++ b/docs/docs/noir/standard_library/meta/trait_impl.md @@ -0,0 +1,52 @@ +--- +title: TraitImpl Methods +--- + +This module contains methods on the built-in `TraitImpl` type which represents a trait +implementation such as `impl Foo for Bar { ... }`. + +## Methods + +### trait_generic_args + +#include_code trait_generic_args noir_stdlib/src/meta/trait_impl.nr rust + +Returns any generic arguments on the trait of this trait implementation, if any. + +```rs +impl Foo for Bar { ... } + +comptime { + let bar_type = quote { Bar }.as_type(); + let foo = quote { Foo }.as_trait_constraint(); + + let my_impl: TraitImpl = bar_type.get_trait_impl(foo).unwrap(); + + let generics = my_impl.trait_generic_args(); + assert_eq(generics.len(), 2); + + assert_eq(generics[0], quote { i32 }.as_type()); + assert_eq(generics[1], quote { Field }.as_type()); +} +``` + +### methods + +#include_code methods noir_stdlib/src/meta/trait_impl.nr rust + +Returns each method in this trait impl. + +Example: + +```rs +comptime { + let i32_type = quote { i32 }.as_type(); + let eq = quote { Eq }.as_trait_constraint(); + + let impl_eq_for_i32: TraitImpl = i32_type.get_trait_impl(eq).unwrap(); + let methods = impl_eq_for_i32.methods(); + + assert_eq(methods.len(), 1); + assert_eq(methods[0].name(), quote { eq }); +} +``` diff --git a/docs/docs/noir/standard_library/meta/typ.md b/docs/docs/noir/standard_library/meta/typ.md new file mode 100644 index 00000000000..9476ede7543 --- /dev/null +++ b/docs/docs/noir/standard_library/meta/typ.md @@ -0,0 +1,126 @@ +--- +title: Type Methods +--- + +This module contains methods on the built-in `Type` type used for representing +a type in the source program. + +## Methods + +### as_array + +#include_code as_array noir_stdlib/src/meta/typ.nr rust + +If this type is an array, return a pair of (element type, size type). + +Example: + +```rust +comptime { + let array_type = quote { [Field; 3] }.as_type(); + let (field_type, three_type) = array_type.as_array().unwrap(); + + assert(field_type.is_field()); + assert_eq(three_type.as_constant().unwrap(), 3); +} +``` + +### as_constant + +#include_code as_constant noir_stdlib/src/meta/typ.nr rust + +If this type is a constant integer (such as the `3` in the array type `[Field; 3]`), +return the numeric constant. + +### as_integer + +#include_code as_integer noir_stdlib/src/meta/typ.nr rust + +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_slice + +#include_code as_slice noir_stdlib/src/meta/typ.nr rust + +If this is a slice type, return the element type of the slice. + +### as_struct + +#include_code as_struct noir_stdlib/src/meta/typ.nr rust + +If this is a struct type, returns the struct in addition to +any generic arguments on this type. + +### as_tuple + +#include_code as_tuple noir_stdlib/src/meta/typ.nr rust + +If this is a tuple type, returns each element type of the tuple. + +### get_trait_impl + +#include_code get_trait_impl noir_stdlib/src/meta/typ.nr rust + +Retrieves the trait implementation that implements the given +trait constraint for this type. If the trait constraint is not +found, `None` is returned. Note that since the concrete trait implementation +for a trait constraint specified from a `where` clause is unknown, +this function will return `None` in these cases. If you only want to know +whether a type implements a true, use `implements` instead. + +Example: + +```rust +comptime { + let field_type = quote { Field }.as_type(); + let default = quote { Default }.as_trait_constraint(); + + let the_impl: TraitImpl = field_type.get_trait_impl(default).unwrap(); + assert(the_impl.methods().len(), 1); +} +``` + +### implements + +#include_code implements noir_stdlib/src/meta/typ.nr rust + +`true` if this type implements the given trait. Note that unlike +`get_trait_impl` this will also return true for any `where` constraints +in scope. + +Example: + +```rust +fn foo() where T: Default { + comptime { + let field_type = quote { Field }.as_type(); + let default = quote { Default }.as_trait_constraint(); + assert(field_type.implements(default)); + + let t = quote { T }.as_type(); + assert(t.implements(default)); + } +} +``` + +### is_bool + +#include_code is_bool noir_stdlib/src/meta/typ.nr rust + +`true` if this type is `bool`. + +### is_field + +#include_code is_field noir_stdlib/src/meta/typ.nr rust + +`true` if this type is `Field`. + +## Trait Implementations + +```rust +impl Eq for Type +``` +Note that this is syntactic equality, this is not the same as whether two types will type check +to be the same type. Unless type inference or generics are being used however, users should not +typically have to worry about this distinction. diff --git a/noir_stdlib/src/cmp.nr b/noir_stdlib/src/cmp.nr index ec979d60753..b7f473429a7 100644 --- a/noir_stdlib/src/cmp.nr +++ b/noir_stdlib/src/cmp.nr @@ -7,12 +7,14 @@ trait Eq { } // docs:end:eq-trait +// docs:start:derive_eq comptime fn derive_eq(s: StructDefinition) -> Quoted { let signature = quote { fn eq(_self: Self, _other: Self) -> bool }; let for_each_field = |name| quote { (_self.$name == _other.$name) }; let body = |fields| fields; crate::meta::make_trait_impl(s, quote { Eq }, signature, for_each_field, quote { & }, body) } +// docs:end:derive_eq impl Eq for Field { fn eq(self, other: Field) -> bool { self == other } } @@ -118,6 +120,7 @@ trait Ord { } // docs:end:ord-trait +// docs:start:derive_ord comptime fn derive_ord(s: StructDefinition) -> Quoted { let signature = quote { fn cmp(_self: Self, _other: Self) -> std::cmp::Ordering }; let for_each_field = |name| quote { @@ -132,6 +135,7 @@ comptime fn derive_ord(s: StructDefinition) -> Quoted { }; crate::meta::make_trait_impl(s, quote { Ord }, signature, for_each_field, quote {}, body) } +// docs:end:derive_ord // Note: Field deliberately does not implement Ord diff --git a/noir_stdlib/src/hash/mod.nr b/noir_stdlib/src/hash/mod.nr index d77b655398a..657e1cd8309 100644 --- a/noir_stdlib/src/hash/mod.nr +++ b/noir_stdlib/src/hash/mod.nr @@ -144,12 +144,14 @@ trait Hash { fn hash(self, state: &mut H) where H: Hasher; } +// docs:start:derive_hash comptime fn derive_hash(s: StructDefinition) -> Quoted { let name = quote { Hash }; let signature = quote { fn hash(_self: Self, _state: &mut H) where H: std::hash::Hasher }; let for_each_field = |name| quote { _self.$name.hash(_state); }; crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, |fields| fields) } +// docs:end:derive_hash // Hasher trait shall be implemented by algorithms to provide hash-agnostic means. // TODO: consider making the types generic here ([u8], [Field], etc.) diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index ad4fe5df094..ad9bde5d0a4 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -4,61 +4,99 @@ use crate::meta::op::BinaryOp; impl Expr { #[builtin(expr_as_array)] + // docs:start:as_array fn as_array(self) -> Option<[Expr]> {} + // docs:end:as_array #[builtin(expr_as_integer)] + // docs:start:as_integer fn as_integer(self) -> Option<(Field, bool)> {} + // docs:end:as_integer #[builtin(expr_as_binary_op)] + // docs:start:as_binary_op fn as_binary_op(self) -> Option<(Expr, BinaryOp, Expr)> {} + // docs:end:as_binary_op #[builtin(expr_as_block)] + // docs:start:as_block fn as_block(self) -> Option<[Expr]> {} + // docs:end:as_block #[builtin(expr_as_bool)] + // docs:start:as_bool fn as_bool(self) -> Option {} + // docs:end:as_bool #[builtin(expr_as_comptime)] + // docs:start:as_comptime fn as_comptime(self) -> Option<[Expr]> {} + // docs:end:as_comptime #[builtin(expr_as_function_call)] + // docs:start:as_function_call fn as_function_call(self) -> Option<(Expr, [Expr])> {} + // docs:end:as_function_call #[builtin(expr_as_if)] + // docs:start:as_if fn as_if(self) -> Option<(Expr, Expr, Option)> {} + // docs:end:as_if #[builtin(expr_as_index)] + // docs:start:as_index fn as_index(self) -> Option<(Expr, Expr)> {} + // docs:end:as_index #[builtin(expr_as_member_access)] + // docs:start:as_member_access fn as_member_access(self) -> Option<(Expr, Quoted)> {} + // docs:end:as_member_access #[builtin(expr_as_repeated_element_array)] + // docs:start:as_repeated_element_array fn as_repeated_element_array(self) -> Option<(Expr, Expr)> {} + // docs:end:as_repeated_element_array #[builtin(expr_as_repeated_element_slice)] + // docs:start:as_repeated_element_slice fn as_repeated_element_slice(self) -> Option<(Expr, Expr)> {} + // docs:end:as_repeated_element_slice #[builtin(expr_as_slice)] + // docs:start:as_slice fn as_slice(self) -> Option<[Expr]> {} + // docs:end:as_slice #[builtin(expr_as_tuple)] + // docs:start:as_tuple fn as_tuple(self) -> Option<[Expr]> {} + // docs:end:as_tuple #[builtin(expr_as_unary_op)] + // docs:start:as_unary_op fn as_unary_op(self) -> Option<(UnaryOp, Expr)> {} + // docs:end:as_unary_op #[builtin(expr_as_unsafe)] + // docs:start:as_unsafe fn as_unsafe(self) -> Option<[Expr]> {} + // docs:end:as_unsafe #[builtin(expr_has_semicolon)] + // docs:start:has_semicolon fn has_semicolon(self) -> bool {} + // docs:end:has_semicolon #[builtin(expr_is_break)] + // docs:start:is_break fn is_break(self) -> bool {} + // docs:end:is_break #[builtin(expr_is_continue)] + // docs:start:is_continue fn is_continue(self) -> bool {} + // docs:end:is_continue } mod tests { diff --git a/noir_stdlib/src/meta/function_def.nr b/noir_stdlib/src/meta/function_def.nr index 2b5ddd008ea..7ac8803e7e4 100644 --- a/noir_stdlib/src/meta/function_def.nr +++ b/noir_stdlib/src/meta/function_def.nr @@ -1,19 +1,31 @@ impl FunctionDefinition { #[builtin(function_def_name)] + // docs:start:name fn name(self) -> Quoted {} + // docs:end:name #[builtin(function_def_parameters)] + // docs:start:parameters fn parameters(self) -> [(Quoted, Type)] {} + // docs:end:parameters #[builtin(function_def_return_type)] + // docs:start:return_type fn return_type(self) -> Type {} + // docs:end:return_type #[builtin(function_def_set_body)] + // docs:start:set_body fn set_body(self, body: Quoted) {} + // docs:end:set_body #[builtin(function_def_set_parameters)] + // docs:start:set_parameters fn set_parameters(self, parameters: [(Quoted, Type)]) {} + // docs:end:set_parameters #[builtin(function_def_set_return_type)] + // docs:start:set_return_type fn set_return_type(self, return_type: Type) {} + // docs:end:set_return_type } diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index d16a8648bc2..03a9dd7de29 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -16,20 +16,26 @@ mod quoted; /// Calling unquote as a macro (via `unquote!(arg)`) will unquote /// its argument. Since this is the effect `!` already does, `unquote` /// itself does not need to do anything besides return its argument. +// docs:start:unquote pub comptime fn unquote(code: Quoted) -> Quoted { +// docs:end:unquote code } /// Returns the type of any value #[builtin(type_of)] +// docs:start:type_of pub comptime fn type_of(x: T) -> Type {} +// docs:end:type_of type DeriveFunction = fn(StructDefinition) -> Quoted; comptime mut global HANDLERS: UHashMap> = UHashMap::default(); +// docs:start:derive #[varargs] pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted { +// docs:end:derive let mut result = quote {}; for trait_to_derive in traits { @@ -45,7 +51,9 @@ pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted result } +// docs:start:derive_via pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { +// docs:end:derive_via HANDLERS.insert(t, f); } @@ -61,6 +69,7 @@ pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { /// any final processing - e.g. wrapping each field in a `StructConstructor { .. }` expression. /// /// See `derive_eq` and `derive_default` for example usage. +// docs:start:make_trait_impl pub comptime fn make_trait_impl( s: StructDefinition, trait_name: Quoted, @@ -69,6 +78,7 @@ pub comptime fn make_trait_impl( join_fields_with: Quoted, body: fn[Env2](Quoted) -> Quoted ) -> Quoted { +// docs:end:make_trait_impl let typ = s.as_type(); let impl_generics = s.generics().map(|g| quote { $g }).join(quote {,}); let where_clause = s.generics().map(|name| quote { $name: $trait_name }).join(quote {,}); diff --git a/noir_stdlib/src/meta/module.nr b/noir_stdlib/src/meta/module.nr index ee00f360806..cc0bbca6f20 100644 --- a/noir_stdlib/src/meta/module.nr +++ b/noir_stdlib/src/meta/module.nr @@ -1,10 +1,16 @@ impl Module { #[builtin(module_is_contract)] +// docs:start:is_contract fn is_contract(self) -> bool {} +// docs:end:is_contract #[builtin(module_functions)] +// docs:start:functions fn functions(self) -> [FunctionDefinition] {} +// docs:end:functions #[builtin(module_name)] +// docs:start:name fn name(self) -> Quoted {} +// docs:end:name } diff --git a/noir_stdlib/src/meta/op.nr b/noir_stdlib/src/meta/op.nr index ebd89677c50..69ad968aaae 100644 --- a/noir_stdlib/src/meta/op.nr +++ b/noir_stdlib/src/meta/op.nr @@ -3,19 +3,19 @@ struct UnaryOp { } impl UnaryOp { - fn is_minus(self) -> bool { + pub fn is_minus(self) -> bool { self.op == 0 } - fn is_not(self) -> bool { + pub fn is_not(self) -> bool { self.op == 1 } - fn is_mutable_reference(self) -> bool { + pub fn is_mutable_reference(self) -> bool { self.op == 2 } - fn is_dereference(self) -> bool { + pub fn is_dereference(self) -> bool { self.op == 3 } } @@ -25,67 +25,67 @@ struct BinaryOp { } impl BinaryOp { - fn is_add(self) -> bool { + pub fn is_add(self) -> bool { self.op == 0 } - fn is_subtract(self) -> bool { + pub fn is_subtract(self) -> bool { self.op == 1 } - fn is_multiply(self) -> bool { + pub fn is_multiply(self) -> bool { self.op == 2 } - fn is_divide(self) -> bool { + pub fn is_divide(self) -> bool { self.op == 3 } - fn is_equal(self) -> bool { + pub fn is_equal(self) -> bool { self.op == 4 } - fn is_not_equal(self) -> bool { + pub fn is_not_equal(self) -> bool { self.op == 5 } - fn is_less(self) -> bool { + pub fn is_less(self) -> bool { self.op == 6 } - fn is_less_equal(self) -> bool { + pub fn is_less_equal(self) -> bool { self.op == 7 } - fn is_greater(self) -> bool { + pub fn is_greater(self) -> bool { self.op == 8 } - fn is_greater_or_equal(self) -> bool { + pub fn is_greater_equal(self) -> bool { self.op == 9 } - fn is_and(self) -> bool { + pub fn is_and(self) -> bool { self.op == 10 } - fn is_or(self) -> bool { + pub fn is_or(self) -> bool { self.op == 11 } - fn is_xor(self) -> bool { + pub fn is_xor(self) -> bool { self.op == 12 } - fn is_shift_right(self) -> bool { + pub fn is_shift_right(self) -> bool { self.op == 13 } - fn is_shift_left(self) -> bool { + pub fn is_shift_left(self) -> bool { self.op == 14 } - fn is_modulo(self) -> bool { + pub fn is_modulo(self) -> bool { self.op == 15 } } diff --git a/noir_stdlib/src/meta/quoted.nr b/noir_stdlib/src/meta/quoted.nr index cccc3fe0f12..600d6bffbf3 100644 --- a/noir_stdlib/src/meta/quoted.nr +++ b/noir_stdlib/src/meta/quoted.nr @@ -3,16 +3,24 @@ use crate::option::Option; impl Quoted { #[builtin(quoted_as_expr)] +// docs:start:as_expr fn as_expr(self) -> Option {} +// docs:end:as_expr #[builtin(quoted_as_module)] +// docs:start:as_module fn as_module(self) -> Option {} +// docs:end:as_module #[builtin(quoted_as_trait_constraint)] +// docs:start:as_trait_constraint fn as_trait_constraint(self) -> TraitConstraint {} +// docs:end:as_trait_constraint #[builtin(quoted_as_type)] +// docs:start:as_type fn as_type(self) -> Type {} +// docs:end:as_type } impl Eq for Quoted { diff --git a/noir_stdlib/src/meta/struct_def.nr b/noir_stdlib/src/meta/struct_def.nr index 8d3f9ceb8a5..53b7fe3fdf9 100644 --- a/noir_stdlib/src/meta/struct_def.nr +++ b/noir_stdlib/src/meta/struct_def.nr @@ -2,14 +2,20 @@ impl StructDefinition { /// Return a syntactic version of this struct definition as a type. /// For example, `as_type(quote { type Foo { ... } })` would return `Foo` #[builtin(struct_def_as_type)] +// docs:start:as_type fn as_type(self) -> Type {} +// docs:end:as_type /// Return each generic on this struct. #[builtin(struct_def_generics)] +// docs:start:generics fn generics(self) -> [Type] {} +// docs:end:generics /// Returns (name, type) pairs of each field in this struct. Each type is as-is /// with any generic arguments unchanged. #[builtin(struct_def_fields)] +// docs:start:fields fn fields(self) -> [(Quoted, Type)] {} +// docs:end:fields } diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr index ca381cb8e16..16e412fc5a9 100644 --- a/noir_stdlib/src/meta/trait_def.nr +++ b/noir_stdlib/src/meta/trait_def.nr @@ -3,7 +3,9 @@ use crate::cmp::Eq; impl TraitDefinition { #[builtin(trait_def_as_trait_constraint)] +// docs:start:as_trait_constraint fn as_trait_constraint(_self: Self) -> TraitConstraint {} +// docs:end:as_trait_constraint } impl Eq for TraitDefinition { diff --git a/noir_stdlib/src/meta/trait_impl.nr b/noir_stdlib/src/meta/trait_impl.nr index 2f82ee5f434..7ba68cbfc20 100644 --- a/noir_stdlib/src/meta/trait_impl.nr +++ b/noir_stdlib/src/meta/trait_impl.nr @@ -1,7 +1,11 @@ impl TraitImpl { #[builtin(trait_impl_trait_generic_args)] +// docs:start:trait_generic_args fn trait_generic_args(self) -> [Type] {} +// docs:end:trait_generic_args #[builtin(trait_impl_methods)] +// docs:start:methods fn methods(self) -> [FunctionDefinition] {} +// docs:end:methods } diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr index 67ad2a96739..21bb10d5c6a 100644 --- a/noir_stdlib/src/meta/typ.nr +++ b/noir_stdlib/src/meta/typ.nr @@ -3,34 +3,54 @@ use crate::option::Option; impl Type { #[builtin(type_as_array)] +// docs:start:as_array fn as_array(self) -> Option<(Type, Type)> {} +// docs:end:as_array #[builtin(type_as_constant)] +// docs:start:as_constant fn as_constant(self) -> Option {} +// docs:end:as_constant #[builtin(type_as_integer)] +// docs:start:as_integer fn as_integer(self) -> Option<(bool, u8)> {} +// docs:end:as_integer #[builtin(type_as_slice)] +// docs:start:as_slice fn as_slice(self) -> Option {} +// docs:end:as_slice #[builtin(type_as_struct)] +// docs:start:as_struct fn as_struct(self) -> Option<(StructDefinition, [Type])> {} +// docs:end:as_struct #[builtin(type_as_tuple)] +// docs:start:as_tuple fn as_tuple(self) -> Option<[Type]> {} +// docs:end:as_tuple #[builtin(type_get_trait_impl)] +// docs:start:get_trait_impl fn get_trait_impl(self, constraint: TraitConstraint) -> Option {} +// docs:end:get_trait_impl #[builtin(type_implements)] +// docs:start:implements fn implements(self, constraint: TraitConstraint) -> bool {} +// docs:end:implements #[builtin(type_is_bool)] +// docs:start:is_bool fn is_bool(self) -> bool {} +// docs:end:is_bool #[builtin(type_is_field)] +// docs:start:is_field fn is_field(self) -> bool {} +// docs:end:is_field } impl Eq for Type { From 8a4f5895e82a7c93b64bd1835c790daee1df6fe0 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Thu, 22 Aug 2024 16:28:29 -0500 Subject: [PATCH 02/21] Typo --- docs/docs/noir/standard_library/meta/expr.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/expr.md b/docs/docs/noir/standard_library/meta/expr.md index 26e9ab896c3..72b147c8103 100644 --- a/docs/docs/noir/standard_library/meta/expr.md +++ b/docs/docs/noir/standard_library/meta/expr.md @@ -79,14 +79,14 @@ expression and the field. The field will be represented as a quoted value. #include_code as_repeated_element_array noir_stdlib/src/meta/expr.nr rust -If this expression is a repated element array `[elem; length]`, return +If this expression is a repeated element array `[elem; length]`, return the repeated element and the length expressions. ### as_repeated_element_slice #include_code as_repeated_element_slice noir_stdlib/src/meta/expr.nr rust -If this expression is a repated element slice `[elem; length]`, return +If this expression is a repeated element slice `[elem; length]`, return the repeated element and the length expressions. ### as_slice From 20bcf22818aa20cc84a4a74981fab14756f856f3 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Fri, 23 Aug 2024 09:35:15 +0000 Subject: [PATCH 03/21] cspell --- cspell.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cspell.json b/cspell.json index f285489530e..af0bd68c670 100644 --- a/cspell.json +++ b/cspell.json @@ -119,6 +119,7 @@ "keccakf", "krate", "libc", + "Linea", "losslessly", "lvalue", "Maddiaa", @@ -126,6 +127,7 @@ "memfs", "memset", "merkle", + "Metaprogramming", "metas", "microcontroller", "minreq", @@ -217,8 +219,7 @@ "wasi", "wasmer", "Weierstraß", - "zshell", - "Linea" + "zshell" ], "ignorePaths": [ "./**/node_modules/**", From 817a1fcf68d47d5cbb91526ead27bd9a166f0696 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Fri, 23 Aug 2024 09:36:41 +0000 Subject: [PATCH 04/21] fix: update references to `is_greater_or_equal` --- docs/docs/noir/standard_library/meta/op.md | 2 +- noir_stdlib/src/meta/expr.nr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/op.md b/docs/docs/noir/standard_library/meta/op.md index f42b5d8dd7e..beb34abde32 100644 --- a/docs/docs/noir/standard_library/meta/op.md +++ b/docs/docs/noir/standard_library/meta/op.md @@ -105,7 +105,7 @@ Represents a binary operator. One of `+`, `-`, `*`, `/`, `%`, `==`, `!=`, `<`, ` #### is_greater_equal -#include_code is_greater_or_equal noir_stdlib/src/meta/expr.nr rust +#include_code is_greater_equal noir_stdlib/src/meta/expr.nr rust `true` if this operator is `>=` diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index ad9bde5d0a4..d645538c5cf 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -156,7 +156,7 @@ mod tests { assert(get_binary_op(quote { x == y }).is_equal()); assert(get_binary_op(quote { x != y }).is_not_equal()); assert(get_binary_op(quote { x > y }).is_greater()); - assert(get_binary_op(quote { x >= y }).is_greater_or_equal()); + assert(get_binary_op(quote { x >= y }).is_greater_equal()); assert(get_binary_op(quote { x & y }).is_and()); assert(get_binary_op(quote { x | y }).is_or()); assert(get_binary_op(quote { x ^ y }).is_xor()); From adef15bb163881c0bc62a02551d9bc3e32f23985 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Fri, 23 Aug 2024 09:59:10 +0000 Subject: [PATCH 05/21] chore: `as_unary` -> `as_unary_op` --- docs/docs/noir/standard_library/meta/expr.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/expr.md b/docs/docs/noir/standard_library/meta/expr.md index 72b147c8103..9c3baa03813 100644 --- a/docs/docs/noir/standard_library/meta/expr.md +++ b/docs/docs/noir/standard_library/meta/expr.md @@ -103,9 +103,9 @@ return each element of the slice. If this expression is a tuple `(field1, ..., fieldN)`, return each element of the tuple. -### as_unary +### as_unary_op -#include_code as_unary noir_stdlib/src/meta/expr.nr rust +#include_code as_unary_op noir_stdlib/src/meta/expr.nr rust If this expression is a unary operation ` `, return the unary operator as well as the right-hand side expression. From 8514e63589a44a716085b7bcc7307340943c1731 Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Fri, 23 Aug 2024 10:30:35 +0000 Subject: [PATCH 06/21] chore: add snippet tags --- docs/docs/noir/standard_library/meta/op.md | 38 ++++++++++---------- noir_stdlib/src/meta/op.nr | 40 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/op.md b/docs/docs/noir/standard_library/meta/op.md index beb34abde32..e9489b41322 100644 --- a/docs/docs/noir/standard_library/meta/op.md +++ b/docs/docs/noir/standard_library/meta/op.md @@ -15,25 +15,25 @@ Represents a unary operator. One of `-`, `!`, `&mut`, or `*`. #### is_minus -#include_code is_minus noir_stdlib/src/meta/expr.nr rust +#include_code is_minus noir_stdlib/src/meta/op.nr rust `true` if this operator is `-` #### is_not -#include_code is_not noir_stdlib/src/meta/expr.nr rust +#include_code is_not noir_stdlib/src/meta/op.nr rust `true` if this operator is `!` #### is_mutable_reference -#include_code is_mutable_reference noir_stdlib/src/meta/expr.nr rust +#include_code is_mutable_reference noir_stdlib/src/meta/op.nr rust `true` if this operator is `&mut` #### is_dereference -#include_code is_dereference noir_stdlib/src/meta/expr.nr rust +#include_code is_dereference noir_stdlib/src/meta/op.nr rust `true` if this operator is `*` @@ -45,90 +45,90 @@ Represents a binary operator. One of `+`, `-`, `*`, `/`, `%`, `==`, `!=`, `<`, ` #### is_add -#include_code is_add noir_stdlib/src/meta/expr.nr rust +#include_code is_add noir_stdlib/src/meta/op.nr rust `true` if this operator is `+` #### is_subtract -#include_code is_subtract noir_stdlib/src/meta/expr.nr rust +#include_code is_subtract noir_stdlib/src/meta/op.nr rust `true` if this operator is `-` #### is_multiply -#include_code is_multiply noir_stdlib/src/meta/expr.nr rust +#include_code is_multiply noir_stdlib/src/meta/op.nr rust `true` if this operator is `*` #### is_divide -#include_code is_divide noir_stdlib/src/meta/expr.nr rust +#include_code is_divide noir_stdlib/src/meta/op.nr rust `true` if this operator is `/` #### is_modulo -#include_code is_modulo noir_stdlib/src/meta/expr.nr rust +#include_code is_modulo noir_stdlib/src/meta/op.nr rust `true` if this operator is `%` #### is_equal -#include_code is_equal noir_stdlib/src/meta/expr.nr rust +#include_code is_equal noir_stdlib/src/meta/op.nr rust `true` if this operator is `==` #### is_not_equal -#include_code is_not_equal noir_stdlib/src/meta/expr.nr rust +#include_code is_not_equal noir_stdlib/src/meta/op.nr rust `true` if this operator is `!=` #### is_less -#include_code is_less noir_stdlib/src/meta/expr.nr rust +#include_code is_less noir_stdlib/src/meta/op.nr rust `true` if this operator is `<` #### is_less_equal -#include_code is_less_equal noir_stdlib/src/meta/expr.nr rust +#include_code is_less_equal noir_stdlib/src/meta/op.nr rust `true` if this operator is `<=` #### is_greater -#include_code is_greater noir_stdlib/src/meta/expr.nr rust +#include_code is_greater noir_stdlib/src/meta/op.nr rust `true` if this operator is `>` #### is_greater_equal -#include_code is_greater_equal noir_stdlib/src/meta/expr.nr rust +#include_code is_greater_equal noir_stdlib/src/meta/op.nr rust `true` if this operator is `>=` #### is_and -#include_code is_and noir_stdlib/src/meta/expr.nr rust +#include_code is_and noir_stdlib/src/meta/op.nr rust `true` if this operator is `&` #### is_or -#include_code is_or noir_stdlib/src/meta/expr.nr rust +#include_code is_or noir_stdlib/src/meta/op.nr rust `true` if this operator is `|` #### is_shift_right -#include_code is_shift_right noir_stdlib/src/meta/expr.nr rust +#include_code is_shift_right noir_stdlib/src/meta/op.nr rust `true` if this operator is `>>` #### is_shift_left -#include_code is_shift_right noir_stdlib/src/meta/expr.nr rust +#include_code is_shift_right noir_stdlib/src/meta/op.nr rust `true` if this operator is `<<` diff --git a/noir_stdlib/src/meta/op.nr b/noir_stdlib/src/meta/op.nr index 69ad968aaae..16955e46a32 100644 --- a/noir_stdlib/src/meta/op.nr +++ b/noir_stdlib/src/meta/op.nr @@ -3,21 +3,29 @@ struct UnaryOp { } impl UnaryOp { + // docs:start:is_minus pub fn is_minus(self) -> bool { self.op == 0 } + // docs:end:is_minus + // docs:start:is_not pub fn is_not(self) -> bool { self.op == 1 } + // docs:end:is_not + // docs:start:is_mutable_reference pub fn is_mutable_reference(self) -> bool { self.op == 2 } + // docs:end:is_mutable_reference + // docs:start:is_dereference pub fn is_dereference(self) -> bool { self.op == 3 } + // docs:end:is_dereference } struct BinaryOp { @@ -25,68 +33,100 @@ struct BinaryOp { } impl BinaryOp { + // docs:start:is_add pub fn is_add(self) -> bool { self.op == 0 } + // docs:end:is_add + // docs:start:is_subtract pub fn is_subtract(self) -> bool { self.op == 1 } + // docs:end:is_subtract + // docs:start:is_multiply pub fn is_multiply(self) -> bool { self.op == 2 } + // docs:end:is_multiply + // docs:start:is_divide pub fn is_divide(self) -> bool { self.op == 3 } + // docs:end:is_divide + // docs:start:is_equal pub fn is_equal(self) -> bool { self.op == 4 } + // docs:end:is_equal + // docs:start:is_not_equal pub fn is_not_equal(self) -> bool { self.op == 5 } + // docs:end:is_not_equal + // docs:start:is_less pub fn is_less(self) -> bool { self.op == 6 } + // docs:end:is_less + // docs:start:is_less_equal pub fn is_less_equal(self) -> bool { self.op == 7 } + // docs:end:is_less_equal + // docs:start:is_greater pub fn is_greater(self) -> bool { self.op == 8 } + // docs:end:is_greater + // docs:start:is_greater_equal pub fn is_greater_equal(self) -> bool { self.op == 9 } + // docs:end:is_greater_equal + // docs:start:is_and pub fn is_and(self) -> bool { self.op == 10 } + // docs:end:is_and + // docs:start:is_or pub fn is_or(self) -> bool { self.op == 11 } + // docs:end:is_or + // docs:start:is_xor pub fn is_xor(self) -> bool { self.op == 12 } + // docs:end:is_xor + // docs:start:is_shift_right pub fn is_shift_right(self) -> bool { self.op == 13 } + // docs:end:is_shift_right + // docs:start:is_shift_left pub fn is_shift_left(self) -> bool { self.op == 14 } + // docs:end:is_shift_left + // docs:start:is_modulo pub fn is_modulo(self) -> bool { self.op == 15 } + // docs:end:is_modulo } From e8080c307936b6ec86e13569670b889c26b60e0e Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 10:21:21 -0500 Subject: [PATCH 07/21] Rename more --- docs/docs/noir/standard_library/meta/op.md | 16 +++++++-------- noir_stdlib/src/meta/expr.nr | 6 ++++-- noir_stdlib/src/meta/op.nr | 24 +++++++++++----------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/op.md b/docs/docs/noir/standard_library/meta/op.md index e9489b41322..01a1bce6e81 100644 --- a/docs/docs/noir/standard_library/meta/op.md +++ b/docs/docs/noir/standard_library/meta/op.md @@ -85,27 +85,27 @@ Represents a binary operator. One of `+`, `-`, `*`, `/`, `%`, `==`, `!=`, `<`, ` `true` if this operator is `!=` -#### is_less +#### is_less_than -#include_code is_less noir_stdlib/src/meta/op.nr rust +#include_code is_less_than noir_stdlib/src/meta/op.nr rust `true` if this operator is `<` -#### is_less_equal +#### is_less_than_or_equal -#include_code is_less_equal noir_stdlib/src/meta/op.nr rust +#include_code is_less_than_or_equal noir_stdlib/src/meta/op.nr rust `true` if this operator is `<=` -#### is_greater +#### is_greater_than -#include_code is_greater noir_stdlib/src/meta/op.nr rust +#include_code is_greater_than noir_stdlib/src/meta/op.nr rust `true` if this operator is `>` -#### is_greater_equal +#### is_greater_than_or_equal -#include_code is_greater_equal noir_stdlib/src/meta/op.nr rust +#include_code is_greater_than_or_equal noir_stdlib/src/meta/op.nr rust `true` if this operator is `>=` diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index d645538c5cf..4ae9d56757c 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -155,8 +155,10 @@ mod tests { assert(get_binary_op(quote { x / y }).is_divide()); assert(get_binary_op(quote { x == y }).is_equal()); assert(get_binary_op(quote { x != y }).is_not_equal()); - assert(get_binary_op(quote { x > y }).is_greater()); - assert(get_binary_op(quote { x >= y }).is_greater_equal()); + assert(get_binary_op(quote { x < y }).is_less_than()); + assert(get_binary_op(quote { x <= y }).is_less_than_or_equal()); + assert(get_binary_op(quote { x > y }).is_greater_than()); + assert(get_binary_op(quote { x >= y }).is_greater_than_or_equal()); assert(get_binary_op(quote { x & y }).is_and()); assert(get_binary_op(quote { x | y }).is_or()); assert(get_binary_op(quote { x ^ y }).is_xor()); diff --git a/noir_stdlib/src/meta/op.nr b/noir_stdlib/src/meta/op.nr index 16955e46a32..2944ff3426f 100644 --- a/noir_stdlib/src/meta/op.nr +++ b/noir_stdlib/src/meta/op.nr @@ -69,29 +69,29 @@ impl BinaryOp { } // docs:end:is_not_equal - // docs:start:is_less - pub fn is_less(self) -> bool { + // docs:start:is_less_than + pub fn is_less_than(self) -> bool { self.op == 6 } - // docs:end:is_less + // docs:end:is_less_than - // docs:start:is_less_equal - pub fn is_less_equal(self) -> bool { + // docs:start:is_less_than_or_equal + pub fn is_less_than_or_equal(self) -> bool { self.op == 7 } - // docs:end:is_less_equal + // docs:end:is_less_than_or_equal - // docs:start:is_greater - pub fn is_greater(self) -> bool { + // docs:start:is_greater_than + pub fn is_greater_than(self) -> bool { self.op == 8 } - // docs:end:is_greater + // docs:end:is_greater_than - // docs:start:is_greater_equal - pub fn is_greater_equal(self) -> bool { + // docs:start:is_greater_than_or_equal + pub fn is_greater_than_or_equal(self) -> bool { self.op == 9 } - // docs:end:is_greater_equal + // docs:end:is_greater_than_or_equal // docs:start:is_and pub fn is_and(self) -> bool { From e99bb7e59b131c5703bdcfbc98e5e850279e23db Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 10:22:29 -0500 Subject: [PATCH 08/21] Nargo fmt; hopefully //doc:start still works while indented --- noir_stdlib/src/meta/mod.nr | 8 ++++---- noir_stdlib/src/meta/module.nr | 6 +++--- noir_stdlib/src/meta/quoted.nr | 8 ++++---- noir_stdlib/src/meta/struct_def.nr | 6 +++--- noir_stdlib/src/meta/trait_def.nr | 2 +- noir_stdlib/src/meta/trait_impl.nr | 4 ++-- noir_stdlib/src/meta/typ.nr | 20 ++++++++++---------- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index 03a9dd7de29..07855d50ad9 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -18,7 +18,7 @@ mod quoted; /// itself does not need to do anything besides return its argument. // docs:start:unquote pub comptime fn unquote(code: Quoted) -> Quoted { -// docs:end:unquote + // docs:end:unquote code } @@ -35,7 +35,7 @@ comptime mut global HANDLERS: UHashMap Quoted { -// docs:end:derive + // docs:end:derive let mut result = quote {}; for trait_to_derive in traits { @@ -53,7 +53,7 @@ pub comptime fn derive(s: StructDefinition, traits: [TraitDefinition]) -> Quoted // docs:start:derive_via pub comptime fn derive_via(t: TraitDefinition, f: DeriveFunction) { -// docs:end:derive_via + // docs:end:derive_via HANDLERS.insert(t, f); } @@ -78,7 +78,7 @@ pub comptime fn make_trait_impl( join_fields_with: Quoted, body: fn[Env2](Quoted) -> Quoted ) -> Quoted { -// docs:end:make_trait_impl + // docs:end:make_trait_impl let typ = s.as_type(); let impl_generics = s.generics().map(|g| quote { $g }).join(quote {,}); let where_clause = s.generics().map(|name| quote { $name: $trait_name }).join(quote {,}); diff --git a/noir_stdlib/src/meta/module.nr b/noir_stdlib/src/meta/module.nr index cc0bbca6f20..6ea3ca55fb1 100644 --- a/noir_stdlib/src/meta/module.nr +++ b/noir_stdlib/src/meta/module.nr @@ -2,15 +2,15 @@ impl Module { #[builtin(module_is_contract)] // docs:start:is_contract fn is_contract(self) -> bool {} -// docs:end:is_contract + // docs:end:is_contract #[builtin(module_functions)] // docs:start:functions fn functions(self) -> [FunctionDefinition] {} -// docs:end:functions + // docs:end:functions #[builtin(module_name)] // docs:start:name fn name(self) -> Quoted {} -// docs:end:name + // docs:end:name } diff --git a/noir_stdlib/src/meta/quoted.nr b/noir_stdlib/src/meta/quoted.nr index 600d6bffbf3..9fd1e9026ba 100644 --- a/noir_stdlib/src/meta/quoted.nr +++ b/noir_stdlib/src/meta/quoted.nr @@ -5,22 +5,22 @@ impl Quoted { #[builtin(quoted_as_expr)] // docs:start:as_expr fn as_expr(self) -> Option {} -// docs:end:as_expr + // docs:end:as_expr #[builtin(quoted_as_module)] // docs:start:as_module fn as_module(self) -> Option {} -// docs:end:as_module + // docs:end:as_module #[builtin(quoted_as_trait_constraint)] // docs:start:as_trait_constraint fn as_trait_constraint(self) -> TraitConstraint {} -// docs:end:as_trait_constraint + // docs:end:as_trait_constraint #[builtin(quoted_as_type)] // docs:start:as_type fn as_type(self) -> Type {} -// docs:end:as_type + // docs:end:as_type } impl Eq for Quoted { diff --git a/noir_stdlib/src/meta/struct_def.nr b/noir_stdlib/src/meta/struct_def.nr index 53b7fe3fdf9..60fdeba21aa 100644 --- a/noir_stdlib/src/meta/struct_def.nr +++ b/noir_stdlib/src/meta/struct_def.nr @@ -4,18 +4,18 @@ impl StructDefinition { #[builtin(struct_def_as_type)] // docs:start:as_type fn as_type(self) -> Type {} -// docs:end:as_type + // docs:end:as_type /// Return each generic on this struct. #[builtin(struct_def_generics)] // docs:start:generics fn generics(self) -> [Type] {} -// docs:end:generics + // docs:end:generics /// Returns (name, type) pairs of each field in this struct. Each type is as-is /// with any generic arguments unchanged. #[builtin(struct_def_fields)] // docs:start:fields fn fields(self) -> [(Quoted, Type)] {} -// docs:end:fields + // docs:end:fields } diff --git a/noir_stdlib/src/meta/trait_def.nr b/noir_stdlib/src/meta/trait_def.nr index 16e412fc5a9..c26b571240b 100644 --- a/noir_stdlib/src/meta/trait_def.nr +++ b/noir_stdlib/src/meta/trait_def.nr @@ -5,7 +5,7 @@ impl TraitDefinition { #[builtin(trait_def_as_trait_constraint)] // docs:start:as_trait_constraint fn as_trait_constraint(_self: Self) -> TraitConstraint {} -// docs:end:as_trait_constraint + // docs:end:as_trait_constraint } impl Eq for TraitDefinition { diff --git a/noir_stdlib/src/meta/trait_impl.nr b/noir_stdlib/src/meta/trait_impl.nr index 7ba68cbfc20..15b02eac6bd 100644 --- a/noir_stdlib/src/meta/trait_impl.nr +++ b/noir_stdlib/src/meta/trait_impl.nr @@ -2,10 +2,10 @@ impl TraitImpl { #[builtin(trait_impl_trait_generic_args)] // docs:start:trait_generic_args fn trait_generic_args(self) -> [Type] {} -// docs:end:trait_generic_args + // docs:end:trait_generic_args #[builtin(trait_impl_methods)] // docs:start:methods fn methods(self) -> [FunctionDefinition] {} -// docs:end:methods + // docs:end:methods } diff --git a/noir_stdlib/src/meta/typ.nr b/noir_stdlib/src/meta/typ.nr index 21bb10d5c6a..a3f35b28e43 100644 --- a/noir_stdlib/src/meta/typ.nr +++ b/noir_stdlib/src/meta/typ.nr @@ -5,52 +5,52 @@ impl Type { #[builtin(type_as_array)] // docs:start:as_array fn as_array(self) -> Option<(Type, Type)> {} -// docs:end:as_array + // docs:end:as_array #[builtin(type_as_constant)] // docs:start:as_constant fn as_constant(self) -> Option {} -// docs:end:as_constant + // docs:end:as_constant #[builtin(type_as_integer)] // docs:start:as_integer fn as_integer(self) -> Option<(bool, u8)> {} -// docs:end:as_integer + // docs:end:as_integer #[builtin(type_as_slice)] // docs:start:as_slice fn as_slice(self) -> Option {} -// docs:end:as_slice + // docs:end:as_slice #[builtin(type_as_struct)] // docs:start:as_struct fn as_struct(self) -> Option<(StructDefinition, [Type])> {} -// docs:end:as_struct + // docs:end:as_struct #[builtin(type_as_tuple)] // docs:start:as_tuple fn as_tuple(self) -> Option<[Type]> {} -// docs:end:as_tuple + // docs:end:as_tuple #[builtin(type_get_trait_impl)] // docs:start:get_trait_impl fn get_trait_impl(self, constraint: TraitConstraint) -> Option {} -// docs:end:get_trait_impl + // docs:end:get_trait_impl #[builtin(type_implements)] // docs:start:implements fn implements(self, constraint: TraitConstraint) -> bool {} -// docs:end:implements + // docs:end:implements #[builtin(type_is_bool)] // docs:start:is_bool fn is_bool(self) -> bool {} -// docs:end:is_bool + // docs:end:is_bool #[builtin(type_is_field)] // docs:start:is_field fn is_field(self) -> bool {} -// docs:end:is_field + // docs:end:is_field } impl Eq for Type { From a568cc1819a56ea034d5b66002549bf5eb33269f Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 15:11:05 -0500 Subject: [PATCH 09/21] Add index page --- docs/docs/noir/standard_library/meta/index.md | 5 +++++ docs/docs/noir/standard_library/meta/mod.md | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 docs/docs/noir/standard_library/meta/index.md diff --git a/docs/docs/noir/standard_library/meta/index.md b/docs/docs/noir/standard_library/meta/index.md new file mode 100644 index 00000000000..6fe4846a018 --- /dev/null +++ b/docs/docs/noir/standard_library/meta/index.md @@ -0,0 +1,5 @@ +--- +title: Metaprogramming +description: Noir's Metaprogramming API +keywords: [metaprogramming, comptime, macros, macro, quote, unquote] +--- diff --git a/docs/docs/noir/standard_library/meta/mod.md b/docs/docs/noir/standard_library/meta/mod.md index 1ee826474df..ddbe4d3a731 100644 --- a/docs/docs/noir/standard_library/meta/mod.md +++ b/docs/docs/noir/standard_library/meta/mod.md @@ -11,7 +11,7 @@ title: Metaprogramming Module Returns the type of a variable at compile-time. Example: -```rs +```rust comptime { let x: i32 = 1; let x_type: Type = std::meta::type_of(x); @@ -27,7 +27,7 @@ comptime { Unquotes the passed-in token stream where this function was called. Example: -```rs +```rust comptime { let code = quote { 1 + 2 }; @@ -48,7 +48,7 @@ with `derive_via` beforehand. The traits in the stdlib that can be derived this way are `Eq`, `Ord`, `Default`, and `Hash`. Example: -```rs +```rust #[derive(Eq, Default)] struct Foo { x: i32, @@ -79,7 +79,7 @@ it helpful to use a function like `std::meta::make_trait_impl` to help creating these impls. Example: -```rs +```rust #[derive_via(derive_do_nothing)] trait DoNothing { fn do_nothing(self); From 41d649875b92bde169a96afc501f2089f6238adc Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 15:24:16 -0500 Subject: [PATCH 10/21] Specify the full module path on each page --- docs/docs/noir/standard_library/meta/expr.md | 4 ++-- docs/docs/noir/standard_library/meta/function_def.md | 4 ++-- docs/docs/noir/standard_library/meta/mod.md | 5 ++++- docs/docs/noir/standard_library/meta/module.md | 4 ++-- docs/docs/noir/standard_library/meta/op.md | 4 ++-- docs/docs/noir/standard_library/meta/quoted.md | 4 ++-- docs/docs/noir/standard_library/meta/struct_def.md | 4 ++-- docs/docs/noir/standard_library/meta/trait_constraint.md | 6 +++--- docs/docs/noir/standard_library/meta/trait_def.md | 4 ++-- docs/docs/noir/standard_library/meta/trait_impl.md | 4 ++-- docs/docs/noir/standard_library/meta/typ.md | 4 ++-- 11 files changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/expr.md b/docs/docs/noir/standard_library/meta/expr.md index 9c3baa03813..bcc9756c06c 100644 --- a/docs/docs/noir/standard_library/meta/expr.md +++ b/docs/docs/noir/standard_library/meta/expr.md @@ -1,8 +1,8 @@ --- -title: Expr Methods +title: Expr --- -This module contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. +`std::meta::expr` contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. ## Methods diff --git a/docs/docs/noir/standard_library/meta/function_def.md b/docs/docs/noir/standard_library/meta/function_def.md index 45378c0bc99..173a013ad3b 100644 --- a/docs/docs/noir/standard_library/meta/function_def.md +++ b/docs/docs/noir/standard_library/meta/function_def.md @@ -1,8 +1,8 @@ --- -title: FunctionDefinition Methods +title: FunctionDefinition --- -This module contains methods on the built-in `FunctionDefinition` type representing +`std::meta::function_def` contains methods on the built-in `FunctionDefinition` type representing a function definition in the source program. ## Methods diff --git a/docs/docs/noir/standard_library/meta/mod.md b/docs/docs/noir/standard_library/meta/mod.md index ddbe4d3a731..3e8983d7d32 100644 --- a/docs/docs/noir/standard_library/meta/mod.md +++ b/docs/docs/noir/standard_library/meta/mod.md @@ -1,7 +1,10 @@ --- -title: Metaprogramming Module +title: Metaprogramming --- +`std::meta` is the entry point for Noir's metaprogramming API. This consists of `comptime` functions +and types used for inspecting and modifying Noir programs. + ## Functions ### type_of diff --git a/docs/docs/noir/standard_library/meta/module.md b/docs/docs/noir/standard_library/meta/module.md index 541c8a46c1c..53826541617 100644 --- a/docs/docs/noir/standard_library/meta/module.md +++ b/docs/docs/noir/standard_library/meta/module.md @@ -1,8 +1,8 @@ --- -title: Module Methods +title: Module --- -This module contains methods on the built-in `Module` type which represents a module in the source program. +`std::meta::module` contains methods on the built-in `Module` type which represents a module in the source program. Note that this type represents a module generally, it isn't limited to only `mod my_submodule { ... }` declarations in the source program. diff --git a/docs/docs/noir/standard_library/meta/op.md b/docs/docs/noir/standard_library/meta/op.md index 01a1bce6e81..b13e3e5f575 100644 --- a/docs/docs/noir/standard_library/meta/op.md +++ b/docs/docs/noir/standard_library/meta/op.md @@ -1,8 +1,8 @@ --- -title: UnaryOp and BinaryOp Methods +title: UnaryOp and BinaryOp --- -This module contains the `UnaryOp` and `BinaryOp` types as well as methods on them. +`std::meta::op` contains the `UnaryOp` and `BinaryOp` types as well as methods on them. These types are used to represent a unary or binary operator respectively in Noir source code. ## Types diff --git a/docs/docs/noir/standard_library/meta/quoted.md b/docs/docs/noir/standard_library/meta/quoted.md index 776e7fc4dbe..3422371c717 100644 --- a/docs/docs/noir/standard_library/meta/quoted.md +++ b/docs/docs/noir/standard_library/meta/quoted.md @@ -1,8 +1,8 @@ --- -title: Quoted Methods +title: Quoted --- -This module contains methods on the built-in `Quoted` type which represents +`std::meta::quoted` contains methods on the built-in `Quoted` type which represents quoted token streams and is the result of the `quote { ... }` expression. ## Methods diff --git a/docs/docs/noir/standard_library/meta/struct_def.md b/docs/docs/noir/standard_library/meta/struct_def.md index ba19ebe009c..2a4dba445f3 100644 --- a/docs/docs/noir/standard_library/meta/struct_def.md +++ b/docs/docs/noir/standard_library/meta/struct_def.md @@ -1,8 +1,8 @@ --- -title: StructDefinition Methods +title: StructDefinition --- -This module contains methods on the built-in `StructDefinition` type. +`std::meta::struct_def` contains methods on the built-in `StructDefinition` type. This type corresponds to `struct Name { field1: Type1, ... }` items in the source program. ## Methods diff --git a/docs/docs/noir/standard_library/meta/trait_constraint.md b/docs/docs/noir/standard_library/meta/trait_constraint.md index dca9a41f43f..3106f732b5a 100644 --- a/docs/docs/noir/standard_library/meta/trait_constraint.md +++ b/docs/docs/noir/standard_library/meta/trait_constraint.md @@ -1,13 +1,13 @@ --- -title: TraitConstraint Methods +title: TraitConstraint --- -This module contains methods on the built-in `TraitConstraint` type which represents +`std::meta::trait_constraint` contains methods on the built-in `TraitConstraint` type which represents a trait constraint that can be used to search for a trait implementation. This is similar syntactically to just the trait itself, but can also contain generic arguments. E.g. `Eq`, `Default`, `BuildHasher`. -This type currently has no methods but it can be used alongside `Type` in `implements` or `get_trait_impl`. +This type currently has no public methods but it can be used alongside `Type` in `implements` or `get_trait_impl`. ## Trait Implementations diff --git a/docs/docs/noir/standard_library/meta/trait_def.md b/docs/docs/noir/standard_library/meta/trait_def.md index 98eba9ff905..b6e8bf4ff76 100644 --- a/docs/docs/noir/standard_library/meta/trait_def.md +++ b/docs/docs/noir/standard_library/meta/trait_def.md @@ -1,8 +1,8 @@ --- -title: TraitDefinition Methods +title: TraitDefinition --- -This module contains methods on the built-in `TraitDefinition` type. This type +`std::meta::trait_def` contains methods on the built-in `TraitDefinition` type. This type represents trait definitions such as `trait Foo { .. }` at the top-level of a program. ## Methods diff --git a/docs/docs/noir/standard_library/meta/trait_impl.md b/docs/docs/noir/standard_library/meta/trait_impl.md index d0c6086f4ca..659c6aad719 100644 --- a/docs/docs/noir/standard_library/meta/trait_impl.md +++ b/docs/docs/noir/standard_library/meta/trait_impl.md @@ -1,8 +1,8 @@ --- -title: TraitImpl Methods +title: TraitImpl --- -This module contains methods on the built-in `TraitImpl` type which represents a trait +`std::meta::trait_impl` contains methods on the built-in `TraitImpl` type which represents a trait implementation such as `impl Foo for Bar { ... }`. ## Methods diff --git a/docs/docs/noir/standard_library/meta/typ.md b/docs/docs/noir/standard_library/meta/typ.md index 9476ede7543..f60bc8377b9 100644 --- a/docs/docs/noir/standard_library/meta/typ.md +++ b/docs/docs/noir/standard_library/meta/typ.md @@ -1,8 +1,8 @@ --- -title: Type Methods +title: Type --- -This module contains methods on the built-in `Type` type used for representing +`std::meta::typ` contains methods on the built-in `Type` type used for representing a type in the source program. ## Methods From 7f974222176b43afa8523c58e9df9aceed0f7545 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 15:38:32 -0500 Subject: [PATCH 11/21] Move mod.md to index.md --- docs/docs/noir/standard_library/meta/index.md | 136 +++++++++++++++++ docs/docs/noir/standard_library/meta/mod.md | 139 ------------------ 2 files changed, 136 insertions(+), 139 deletions(-) delete mode 100644 docs/docs/noir/standard_library/meta/mod.md diff --git a/docs/docs/noir/standard_library/meta/index.md b/docs/docs/noir/standard_library/meta/index.md index 6fe4846a018..db0e5d0e411 100644 --- a/docs/docs/noir/standard_library/meta/index.md +++ b/docs/docs/noir/standard_library/meta/index.md @@ -3,3 +3,139 @@ title: Metaprogramming description: Noir's Metaprogramming API keywords: [metaprogramming, comptime, macros, macro, quote, unquote] --- + +`std::meta` is the entry point for Noir's metaprogramming API. This consists of `comptime` functions +and types used for inspecting and modifying Noir programs. + +## Functions + +### type_of + +#include_code type_of noir_stdlib/src/meta/mod.nr rust + +Returns the type of a variable at compile-time. + +Example: +```rust +comptime { + let x: i32 = 1; + let x_type: Type = std::meta::type_of(x); + + assert_eq(x_type, quote { i32 }.as_type()); +} +``` + +### unquote + +#include_code unquote noir_stdlib/src/meta/mod.nr rust + +Unquotes the passed-in token stream where this function was called. + +Example: +```rust +comptime { + let code = quote { 1 + 2 }; + + // let x = 1 + 2; + let x = unquote!(code); +} +``` + +### derive + +#include_code derive noir_stdlib/src/meta/mod.nr rust + +Attribute placed on struct definitions. + +Creates a trait impl for each trait passed in as an argument. +To do this, the trait must have a derive handler registered +with `derive_via` beforehand. The traits in the stdlib that +can be derived this way are `Eq`, `Ord`, `Default`, and `Hash`. + +Example: +```rust +#[derive(Eq, Default)] +struct Foo { + x: i32, + y: T, +} + +fn main() { + let foo1 = Foo::default(); + let foo2 = Foo { x: 0, y: &[0] }; + assert_eq(foo1, foo2); +} +``` + +### derive_via + +#include_code derive_via_signature noir_stdlib/src/meta/mod.nr rust + +Attribute placed on trait definitions. + +Registers a function to create impls for the given trait +when the trait is used in a `derive` call. Users may use +this to register their own functions to enable their traits +to be derived by `derive`. + +Because this function requires a function as an argument which +should produce a trait impl for any given struct, users may find +it helpful to use a function like `std::meta::make_trait_impl` to +help creating these impls. + +Example: +```rust +#[derive_via(derive_do_nothing)] +trait DoNothing { + fn do_nothing(self); +} + +comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { + let typ = s.as_type(); + quote { + impl DoNothing for $typ { + fn do_nothing(self) { + println("Nothing"); + } + } + } +} +``` + +As another example, `derive_eq` in the stdlib is used to derive the `Eq` +trait for any struct. It makes use of `make_trait_impl` to do this: + +#include_code derive_eq noir_stdlib/src/cmp.nr rust + +### make_trait_impl + +#include_code make_trait_impl noir_stdlib/src/meta/mod.nr rust + +A helper function to more easily create trait impls while deriving traits. + +Note that this function only works for traits which: +1. Have only one method +2. Have no generics on the trait itself. + - E.g. Using this on a trait such as `trait Foo { ... }` will result in the + generated impl incorrectly missing the `T` generic. + +If your trait fits these criteria then `make_trait_impl` is likely the easiest +way to write your derive handler. The arguments are as follows: + +- `s`: The struct to make the impl for +- `trait_name`: The name of the trait to derive. E.g. `quote { Eq }`. +- `function_signature`: The signature of the trait method to derive. E.g. `fn eq(self, other: Self) -> bool`. +- `for_each_field`: An operation to be performed on each field. E.g. `|name| quote { (self.$name == other.$name) }`. +- `join_fields_with`: A separator to join each result of `for_each_field` with. + E.g. `quote { & }`. You can also use an empty `quote {}` for no separator. +- `body`: The result of the field operations are passed into this function for any final processing. + This is the place to insert any setup/teardown code the trait requires. If the trait doesn't require + any such code, you can return the body as-is: `|body| body`. + +Example deriving `Hash`: + +#include_code derive_hash noir_stdlib/src/hash/mod.nr rust + +Example deriving `Ord`: + +#include_code derive_ord noir_stdlib/src/cmp.nr rust diff --git a/docs/docs/noir/standard_library/meta/mod.md b/docs/docs/noir/standard_library/meta/mod.md deleted file mode 100644 index 7d9a1ca9566..00000000000 --- a/docs/docs/noir/standard_library/meta/mod.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: Metaprogramming ---- - -`std::meta` is the entry point for Noir's metaprogramming API. This consists of `comptime` functions -and types used for inspecting and modifying Noir programs. - -## Functions - -### type_of - -#include_code type_of noir_stdlib/src/meta/mod.nr rust - -Returns the type of a variable at compile-time. - -Example: -```rust -comptime { - let x: i32 = 1; - let x_type: Type = std::meta::type_of(x); - - assert_eq(x_type, quote { i32 }.as_type()); -} -``` - -### unquote - -#include_code unquote noir_stdlib/src/meta/mod.nr rust - -Unquotes the passed-in token stream where this function was called. - -Example: -```rust -comptime { - let code = quote { 1 + 2 }; - - // let x = 1 + 2; - let x = unquote!(code); -} -``` - -### derive - -#include_code derive noir_stdlib/src/meta/mod.nr rust - -Attribute placed on struct definitions. - -Creates a trait impl for each trait passed in as an argument. -To do this, the trait must have a derive handler registered -with `derive_via` beforehand. The traits in the stdlib that -can be derived this way are `Eq`, `Ord`, `Default`, and `Hash`. - -Example: -```rust -#[derive(Eq, Default)] -struct Foo { - x: i32, - y: T, -} - -fn main() { - let foo1 = Foo::default(); - let foo2 = Foo { x: 0, y: &[0] }; - assert_eq(foo1, foo2); -} -``` - -### derive_via - -#include_code derive_via_signature noir_stdlib/src/meta/mod.nr rust - -Attribute placed on trait definitions. - -Registers a function to create impls for the given trait -when the trait is used in a `derive` call. Users may use -this to register their own functions to enable their traits -to be derived by `derive`. - -Because this function requires a function as an argument which -should produce a trait impl for any given struct, users may find -it helpful to use a function like `std::meta::make_trait_impl` to -help creating these impls. - -Example: -```rust -#[derive_via(derive_do_nothing)] -trait DoNothing { - fn do_nothing(self); -} - -comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { - let typ = s.as_type(); - quote { - impl DoNothing for $typ { - fn do_nothing(self) { - println("Nothing"); - } - } - } -} -``` - -As another example, `derive_eq` in the stdlib is used to derive the `Eq` -trait for any struct. It makes use of `make_trait_impl` to do this: - -#include_code derive_eq noir_stdlib/src/cmp.nr rust - -### make_trait_impl - -#include_code make_trait_impl noir_stdlib/src/meta/mod.nr rust - -A helper function to more easily create trait impls while deriving traits. - -Note that this function only works for traits which: -1. Have only one method -2. Have no generics on the trait itself. - - E.g. Using this on a trait such as `trait Foo { ... }` will result in the - generated impl incorrectly missing the `T` generic. - -If your trait fits these criteria then `make_trait_impl` is likely the easiest -way to write your derive handler. The arguments are as follows: - -- `s`: The struct to make the impl for -- `trait_name`: The name of the trait to derive. E.g. `quote { Eq }`. -- `function_signature`: The signature of the trait method to derive. E.g. `fn eq(self, other: Self) -> bool`. -- `for_each_field`: An operation to be performed on each field. E.g. `|name| quote { (self.$name == other.$name) }`. -- `join_fields_with`: A separator to join each result of `for_each_field` with. - E.g. `quote { & }`. You can also use an empty `quote {}` for no separator. -- `body`: The result of the field operations are passed into this function for any final processing. - This is the place to insert any setup/teardown code the trait requires. If the trait doesn't require - any such code, you can return the body as-is: `|body| body`. - -Example deriving `Hash`: - -#include_code derive_hash noir_stdlib/src/hash/mod.nr rust - -Example deriving `Ord`: - -#include_code derive_ord noir_stdlib/src/cmp.nr rust From efb3ad1b0c0a9fae5f6f65be2068cccdb4ffa089 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 15:43:02 -0500 Subject: [PATCH 12/21] Format --- noir_stdlib/src/meta/op.nr | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/noir_stdlib/src/meta/op.nr b/noir_stdlib/src/meta/op.nr index f3da2ef8cd5..9c892c4d80b 100644 --- a/noir_stdlib/src/meta/op.nr +++ b/noir_stdlib/src/meta/op.nr @@ -5,25 +5,25 @@ struct UnaryOp { impl UnaryOp { // docs:start:is_minus pub fn is_minus(self) -> bool { - // docs:end:is_minus + // docs:end:is_minus self.op == 0 } // docs:start:is_not pub fn is_not(self) -> bool { - // docs:end:is_not + // docs:end:is_not self.op == 1 } // docs:start:is_mutable_reference pub fn is_mutable_reference(self) -> bool { - // docs:end:is_mutable_reference + // docs:end:is_mutable_reference self.op == 2 } // docs:start:is_dereference pub fn is_dereference(self) -> bool { - // docs:end:is_dereference + // docs:end:is_dereference self.op == 3 } } @@ -35,97 +35,97 @@ struct BinaryOp { impl BinaryOp { // docs:start:is_add pub fn is_add(self) -> bool { - // docs:end:is_add + // docs:end:is_add self.op == 0 } // docs:start:is_subtract pub fn is_subtract(self) -> bool { - // docs:end:is_subtract + // docs:end:is_subtract self.op == 1 } // docs:start:is_multiply pub fn is_multiply(self) -> bool { - // docs:end:is_multiply + // docs:end:is_multiply self.op == 2 } // docs:start:is_divide pub fn is_divide(self) -> bool { - // docs:end:is_divide + // docs:end:is_divide self.op == 3 } // docs:start:is_equal pub fn is_equal(self) -> bool { - // docs:end:is_equal + // docs:end:is_equal self.op == 4 } // docs:start:is_not_equal pub fn is_not_equal(self) -> bool { - // docs:end:is_not_equal + // docs:end:is_not_equal self.op == 5 } // docs:start:is_less_than pub fn is_less_than(self) -> bool { - // docs:end:is_less_than + // docs:end:is_less_than self.op == 6 } // docs:start:is_less_than_or_equal pub fn is_less_than_or_equal(self) -> bool { - // docs:end:is_less_than_or_equal + // docs:end:is_less_than_or_equal self.op == 7 } // docs:start:is_greater_than pub fn is_greater_than(self) -> bool { - // docs:end:is_greater_than + // docs:end:is_greater_than self.op == 8 } // docs:start:is_greater_than_or_equal pub fn is_greater_than_or_equal(self) -> bool { - // docs:end:is_greater_than_or_equal + // docs:end:is_greater_than_or_equal self.op == 9 } // docs:start:is_and pub fn is_and(self) -> bool { - // docs:end:is_and + // docs:end:is_and self.op == 10 } // docs:start:is_or pub fn is_or(self) -> bool { - // docs:end:is_or + // docs:end:is_or self.op == 11 } // docs:start:is_xor pub fn is_xor(self) -> bool { - // docs:end:is_xor + // docs:end:is_xor self.op == 12 } // docs:start:is_shift_right pub fn is_shift_right(self) -> bool { - // docs:end:is_shift_right + // docs:end:is_shift_right self.op == 13 } // docs:start:is_shift_left pub fn is_shift_left(self) -> bool { - // docs:end:is_shift_left + // docs:end:is_shift_left self.op == 14 } // docs:start:is_modulo pub fn is_modulo(self) -> bool { - // docs:end:is_modulo + // docs:end:is_modulo self.op == 15 } } From a2e12e3ec672f34fc414ea2c1a3e28f8e141e443 Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 23 Aug 2024 15:52:30 -0500 Subject: [PATCH 13/21] Update docs/docs/noir/standard_library/meta/function_def.md Co-authored-by: Maxim Vezenov --- docs/docs/noir/standard_library/meta/function_def.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/function_def.md b/docs/docs/noir/standard_library/meta/function_def.md index 173a013ad3b..4b359a9d343 100644 --- a/docs/docs/noir/standard_library/meta/function_def.md +++ b/docs/docs/noir/standard_library/meta/function_def.md @@ -11,7 +11,7 @@ a function definition in the source program. #include_code name noir_stdlib/src/meta/function_def.nr rust -Returns the name of the function +Returns the name of the function. ### parameters From 0921d74f5d3c793d1453415cc6956ad756e322cb Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 23 Aug 2024 15:52:36 -0500 Subject: [PATCH 14/21] Update docs/docs/noir/standard_library/meta/module.md Co-authored-by: Maxim Vezenov --- docs/docs/noir/standard_library/meta/module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/module.md b/docs/docs/noir/standard_library/meta/module.md index 53826541617..9e3a8c9645b 100644 --- a/docs/docs/noir/standard_library/meta/module.md +++ b/docs/docs/noir/standard_library/meta/module.md @@ -12,7 +12,7 @@ declarations in the source program. #include_code name noir_stdlib/src/meta/module.nr rust -Returns the name of the module +Returns the name of the module. ### functions From a3ddc79cf20e1f74f529661beaed23d6fb0d08b4 Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 23 Aug 2024 15:52:47 -0500 Subject: [PATCH 15/21] Update docs/docs/noir/standard_library/meta/op.md Co-authored-by: Maxim Vezenov --- docs/docs/noir/standard_library/meta/op.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/op.md b/docs/docs/noir/standard_library/meta/op.md index b13e3e5f575..37d4cb746ac 100644 --- a/docs/docs/noir/standard_library/meta/op.md +++ b/docs/docs/noir/standard_library/meta/op.md @@ -17,7 +17,7 @@ Represents a unary operator. One of `-`, `!`, `&mut`, or `*`. #include_code is_minus noir_stdlib/src/meta/op.nr rust -`true` if this operator is `-` +Returns `true` if this operator is `-`. #### is_not From cceeeea185a8cca89d362704d07bc682b87e5937 Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 23 Aug 2024 15:52:53 -0500 Subject: [PATCH 16/21] Update docs/docs/noir/standard_library/meta/module.md Co-authored-by: Maxim Vezenov --- docs/docs/noir/standard_library/meta/module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/module.md b/docs/docs/noir/standard_library/meta/module.md index 9e3a8c9645b..d283f2da8b2 100644 --- a/docs/docs/noir/standard_library/meta/module.md +++ b/docs/docs/noir/standard_library/meta/module.md @@ -18,7 +18,7 @@ Returns the name of the module. #include_code functions noir_stdlib/src/meta/module.nr rust -Returns each function in the module +Returns each function in the module. ### is_contract From b650024b842ef2de7de3c2ca4870ccc7084f1967 Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 23 Aug 2024 15:53:11 -0500 Subject: [PATCH 17/21] Update docs/docs/noir/standard_library/meta/quoted.md Co-authored-by: Maxim Vezenov --- docs/docs/noir/standard_library/meta/quoted.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/quoted.md b/docs/docs/noir/standard_library/meta/quoted.md index 3422371c717..d14a75966e4 100644 --- a/docs/docs/noir/standard_library/meta/quoted.md +++ b/docs/docs/noir/standard_library/meta/quoted.md @@ -30,7 +30,7 @@ comptime { #include_code as_module noir_stdlib/src/meta/quoted.nr rust Interprets this token stream as a module path leading to the name of a module. -Returns `None` if the module isn't found or this cannot be parsed as a path. +Returns `None` if the module isn't found or the token stream cannot be parsed as a path. Example: From d61e45c7068e2998d385c95619d7614394b78d49 Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 23 Aug 2024 15:53:22 -0500 Subject: [PATCH 18/21] Update docs/docs/noir/standard_library/meta/struct_def.md Co-authored-by: Maxim Vezenov --- docs/docs/noir/standard_library/meta/struct_def.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/struct_def.md b/docs/docs/noir/standard_library/meta/struct_def.md index 2a4dba445f3..ab3ea4e0698 100644 --- a/docs/docs/noir/standard_library/meta/struct_def.md +++ b/docs/docs/noir/standard_library/meta/struct_def.md @@ -42,4 +42,4 @@ comptime fn example(foo: StructDefinition) { #include_code fields noir_stdlib/src/meta/struct_def.nr rust -Returns each field of this struct as a pair of (field name, field type) +Returns each field of this struct as a pair of (field name, field type). From 38ee3149a94bff7be8a209a8ded01fb37e36ef77 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 16:05:52 -0500 Subject: [PATCH 19/21] Add snippets --- .../docs/noir/standard_library/meta/quoted.md | 42 ++++--------------- docs/docs/noir/standard_library/meta/typ.md | 2 +- noir_stdlib/src/meta/expr.nr | 4 +- .../comptime_module/src/main.nr | 14 +++++++ .../comptime_type/src/main.nr | 2 + 5 files changed, 27 insertions(+), 37 deletions(-) diff --git a/docs/docs/noir/standard_library/meta/quoted.md b/docs/docs/noir/standard_library/meta/quoted.md index 3422371c717..a18d258341b 100644 --- a/docs/docs/noir/standard_library/meta/quoted.md +++ b/docs/docs/noir/standard_library/meta/quoted.md @@ -11,57 +11,35 @@ quoted token streams and is the result of the `quote { ... }` expression. #include_code as_expr noir_stdlib/src/meta/quoted.nr rust -Parses the quoted token stream as an expression. Returns `None` if +Parses the quoted token stream as an expression. Returns `Option::none()` if the expression failed to parse. Example: -```rust -comptime { - let add: Expr = quote { 1 + 2 }.as_expr().unwrap(); - - let (_one, op, _two) = add.as_binary_op().unwrap(); - assert(op.is_add()); -} -``` +#include_code as_expr_example noir_stdlib/src/meta/quoted.nr rust ### as_module #include_code as_module noir_stdlib/src/meta/quoted.nr rust Interprets this token stream as a module path leading to the name of a module. -Returns `None` if the module isn't found or this cannot be parsed as a path. +Returns `Option::none()` if the module isn't found or this cannot be parsed as a path. Example: -```rust -mod foo { - mod bar { ... } -} - -comptime { - let my_mod = quote { foo::bar }.as_module().unwrap(); - assert_eq(my_mod.name(), quote { bar }); -} -``` +#include_code as_module_example test_programs/compile_success_empty/comptime_module/src/main.nr rust ### as_trait_constraint #include_code as_trait_constraint noir_stdlib/src/meta/quoted.nr rust Interprets this token stream as a trait constraint (without an object type). -Note that this function panics instead of returning None if the token +Note that this function panics instead of returning `Option::none()` if the token stream does not parse and resolve to a valid trait constraint. Example: -```rust -comptime { - let eq = quote { Eq }.as_trait_constraint(); - let i32_type = quote { i32 }.as_type(); - assert(i32_type.implements(eq)); -} -``` +#include_code implements_example noir_stdlib/src/meta/quoted.nr rust ### as_type @@ -70,13 +48,7 @@ comptime { Interprets this token stream as a resolved type. Panics if the token stream doesn't parse to a type or if the type isn't a valid type in scope. -```rust -comptime { - let eq = quote { Eq }.as_trait_constraint(); - let i32_type = quote { i32 }.as_type(); - assert(i32_type.implements(eq)); -} -``` +#include_code implements_example noir_stdlib/src/meta/quoted.nr rust ## Trait Implementations diff --git a/docs/docs/noir/standard_library/meta/typ.md b/docs/docs/noir/standard_library/meta/typ.md index f60bc8377b9..bad6435e94a 100644 --- a/docs/docs/noir/standard_library/meta/typ.md +++ b/docs/docs/noir/standard_library/meta/typ.md @@ -67,7 +67,7 @@ trait constraint for this type. If the trait constraint is not found, `None` is returned. Note that since the concrete trait implementation for a trait constraint specified from a `where` clause is unknown, this function will return `None` in these cases. If you only want to know -whether a type implements a true, use `implements` instead. +whether a type implements a trait, use `implements` instead. Example: diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index cd092d4819c..4d6c15099c7 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -218,13 +218,15 @@ mod tests { #[test] fn test_expr_as_function_call() { - comptime + // docs:start:as_expr_example + { let expr = quote { foo(42) }.as_expr().unwrap(); let (_function, args) = expr.as_function_call().unwrap(); assert_eq(args.len(), 1); assert_eq(args[0].as_integer().unwrap(), (42, false)); } + // docs:end:as_expr_example } #[test] diff --git a/test_programs/compile_success_empty/comptime_module/src/main.nr b/test_programs/compile_success_empty/comptime_module/src/main.nr index e9c9817cfd8..b9b3d451709 100644 --- a/test_programs/compile_success_empty/comptime_module/src/main.nr +++ b/test_programs/compile_success_empty/comptime_module/src/main.nr @@ -24,3 +24,17 @@ fn main() { assert_eq(bar.name(), quote { bar }); } } + +// docs:start:as_module_example +mod baz { + mod qux {} +} + +#[test] +fn as_module_test() { + comptime { + let my_mod = quote { baz::qux }.as_module().unwrap(); + assert_eq(my_mod.name(), quote { qux }); + } +} +// docs:end:as_module_example diff --git a/test_programs/compile_success_empty/comptime_type/src/main.nr b/test_programs/compile_success_empty/comptime_type/src/main.nr index f0b53a392ed..6d98d1d173b 100644 --- a/test_programs/compile_success_empty/comptime_type/src/main.nr +++ b/test_programs/compile_success_empty/comptime_type/src/main.nr @@ -113,6 +113,7 @@ fn main() { } } +// docs:start:implements_example fn function_with_where(_x: T) where T: SomeTrait { comptime { @@ -123,3 +124,4 @@ fn function_with_where(_x: T) where T: SomeTrait { assert(t.get_trait_impl(some_trait_i32).is_none()); } } +// docs:end:implements_example From 6822c85428e0a4b89c666e73aaf1f527bb0a5e3e Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 16:19:01 -0500 Subject: [PATCH 20/21] nargo fmt removes 'comptime' keyword if there is a comment before a comptime block --- noir_stdlib/src/meta/expr.nr | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index 4d6c15099c7..718ba9607d4 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -216,18 +216,20 @@ mod tests { } } + // This test can't only be around the comptime block since that will cause + // `nargo fmt` to remove the comptime keyword. + // docs:start:as_expr_example #[test] fn test_expr_as_function_call() { - // docs:start:as_expr_example - + comptime { let expr = quote { foo(42) }.as_expr().unwrap(); let (_function, args) = expr.as_function_call().unwrap(); assert_eq(args.len(), 1); assert_eq(args[0].as_integer().unwrap(), (42, false)); } - // docs:end:as_expr_example } + // docs:end:as_expr_example #[test] fn test_expr_as_if() { From 4159827fa0acca8f6e6c56f2116aaf8d5e00d199 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 23 Aug 2024 16:28:37 -0500 Subject: [PATCH 21/21] Format --- .../compile_success_empty/comptime_module/src/main.nr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_programs/compile_success_empty/comptime_module/src/main.nr b/test_programs/compile_success_empty/comptime_module/src/main.nr index b9b3d451709..8d834381fea 100644 --- a/test_programs/compile_success_empty/comptime_module/src/main.nr +++ b/test_programs/compile_success_empty/comptime_module/src/main.nr @@ -32,7 +32,8 @@ mod baz { #[test] fn as_module_test() { - comptime { + comptime + { let my_mod = quote { baz::qux }.as_module().unwrap(); assert_eq(my_mod.name(), quote { qux }); }