From bdde2e2d7ca4b14b0a8087ad27769df0ad0c5173 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 21 Jun 2024 15:00:51 -0500 Subject: [PATCH 1/4] Implement slice_push_back in the interpreter --- .../src/hir/comptime/interpreter/builtin.rs | 15 +++++++ .../derive_impl/Nargo.toml | 7 +++ .../derive_impl/src/main.nr | 45 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 test_programs/compile_success_empty/derive_impl/Nargo.toml create mode 100644 test_programs/compile_success_empty/derive_impl/src/main.nr diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 4a811253fce..56d86db1977 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -19,6 +19,7 @@ pub(super) fn call_builtin( match name { "array_len" => array_len(&arguments), "as_slice" => as_slice(arguments), + "slice_push_back" => slice_push_back(arguments), "type_def_as_type" => type_def_as_type(interner, arguments), "type_def_generics" => type_def_generics(interner, arguments), "type_def_fields" => type_def_fields(interner, arguments), @@ -48,6 +49,20 @@ fn as_slice(mut arguments: Vec<(Value, Location)>) -> IResult { } } +fn slice_push_back(mut arguments: Vec<(Value, Location)>) -> IResult { + assert_eq!(arguments.len(), 2, "ICE: `slice_push_back` should only receive two arguments"); + let (element, _) = arguments.pop().unwrap(); + let (slice, _) = arguments.pop().unwrap(); + match slice { + Value::Slice(mut values, typ) => { + values.push_back(element); + Ok(Value::Slice(values, typ)) + }, + // Type checking should prevent this branch being taken. + _ => unreachable!("ICE: `slice_push_back` expects a slice as its first argument"), + } +} + /// fn as_type(self) -> Quoted fn type_def_as_type( interner: &NodeInterner, diff --git a/test_programs/compile_success_empty/derive_impl/Nargo.toml b/test_programs/compile_success_empty/derive_impl/Nargo.toml new file mode 100644 index 00000000000..26a6020a6b1 --- /dev/null +++ b/test_programs/compile_success_empty/derive_impl/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "derive_impl" +type = "bin" +authors = [""] +compiler_version = ">=0.30.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/derive_impl/src/main.nr b/test_programs/compile_success_empty/derive_impl/src/main.nr new file mode 100644 index 00000000000..5e01816307c --- /dev/null +++ b/test_programs/compile_success_empty/derive_impl/src/main.nr @@ -0,0 +1,45 @@ +comptime fn derive_default(typ: TypeDefinition) -> Quoted { + let generics: [Quoted] = typ.generics(); + assert_eq(generics.len(), 0, "derive_default: Deriving Default on generic types is currently unimplemented"); + + let type_name = typ.as_type(); + let fields = typ.fields(); + + let fields = join(make_field_exprs(fields)); + + let result = quote { + impl Default for $type_name { + fn default() -> Self { + Self { $fields } + } + } + }; + println(result); + result +} + +#[derive_default] +struct Foo { + x: Field, + y: u32, +} + + +comptime fn make_field_exprs(fields: [(Quoted, Quoted)]) -> [Quoted] { + let mut result = &[]; + for my_field in fields { + let name = my_field.0; + result = result.push_back(quote { $name: Default::default(), }); + } + result +} + +comptime fn join(slice: [Quoted]) -> Quoted { + let mut result = quote {}; + for elem in slice { + result = quote { $result $elem }; + } + result +} + +fn main(){} From 9e13b001a695c55783a71068c8741056d253b837 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 21 Jun 2024 15:01:10 -0500 Subject: [PATCH 2/4] Format --- .../noirc_frontend/src/hir/comptime/interpreter.rs | 12 ++++++++---- .../src/hir/comptime/interpreter/builtin.rs | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 0803d06a508..565aa1f6d51 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -929,10 +929,14 @@ impl<'a> Interpreter<'a> { Value::Struct(fields, typ) => (fields, typ), Value::Tuple(fields) => { let mut field_types = Vec::with_capacity(fields.len()); - let fields = fields.into_iter().enumerate().map(|(i, field)| { - field_types.push(field.get_type().into_owned()); - (Rc::new(i.to_string()), field) - }).collect(); + let fields = fields + .into_iter() + .enumerate() + .map(|(i, field)| { + field_types.push(field.get_type().into_owned()); + (Rc::new(i.to_string()), field) + }) + .collect(); (fields, Type::Tuple(field_types)) } value => { diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 56d86db1977..d25a3abd669 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -57,7 +57,7 @@ fn slice_push_back(mut arguments: Vec<(Value, Location)>) -> IResult { Value::Slice(mut values, typ) => { values.push_back(element); Ok(Value::Slice(values, typ)) - }, + } // Type checking should prevent this branch being taken. _ => unreachable!("ICE: `slice_push_back` expects a slice as its first argument"), } From f53d6ba6c117b72671b72adaebdca88059e06001 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 21 Jun 2024 15:34:34 -0500 Subject: [PATCH 3/4] Remove println. It is too powerful for the tests --- test_programs/compile_success_empty/derive_impl/src/main.nr | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test_programs/compile_success_empty/derive_impl/src/main.nr b/test_programs/compile_success_empty/derive_impl/src/main.nr index 5e01816307c..63c550a8306 100644 --- a/test_programs/compile_success_empty/derive_impl/src/main.nr +++ b/test_programs/compile_success_empty/derive_impl/src/main.nr @@ -7,15 +7,13 @@ comptime fn derive_default(typ: TypeDefinition) -> Quoted { let fields = join(make_field_exprs(fields)); - let result = quote { + quote { impl Default for $type_name { fn default() -> Self { Self { $fields } } } - }; - println(result); - result + } } #[derive_default] From dde827e3c59b834a2220e56226d6422f778ed993 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Fri, 21 Jun 2024 16:08:45 -0500 Subject: [PATCH 4/4] Fmt --- .../compile_success_empty/derive_impl/src/main.nr | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test_programs/compile_success_empty/derive_impl/src/main.nr b/test_programs/compile_success_empty/derive_impl/src/main.nr index 63c550a8306..abad6d4f8e1 100644 --- a/test_programs/compile_success_empty/derive_impl/src/main.nr +++ b/test_programs/compile_success_empty/derive_impl/src/main.nr @@ -1,10 +1,12 @@ comptime fn derive_default(typ: TypeDefinition) -> Quoted { let generics: [Quoted] = typ.generics(); - assert_eq(generics.len(), 0, "derive_default: Deriving Default on generic types is currently unimplemented"); + assert_eq( + generics.len(), 0, "derive_default: Deriving Default on generic types is currently unimplemented" + ); let type_name = typ.as_type(); let fields = typ.fields(); - + let fields = join(make_field_exprs(fields)); quote { @@ -22,7 +24,6 @@ struct Foo { y: u32, } - comptime fn make_field_exprs(fields: [(Quoted, Quoted)]) -> [Quoted] { let mut result = &[]; for my_field in fields { @@ -40,4 +41,4 @@ comptime fn join(slice: [Quoted]) -> Quoted { result } -fn main(){} +fn main() {}