diff --git a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs index 469d5133840..1e88cd03249 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs @@ -129,8 +129,9 @@ impl DefunctionalizationContext { // Temporarily take the parameters here just to avoid cloning them let parameters = block.take_parameters(); for parameter in ¶meters { - if func.dfg.type_of_value(*parameter) == Type::Function { - func.dfg.set_type_of_value(*parameter, Type::field()); + let typ = &func.dfg.type_of_value(*parameter); + if is_function_type(typ) { + func.dfg.set_type_of_value(*parameter, replacement_type(typ)); } } @@ -158,8 +159,9 @@ impl DefunctionalizationContext { #[allow(clippy::unnecessary_to_owned)] // clippy is wrong here for result in func.dfg.instruction_results(instruction_id).to_vec() { - if func.dfg.type_of_value(result) == Type::Function { - func.dfg.set_type_of_value(result, Type::field()); + let typ = &func.dfg.type_of_value(result); + if is_function_type(typ) { + func.dfg.set_type_of_value(result, replacement_type(typ)); } } @@ -275,7 +277,8 @@ fn remove_first_class_functions_in_instruction( /// Try to map the given function literal to a field, returning Some(field) on success. /// Returns none if the given value was not a function or doesn't need to be mapped. fn map_function_to_field(func: &mut Function, value: ValueId) -> Option { - if let Type::Function = func.dfg[value].get_type().as_ref() { + let typ = func.dfg[value].get_type(); + if is_function_type(typ.as_ref()) { match &func.dfg[value] { // If the value is a static function, transform it to the function id Value::Function(id) => { @@ -284,7 +287,7 @@ fn map_function_to_field(func: &mut Function, value: ValueId) -> Option } // If the value is a function used as value, just change the type of it Value::Instruction { .. } | Value::Param { .. } => { - func.dfg.set_type_of_value(value, Type::field()); + func.dfg.set_type_of_value(value, replacement_type(typ.as_ref())); } _ => (), } @@ -426,15 +429,15 @@ fn create_apply_functions(ssa: &mut Ssa, variants_map: Variants) -> ApplyFunctio // Update the shared function signature of the higher-order function variants // to replace any function passed as a value to a numeric field type. for param in &mut signature.params { - if *param == Type::Function { - *param = Type::field(); + if is_function_type(param) { + *param = replacement_type(param); } } // Update the return value types as we did for the signature parameters above. for ret in &mut signature.returns { - if *ret == Type::Function { - *ret = Type::field(); + if is_function_type(ret) { + *ret = replacement_type(ret); } } @@ -614,13 +617,6 @@ fn create_apply_function( /// * All blocks which took function parameters should receive a discriminator instead #[cfg(debug_assertions)] fn defunctionalize_post_check(func: &Function) { - fn is_function(typ: &Type) -> bool { - match typ { - Type::Function => true, - Type::Reference(typ) => is_function(typ), - _ => false, - } - } for block_id in func.reachable_blocks() { for param in func.dfg[block_id].parameters() { let value = &func.dfg[*param]; @@ -628,13 +624,31 @@ fn defunctionalize_post_check(func: &Function) { panic!("unexpected parameter value: {value:?}"); }; assert!( - !is_function(typ), - "Blocks are not expected to take function parameters any more." + !is_function_type(typ), + "Blocks are not expected to take function parameters any more. Got '{typ}' in param {param} of block {block_id} in function {} {}", + func.name(), + func.id() ); } } } +fn is_function_type(typ: &Type) -> bool { + match typ { + Type::Function => true, + Type::Reference(typ) => is_function_type(typ), + _ => false, + } +} + +fn replacement_type(typ: &Type) -> Type { + if matches!(typ, Type::Reference(_)) { + Type::Reference(Arc::new(Type::field())) + } else { + Type::field() + } +} + #[cfg(test)] mod tests { use crate::assert_ssa_snapshot; @@ -842,7 +856,7 @@ mod tests { @r" acir(inline) fn main f0 { b0(v0: u1): - v1 = allocate -> &mut function + v1 = allocate -> &mut Field store Field 1 at v1 jmpif v0 then: b1, else: b2 b1(): @@ -1188,4 +1202,104 @@ mod tests { } "#); } + + #[test] + fn mut_ref_function() { + let src = " + acir(inline) fn main f0 { + b0(): + v0 = allocate -> &mut function + store f1 at v0 + v3 = call f2(v0) -> u1 + return v3 + } + acir(inline) fn bar f1 { + b0(): + return u1 0 + } + acir(inline) fn foo f2 { + b0(v0: &mut function): + v1 = load v0 -> function + v2 = call v1() -> u1 + return v2 + } + "; + + let ssa = Ssa::from_str(src).unwrap(); + let ssa = ssa.defunctionalize(); + + assert_ssa_snapshot!(ssa, @r" + acir(inline) fn main f0 { + b0(): + v0 = allocate -> &mut Field + store Field 1 at v0 + v3 = call f2(v0) -> u1 + return v3 + } + acir(inline) fn bar f1 { + b0(): + return u1 0 + } + acir(inline) fn foo f2 { + b0(v0: &mut Field): + v1 = load v0 -> Field + v3 = call f1() -> u1 + return v3 + } + "); + } + + #[test] + fn mut_ref_function_matching() { + let src = " + brillig(inline) fn add_to_tally_public f0 { + b0(): + v4 = allocate -> &mut function + store f2 at v4 + v10 = call f10(v4, f33) -> Field + return + } + brillig(inline) fn lambda f2 { + b0(): + return Field 1 + } + brillig(inline) fn at f10 { + b0(v4: &mut function, v6: function): + v10 = call v6(v4) -> Field + return v10 + } + brillig(inline) fn lambda f33 { + b0(v4: &mut function): + v10 = call v4() -> Field + return v10 + } + "; + + let ssa = Ssa::from_str(src).unwrap(); + let ssa = ssa.defunctionalize(); + + assert_ssa_snapshot!(ssa, @r" + brillig(inline) fn add_to_tally_public f0 { + b0(): + v0 = allocate -> &mut Field + store Field 1 at v0 + v4 = call f2(v0, Field 3) -> Field + return + } + brillig(inline) fn lambda f1 { + b0(): + return Field 1 + } + brillig(inline) fn at f2 { + b0(v0: &mut Field, v1: Field): + v3 = call f3(v0) -> Field + return v3 + } + brillig(inline) fn lambda f3 { + b0(v0: &mut Field): + v2 = call f1() -> Field + return v2 + } + "); + } } diff --git a/test_programs/execution_success/regression_8662/Nargo.toml b/test_programs/execution_success/regression_8662/Nargo.toml new file mode 100644 index 00000000000..ba8849d7a03 --- /dev/null +++ b/test_programs/execution_success/regression_8662/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_8662" +version = "0.1.0" +type = "bin" +authors = [""] + +[dependencies] diff --git a/test_programs/execution_success/regression_8662/Prover.toml b/test_programs/execution_success/regression_8662/Prover.toml new file mode 100644 index 00000000000..48a4798e742 --- /dev/null +++ b/test_programs/execution_success/regression_8662/Prover.toml @@ -0,0 +1,2 @@ +c = true +return = true diff --git a/test_programs/execution_success/regression_8662/src/main.nr b/test_programs/execution_success/regression_8662/src/main.nr new file mode 100644 index 00000000000..35090a34f4a --- /dev/null +++ b/test_programs/execution_success/regression_8662/src/main.nr @@ -0,0 +1,22 @@ +struct Context { + f: fn() -> bool, +} +fn main(c: bool) -> pub bool { + let mut ctx = Context { f: bar }; + if c { + ctx.f = qux; + } + foo(&mut ctx) +} + +fn foo(ctx: &mut Context) -> bool { + (ctx.f)() +} + +fn bar() -> bool { + false +} + +fn qux() -> bool { + true +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__expanded.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__expanded.snap new file mode 100644 index 00000000000..b77378dbe3a --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__expanded.snap @@ -0,0 +1,25 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: expanded_code +--- +struct Context { + f: fn() -> bool, +} + +fn main(c: bool) -> pub bool { + let mut ctx: Context = Context { f: bar }; + if c { ctx.f = qux; }; + foo(&mut ctx) +} + +fn foo(ctx: &mut Context) -> bool { + (ctx.f)() +} + +fn bar() -> bool { + false +} + +fn qux() -> bool { + true +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap new file mode 100644 index 00000000000..f11a63e74a3 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap @@ -0,0 +1,54 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [ + { + "name": "c", + "type": { + "kind": "boolean" + }, + "visibility": "private" + } + ], + "return_type": { + "abi_type": { + "kind": "boolean" + }, + "visibility": "public" + }, + "error_types": {} + }, + "bytecode": [ + "func 0", + "current witness index : _3", + "private parameters indices : [_0]", + "public parameters indices : []", + "return value indices : [_1]", + "BLACKBOX::RANGE [(_0, 1)] []", + "BRILLIG CALL func 0: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })], outputs: [Simple(Witness(2))]", + "EXPR [ (1, _0, _2) (1, _3) -1 ]", + "EXPR [ (1, _0, _3) 0 ]", + "EXPR [ (-1, _0, _3) (1, _0) (1, _3) -1 ]", + "EXPR [ (1, _1) (1, _3) -1 ]", + "unconstrained func 0", + "[Const { destination: Direct(21), bit_size: Integer(U32), value: 1 }, Const { destination: Direct(20), bit_size: Integer(U32), value: 0 }, CalldataCopy { destination_address: Direct(0), size_address: Direct(21), offset_address: Direct(20) }, Const { destination: Direct(2), bit_size: Field, value: 0 }, BinaryFieldOp { destination: Direct(3), op: Equals, lhs: Direct(0), rhs: Direct(2) }, JumpIf { condition: Direct(3), location: 8 }, Const { destination: Direct(1), bit_size: Field, value: 1 }, BinaryFieldOp { destination: Direct(0), op: Div, lhs: Direct(1), rhs: Direct(0) }, Stop { return_data: HeapVector { pointer: Direct(20), size: Direct(21) } }]" + ], + "debug_symbols": "dZDBCoMwDIbfJecerJvb8FXGkFqjFEpbYjsY4rsvFt304CVp8udryD9Bh20aGuN6P0L9nKAlY60ZGuu1isY77k6zgK1sIiFyC3Y6U0ERugi1S9YKeCub8tAYlMs5KmK1EICu48wf9sbi8prFny7OUVnJFZa36w+vjrw858visfKlvB/4F1dKGzpcDJIHBZQ5XnK8cpyXBWRUa3H1pU9O72yKn7Apm5GBvMYuES4LssYrvw==", + "file_map": { + "50": { + "source": "struct Context {\n f: fn() -> bool,\n}\nfn main(c: bool) -> pub bool {\n let mut ctx = Context { f: bar };\n if c {\n ctx.f = qux;\n }\n foo(&mut ctx)\n}\n\nfn foo(ctx: &mut Context) -> bool {\n (ctx.f)()\n}\n\nfn bar() -> bool {\n false\n}\n\nfn qux() -> bool {\n true\n}\n", + "path": "" + } + }, + "names": [ + "main" + ], + "brillig_names": [ + "directive_invert" + ] +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_0.snap new file mode 100644 index 00000000000..f11a63e74a3 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_0.snap @@ -0,0 +1,54 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [ + { + "name": "c", + "type": { + "kind": "boolean" + }, + "visibility": "private" + } + ], + "return_type": { + "abi_type": { + "kind": "boolean" + }, + "visibility": "public" + }, + "error_types": {} + }, + "bytecode": [ + "func 0", + "current witness index : _3", + "private parameters indices : [_0]", + "public parameters indices : []", + "return value indices : [_1]", + "BLACKBOX::RANGE [(_0, 1)] []", + "BRILLIG CALL func 0: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })], outputs: [Simple(Witness(2))]", + "EXPR [ (1, _0, _2) (1, _3) -1 ]", + "EXPR [ (1, _0, _3) 0 ]", + "EXPR [ (-1, _0, _3) (1, _0) (1, _3) -1 ]", + "EXPR [ (1, _1) (1, _3) -1 ]", + "unconstrained func 0", + "[Const { destination: Direct(21), bit_size: Integer(U32), value: 1 }, Const { destination: Direct(20), bit_size: Integer(U32), value: 0 }, CalldataCopy { destination_address: Direct(0), size_address: Direct(21), offset_address: Direct(20) }, Const { destination: Direct(2), bit_size: Field, value: 0 }, BinaryFieldOp { destination: Direct(3), op: Equals, lhs: Direct(0), rhs: Direct(2) }, JumpIf { condition: Direct(3), location: 8 }, Const { destination: Direct(1), bit_size: Field, value: 1 }, BinaryFieldOp { destination: Direct(0), op: Div, lhs: Direct(1), rhs: Direct(0) }, Stop { return_data: HeapVector { pointer: Direct(20), size: Direct(21) } }]" + ], + "debug_symbols": "dZDBCoMwDIbfJecerJvb8FXGkFqjFEpbYjsY4rsvFt304CVp8udryD9Bh20aGuN6P0L9nKAlY60ZGuu1isY77k6zgK1sIiFyC3Y6U0ERugi1S9YKeCub8tAYlMs5KmK1EICu48wf9sbi8prFny7OUVnJFZa36w+vjrw858visfKlvB/4F1dKGzpcDJIHBZQ5XnK8cpyXBWRUa3H1pU9O72yKn7Apm5GBvMYuES4LssYrvw==", + "file_map": { + "50": { + "source": "struct Context {\n f: fn() -> bool,\n}\nfn main(c: bool) -> pub bool {\n let mut ctx = Context { f: bar };\n if c {\n ctx.f = qux;\n }\n foo(&mut ctx)\n}\n\nfn foo(ctx: &mut Context) -> bool {\n (ctx.f)()\n}\n\nfn bar() -> bool {\n false\n}\n\nfn qux() -> bool {\n true\n}\n", + "path": "" + } + }, + "names": [ + "main" + ], + "brillig_names": [ + "directive_invert" + ] +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_9223372036854775807.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_9223372036854775807.snap new file mode 100644 index 00000000000..f11a63e74a3 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_false_inliner_9223372036854775807.snap @@ -0,0 +1,54 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [ + { + "name": "c", + "type": { + "kind": "boolean" + }, + "visibility": "private" + } + ], + "return_type": { + "abi_type": { + "kind": "boolean" + }, + "visibility": "public" + }, + "error_types": {} + }, + "bytecode": [ + "func 0", + "current witness index : _3", + "private parameters indices : [_0]", + "public parameters indices : []", + "return value indices : [_1]", + "BLACKBOX::RANGE [(_0, 1)] []", + "BRILLIG CALL func 0: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })], outputs: [Simple(Witness(2))]", + "EXPR [ (1, _0, _2) (1, _3) -1 ]", + "EXPR [ (1, _0, _3) 0 ]", + "EXPR [ (-1, _0, _3) (1, _0) (1, _3) -1 ]", + "EXPR [ (1, _1) (1, _3) -1 ]", + "unconstrained func 0", + "[Const { destination: Direct(21), bit_size: Integer(U32), value: 1 }, Const { destination: Direct(20), bit_size: Integer(U32), value: 0 }, CalldataCopy { destination_address: Direct(0), size_address: Direct(21), offset_address: Direct(20) }, Const { destination: Direct(2), bit_size: Field, value: 0 }, BinaryFieldOp { destination: Direct(3), op: Equals, lhs: Direct(0), rhs: Direct(2) }, JumpIf { condition: Direct(3), location: 8 }, Const { destination: Direct(1), bit_size: Field, value: 1 }, BinaryFieldOp { destination: Direct(0), op: Div, lhs: Direct(1), rhs: Direct(0) }, Stop { return_data: HeapVector { pointer: Direct(20), size: Direct(21) } }]" + ], + "debug_symbols": "dZDBCoMwDIbfJecerJvb8FXGkFqjFEpbYjsY4rsvFt304CVp8udryD9Bh20aGuN6P0L9nKAlY60ZGuu1isY77k6zgK1sIiFyC3Y6U0ERugi1S9YKeCub8tAYlMs5KmK1EICu48wf9sbi8prFny7OUVnJFZa36w+vjrw858visfKlvB/4F1dKGzpcDJIHBZQ5XnK8cpyXBWRUa3H1pU9O72yKn7Apm5GBvMYuES4LssYrvw==", + "file_map": { + "50": { + "source": "struct Context {\n f: fn() -> bool,\n}\nfn main(c: bool) -> pub bool {\n let mut ctx = Context { f: bar };\n if c {\n ctx.f = qux;\n }\n foo(&mut ctx)\n}\n\nfn foo(ctx: &mut Context) -> bool {\n (ctx.f)()\n}\n\nfn bar() -> bool {\n false\n}\n\nfn qux() -> bool {\n true\n}\n", + "path": "" + } + }, + "names": [ + "main" + ], + "brillig_names": [ + "directive_invert" + ] +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap new file mode 100644 index 00000000000..24827910591 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_-9223372036854775808.snap @@ -0,0 +1,54 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [ + { + "name": "c", + "type": { + "kind": "boolean" + }, + "visibility": "private" + } + ], + "return_type": { + "abi_type": { + "kind": "boolean" + }, + "visibility": "public" + }, + "error_types": { + "17843811134343075018": { + "error_kind": "string", + "string": "Stack too deep" + } + } + }, + "bytecode": [ + "func 0", + "current witness index : _1", + "private parameters indices : [_0]", + "public parameters indices : []", + "return value indices : [_1]", + "BRILLIG CALL func 0: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })], outputs: [Simple(Witness(1))]", + "unconstrained func 0", + "[Const { destination: Direct(2), bit_size: Integer(U32), value: 1 }, Const { destination: Direct(1), bit_size: Integer(U32), value: 32838 }, Const { destination: Direct(0), bit_size: Integer(U32), value: 3 }, Const { destination: Relative(2), bit_size: Integer(U32), value: 1 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 0 }, CalldataCopy { destination_address: Direct(32836), size_address: Relative(2), offset_address: Relative(3) }, Cast { destination: Direct(32836), source: Direct(32836), bit_size: Integer(U1) }, Mov { destination: Relative(1), source: Direct(32836) }, Call { location: 14 }, Call { location: 15 }, Mov { destination: Direct(32837), source: Relative(1) }, Const { destination: Relative(2), bit_size: Integer(U32), value: 32837 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 1 }, Stop { return_data: HeapVector { pointer: Relative(2), size: Relative(3) } }, Return, Call { location: 40 }, Mov { destination: Relative(2), source: Direct(1) }, BinaryIntOp { destination: Direct(1), op: Add, bit_size: U32, lhs: Direct(1), rhs: Direct(2) }, Const { destination: Relative(3), bit_size: Field, value: 1 }, Store { destination_pointer: Relative(2), source: Relative(3) }, Const { destination: Relative(4), bit_size: Field, value: 2 }, JumpIf { condition: Relative(1), location: 23 }, Jump { location: 25 }, Store { destination_pointer: Relative(2), source: Relative(4) }, Jump { location: 25 }, Load { destination: Relative(5), source_pointer: Relative(2) }, BinaryFieldOp { destination: Relative(2), op: Equals, lhs: Relative(5), rhs: Relative(3) }, JumpIf { condition: Relative(2), location: 36 }, Jump { location: 29 }, BinaryFieldOp { destination: Relative(2), op: Equals, lhs: Relative(5), rhs: Relative(4) }, JumpIf { condition: Relative(2), location: 33 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 0 }, Trap { revert_data: HeapVector { pointer: Direct(1), size: Relative(3) } }, Const { destination: Relative(2), bit_size: Integer(U1), value: 1 }, Mov { destination: Relative(1), source: Relative(2) }, Jump { location: 39 }, Const { destination: Relative(2), bit_size: Integer(U1), value: 0 }, Mov { destination: Relative(1), source: Relative(2) }, Jump { location: 39 }, Return, Const { destination: Direct(32772), bit_size: Integer(U32), value: 30720 }, BinaryIntOp { destination: Direct(32771), op: LessThan, bit_size: U32, lhs: Direct(0), rhs: Direct(32772) }, JumpIf { condition: Direct(32771), location: 45 }, IndirectConst { destination_pointer: Direct(1), bit_size: Integer(U64), value: 17843811134343075018 }, Trap { revert_data: HeapVector { pointer: Direct(1), size: Direct(2) } }, Return]" + ], + "debug_symbols": "tZHLDoMgEEX/ZdYsgGof/krTGNSxISFoEJo0hn/v4KPqostu5jJczp2EGaHBKjxLbdtugOI+QuW0MfpZmq5WXneWbkfgqcgcCslAnqE4kdwmOfFZxCySJEYGK116h5jgXRwN6ZVD66GwwRgGL2XC9GjolZ3UK0cuZ4C2IaXAVhtMp8g2mv9GRS4WWJyzL54fefE/XvLrwktxOfAP6lSt3eGDY0pyWlUGl7YNtt65/t2vzrqg3nU1NsFhStq2JKjeM86y/BHTtA8=", + "file_map": { + "50": { + "source": "struct Context {\n f: fn() -> bool,\n}\nfn main(c: bool) -> pub bool {\n let mut ctx = Context { f: bar };\n if c {\n ctx.f = qux;\n }\n foo(&mut ctx)\n}\n\nfn foo(ctx: &mut Context) -> bool {\n (ctx.f)()\n}\n\nfn bar() -> bool {\n false\n}\n\nfn qux() -> bool {\n true\n}\n", + "path": "" + } + }, + "names": [ + "main" + ], + "brillig_names": [ + "main" + ] +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_0.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_0.snap new file mode 100644 index 00000000000..24827910591 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_0.snap @@ -0,0 +1,54 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [ + { + "name": "c", + "type": { + "kind": "boolean" + }, + "visibility": "private" + } + ], + "return_type": { + "abi_type": { + "kind": "boolean" + }, + "visibility": "public" + }, + "error_types": { + "17843811134343075018": { + "error_kind": "string", + "string": "Stack too deep" + } + } + }, + "bytecode": [ + "func 0", + "current witness index : _1", + "private parameters indices : [_0]", + "public parameters indices : []", + "return value indices : [_1]", + "BRILLIG CALL func 0: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })], outputs: [Simple(Witness(1))]", + "unconstrained func 0", + "[Const { destination: Direct(2), bit_size: Integer(U32), value: 1 }, Const { destination: Direct(1), bit_size: Integer(U32), value: 32838 }, Const { destination: Direct(0), bit_size: Integer(U32), value: 3 }, Const { destination: Relative(2), bit_size: Integer(U32), value: 1 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 0 }, CalldataCopy { destination_address: Direct(32836), size_address: Relative(2), offset_address: Relative(3) }, Cast { destination: Direct(32836), source: Direct(32836), bit_size: Integer(U1) }, Mov { destination: Relative(1), source: Direct(32836) }, Call { location: 14 }, Call { location: 15 }, Mov { destination: Direct(32837), source: Relative(1) }, Const { destination: Relative(2), bit_size: Integer(U32), value: 32837 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 1 }, Stop { return_data: HeapVector { pointer: Relative(2), size: Relative(3) } }, Return, Call { location: 40 }, Mov { destination: Relative(2), source: Direct(1) }, BinaryIntOp { destination: Direct(1), op: Add, bit_size: U32, lhs: Direct(1), rhs: Direct(2) }, Const { destination: Relative(3), bit_size: Field, value: 1 }, Store { destination_pointer: Relative(2), source: Relative(3) }, Const { destination: Relative(4), bit_size: Field, value: 2 }, JumpIf { condition: Relative(1), location: 23 }, Jump { location: 25 }, Store { destination_pointer: Relative(2), source: Relative(4) }, Jump { location: 25 }, Load { destination: Relative(5), source_pointer: Relative(2) }, BinaryFieldOp { destination: Relative(2), op: Equals, lhs: Relative(5), rhs: Relative(3) }, JumpIf { condition: Relative(2), location: 36 }, Jump { location: 29 }, BinaryFieldOp { destination: Relative(2), op: Equals, lhs: Relative(5), rhs: Relative(4) }, JumpIf { condition: Relative(2), location: 33 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 0 }, Trap { revert_data: HeapVector { pointer: Direct(1), size: Relative(3) } }, Const { destination: Relative(2), bit_size: Integer(U1), value: 1 }, Mov { destination: Relative(1), source: Relative(2) }, Jump { location: 39 }, Const { destination: Relative(2), bit_size: Integer(U1), value: 0 }, Mov { destination: Relative(1), source: Relative(2) }, Jump { location: 39 }, Return, Const { destination: Direct(32772), bit_size: Integer(U32), value: 30720 }, BinaryIntOp { destination: Direct(32771), op: LessThan, bit_size: U32, lhs: Direct(0), rhs: Direct(32772) }, JumpIf { condition: Direct(32771), location: 45 }, IndirectConst { destination_pointer: Direct(1), bit_size: Integer(U64), value: 17843811134343075018 }, Trap { revert_data: HeapVector { pointer: Direct(1), size: Direct(2) } }, Return]" + ], + "debug_symbols": "tZHLDoMgEEX/ZdYsgGof/krTGNSxISFoEJo0hn/v4KPqostu5jJczp2EGaHBKjxLbdtugOI+QuW0MfpZmq5WXneWbkfgqcgcCslAnqE4kdwmOfFZxCySJEYGK116h5jgXRwN6ZVD66GwwRgGL2XC9GjolZ3UK0cuZ4C2IaXAVhtMp8g2mv9GRS4WWJyzL54fefE/XvLrwktxOfAP6lSt3eGDY0pyWlUGl7YNtt65/t2vzrqg3nU1NsFhStq2JKjeM86y/BHTtA8=", + "file_map": { + "50": { + "source": "struct Context {\n f: fn() -> bool,\n}\nfn main(c: bool) -> pub bool {\n let mut ctx = Context { f: bar };\n if c {\n ctx.f = qux;\n }\n foo(&mut ctx)\n}\n\nfn foo(ctx: &mut Context) -> bool {\n (ctx.f)()\n}\n\nfn bar() -> bool {\n false\n}\n\nfn qux() -> bool {\n true\n}\n", + "path": "" + } + }, + "names": [ + "main" + ], + "brillig_names": [ + "main" + ] +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_9223372036854775807.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_9223372036854775807.snap new file mode 100644 index 00000000000..24827910591 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__force_brillig_true_inliner_9223372036854775807.snap @@ -0,0 +1,54 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: artifact +--- +{ + "noir_version": "[noir_version]", + "hash": "[hash]", + "abi": { + "parameters": [ + { + "name": "c", + "type": { + "kind": "boolean" + }, + "visibility": "private" + } + ], + "return_type": { + "abi_type": { + "kind": "boolean" + }, + "visibility": "public" + }, + "error_types": { + "17843811134343075018": { + "error_kind": "string", + "string": "Stack too deep" + } + } + }, + "bytecode": [ + "func 0", + "current witness index : _1", + "private parameters indices : [_0]", + "public parameters indices : []", + "return value indices : [_1]", + "BRILLIG CALL func 0: inputs: [Single(Expression { mul_terms: [], linear_combinations: [(1, Witness(0))], q_c: 0 })], outputs: [Simple(Witness(1))]", + "unconstrained func 0", + "[Const { destination: Direct(2), bit_size: Integer(U32), value: 1 }, Const { destination: Direct(1), bit_size: Integer(U32), value: 32838 }, Const { destination: Direct(0), bit_size: Integer(U32), value: 3 }, Const { destination: Relative(2), bit_size: Integer(U32), value: 1 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 0 }, CalldataCopy { destination_address: Direct(32836), size_address: Relative(2), offset_address: Relative(3) }, Cast { destination: Direct(32836), source: Direct(32836), bit_size: Integer(U1) }, Mov { destination: Relative(1), source: Direct(32836) }, Call { location: 14 }, Call { location: 15 }, Mov { destination: Direct(32837), source: Relative(1) }, Const { destination: Relative(2), bit_size: Integer(U32), value: 32837 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 1 }, Stop { return_data: HeapVector { pointer: Relative(2), size: Relative(3) } }, Return, Call { location: 40 }, Mov { destination: Relative(2), source: Direct(1) }, BinaryIntOp { destination: Direct(1), op: Add, bit_size: U32, lhs: Direct(1), rhs: Direct(2) }, Const { destination: Relative(3), bit_size: Field, value: 1 }, Store { destination_pointer: Relative(2), source: Relative(3) }, Const { destination: Relative(4), bit_size: Field, value: 2 }, JumpIf { condition: Relative(1), location: 23 }, Jump { location: 25 }, Store { destination_pointer: Relative(2), source: Relative(4) }, Jump { location: 25 }, Load { destination: Relative(5), source_pointer: Relative(2) }, BinaryFieldOp { destination: Relative(2), op: Equals, lhs: Relative(5), rhs: Relative(3) }, JumpIf { condition: Relative(2), location: 36 }, Jump { location: 29 }, BinaryFieldOp { destination: Relative(2), op: Equals, lhs: Relative(5), rhs: Relative(4) }, JumpIf { condition: Relative(2), location: 33 }, Const { destination: Relative(3), bit_size: Integer(U32), value: 0 }, Trap { revert_data: HeapVector { pointer: Direct(1), size: Relative(3) } }, Const { destination: Relative(2), bit_size: Integer(U1), value: 1 }, Mov { destination: Relative(1), source: Relative(2) }, Jump { location: 39 }, Const { destination: Relative(2), bit_size: Integer(U1), value: 0 }, Mov { destination: Relative(1), source: Relative(2) }, Jump { location: 39 }, Return, Const { destination: Direct(32772), bit_size: Integer(U32), value: 30720 }, BinaryIntOp { destination: Direct(32771), op: LessThan, bit_size: U32, lhs: Direct(0), rhs: Direct(32772) }, JumpIf { condition: Direct(32771), location: 45 }, IndirectConst { destination_pointer: Direct(1), bit_size: Integer(U64), value: 17843811134343075018 }, Trap { revert_data: HeapVector { pointer: Direct(1), size: Direct(2) } }, Return]" + ], + "debug_symbols": "tZHLDoMgEEX/ZdYsgGof/krTGNSxISFoEJo0hn/v4KPqostu5jJczp2EGaHBKjxLbdtugOI+QuW0MfpZmq5WXneWbkfgqcgcCslAnqE4kdwmOfFZxCySJEYGK116h5jgXRwN6ZVD66GwwRgGL2XC9GjolZ3UK0cuZ4C2IaXAVhtMp8g2mv9GRS4WWJyzL54fefE/XvLrwktxOfAP6lSt3eGDY0pyWlUGl7YNtt65/t2vzrqg3nU1NsFhStq2JKjeM86y/BHTtA8=", + "file_map": { + "50": { + "source": "struct Context {\n f: fn() -> bool,\n}\nfn main(c: bool) -> pub bool {\n let mut ctx = Context { f: bar };\n if c {\n ctx.f = qux;\n }\n foo(&mut ctx)\n}\n\nfn foo(ctx: &mut Context) -> bool {\n (ctx.f)()\n}\n\nfn bar() -> bool {\n false\n}\n\nfn qux() -> bool {\n true\n}\n", + "path": "" + } + }, + "names": [ + "main" + ], + "brillig_names": [ + "main" + ] +} diff --git a/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__stdout.snap b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__stdout.snap new file mode 100644 index 00000000000..8fb3e939bd9 --- /dev/null +++ b/tooling/nargo_cli/tests/snapshots/execution_success/regression_8662/execute__tests__stdout.snap @@ -0,0 +1,5 @@ +--- +source: tooling/nargo_cli/tests/execute.rs +expression: stdout +--- +[regression_8662] Circuit output: Field(1)