Skip to content

Commit b1142b6

Browse files
authored
chore: interpret all execution_success programs (#8887)
1 parent f34d5c2 commit b1142b6

10 files changed

Lines changed: 164 additions & 17 deletions

File tree

compiler/noirc_driver/src/abi_gen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use noirc_frontend::{
2323

2424
/// Arranges a function signature and a generated circuit's return witnesses into a
2525
/// `noirc_abi::Abi`.
26-
pub(super) fn gen_abi(
26+
pub fn gen_abi(
2727
context: &Context,
2828
func_id: &FuncId,
2929
return_visibility: Visibility,

compiler/noirc_driver/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ mod stdlib;
3838

3939
use debug::filter_relevant_files;
4040

41+
pub use abi_gen::gen_abi;
4142
pub use contract::{CompiledContract, CompiledContractOutputs, ContractFunction};
4243
pub use debug::DebugFile;
4344
pub use noirc_frontend::graph::{CrateId, CrateName};
@@ -794,7 +795,7 @@ pub fn compile_no_check(
794795
create_program(program, &ssa_evaluator_options)?
795796
};
796797

797-
let abi = abi_gen::gen_abi(context, &main_function, return_visibility, error_types);
798+
let abi = gen_abi(context, &main_function, return_visibility, error_types);
798799
let file_map = filter_relevant_files(&debug, &context.file_manager);
799800

800801
Ok(CompiledProgram {

tooling/nargo_cli/build.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ fn main() {
4242
generate_compile_success_with_bug_tests(&mut test_file, &test_dir);
4343
generate_compile_failure_tests(&mut test_file, &test_dir);
4444

45+
generate_interpret_execution_success_tests(&mut test_file, &test_dir);
46+
4547
generate_fuzzing_failure_tests(&mut test_file, &test_dir);
4648

4749
generate_nargo_expand_execution_success_tests(&mut test_file, &test_dir);
@@ -115,6 +117,81 @@ const TESTS_WITH_EXPECTED_WARNINGS: [&str; 5] = [
115117
"brillig_continue_break",
116118
];
117119

120+
/// `nargo interpret` ignored tests, either because they don't currently work or
121+
/// becuase they are too slow to run.
122+
const IGNORED_INTERPRET_EXECUTION_TESTS: [&str; 35] = [
123+
// slow
124+
"regression_4709",
125+
// panic: index out of bounds
126+
"array_dynamic_nested_blackbox_input",
127+
// gives a different result with `--force-brillig`
128+
"array_oob_regression_7965",
129+
// gives a different result with `--force-brillig`
130+
"array_oob_regression_7975",
131+
// panic: FunctionReturnedIncorrectArgCount
132+
"as_witness",
133+
// wrong result
134+
"brillig_block_parameter_liveness",
135+
// panic: BlockArgumentCountMismatch
136+
"brillig_cow_regression",
137+
// wrong result
138+
"databus",
139+
// panic: index out of bounds
140+
"databus_composite_calldata",
141+
// wrong result
142+
"databus_two_calldata",
143+
// wrong result
144+
"databus_two_calldata_simple",
145+
// panic: IntrinsicArgumentCountMismatch
146+
"fold_numeric_generic_poseidon",
147+
// gives a different result with `--force-brillig`
148+
"global_array_rc_regression_8259",
149+
// panic: IntrinsicArgumentCountMismatch
150+
"hash_to_field",
151+
// panic: Internal(TypeError)
152+
"inline_decompose_hint_brillig_call",
153+
// panic: Internal(TypeError)
154+
"multi_scalar_mul",
155+
// gives a different result with `--force-brillig`
156+
"nested_if_then_block_same_cond",
157+
// panic: IntrinsicArgumentCountMismatch
158+
"no_predicates_numeric_generic_poseidon",
159+
// panic: IntrinsicArgumentCountMismatch
160+
"ram_blowup_regression",
161+
// panic: index out of bounds
162+
"regression_11294",
163+
// panic: Internal(TypeError)
164+
"regression_3889",
165+
// panic: IntrinsicArgumentCountMismatch
166+
"regression_5252",
167+
// panic: IntrinsicArgumentCountMismatch
168+
"regression_7128",
169+
// panic: index out of bounds
170+
"regression_7612",
171+
// gives a wrong result
172+
"regression_7744",
173+
// gives a wrong result
174+
"regression_8174",
175+
// panic: index out of bounds
176+
"regression_struct_array_conditional",
177+
// panic Internal(TypeError)
178+
"simple_shield",
179+
// panic: index out of bounds
180+
"slice_loop",
181+
// panic: index out of bounds
182+
"struct_array_inputs",
183+
// panic: BlockArgumentCountMismatch
184+
"struct_inputs",
185+
// panic: IntrinsicArgumentCountMismatch
186+
"to_be_bytes",
187+
// panic: IntrinsicArgumentCountMismatch
188+
"to_le_bytes",
189+
// panic: BlockArgumentCountMismatch
190+
"tuple_inputs",
191+
// panic: IntrinsicArgumentCountMismatch
192+
"unrolling_regression_8333",
193+
];
194+
118195
/// These tests are ignored because making them work involves a more complex test code that
119196
/// might not be worth it.
120197
/// Others are ignored because of existing bugs in `nargo expand`.
@@ -381,6 +458,7 @@ fn test_{test_name}() {{
381458
)
382459
.expect("Could not write templated test file.");
383460
}
461+
384462
fn generate_execution_success_tests(test_file: &mut File, test_data_dir: &Path) {
385463
let test_type = "execution_success";
386464
let test_cases = read_test_cases(test_data_dir, test_type);
@@ -699,6 +777,41 @@ fn generate_compile_failure_tests(test_file: &mut File, test_data_dir: &Path) {
699777
writeln!(test_file, "}}").unwrap();
700778
}
701779

780+
fn generate_interpret_execution_success_tests(test_file: &mut File, test_data_dir: &Path) {
781+
let test_type = "execution_success";
782+
let test_cases = read_test_cases(test_data_dir, test_type);
783+
784+
writeln!(
785+
test_file,
786+
"mod interpret_{test_type} {{
787+
use super::*;
788+
"
789+
)
790+
.unwrap();
791+
for (test_name, test_dir) in test_cases {
792+
if IGNORED_INTERPRET_EXECUTION_TESTS.contains(&test_name.as_str()) {
793+
continue;
794+
}
795+
796+
let test_dir = test_dir.display();
797+
798+
generate_test_cases(
799+
test_file,
800+
&test_name,
801+
&test_dir,
802+
"interpret",
803+
"interpret_execution_success(nargo);",
804+
&MatrixConfig {
805+
vary_brillig: !IGNORED_BRILLIG_TESTS.contains(&test_name.as_str()),
806+
vary_inliner: true,
807+
min_inliner: min_inliner(&test_name),
808+
max_inliner: max_inliner(&test_name),
809+
},
810+
);
811+
}
812+
writeln!(test_file, "}}").unwrap();
813+
}
814+
702815
/// Here we check, for every program in `test_programs/exeuction_success`, that:
703816
/// 1. `nargo expand` works on it
704817
/// 2. That the output of the original program is the same as the output of the expanded program

tooling/nargo_cli/src/cli/interpret_cmd.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
//! Use the SSA Interpreter to execute a SSA after a certain pass.
22
3+
use std::collections::BTreeMap;
4+
35
use acvm::acir::circuit::ExpressionWidth;
46
use fm::{FileId, FileManager};
57
use nargo::constants::PROVER_INPUT_FILE;
68
use nargo::ops::report_errors;
79
use nargo::package::Package;
810
use nargo::workspace::Workspace;
911
use nargo_toml::PackageSelection;
10-
use noirc_driver::{CompilationResult, CompileOptions};
12+
use noirc_abi::Abi;
13+
use noirc_driver::{CompilationResult, CompileOptions, gen_abi};
1114

1215
use clap::Args;
1316
use noirc_errors::CustomDiagnostic;
@@ -80,15 +83,14 @@ pub(crate) fn run(args: InterpretCommand, workspace: Workspace) -> Result<(), Cl
8083
);
8184

8285
// Report warnings and get the AST, or exit if the compilation failed.
83-
let program = report_errors(
86+
let (program, abi) = report_errors(
8487
program_result,
8588
&file_manager,
8689
args.compile_options.deny_warnings,
8790
args.compile_options.silence_warnings,
8891
)?;
8992

9093
// Parse the inputs and convert them to what the SSA interpreter expects.
91-
let abi = noir_ast_fuzzer::program_abi(&program);
9294
let prover_file = package.root_dir.join(&args.prover_name).with_extension("toml");
9395
let (prover_input, return_value) =
9496
noir_artifact_cli::fs::inputs::read_inputs_from_file(&prover_file, &abi)?;
@@ -154,7 +156,7 @@ fn compile_into_program(
154156
workspace: &Workspace,
155157
package: &Package,
156158
options: &CompileOptions,
157-
) -> CompilationResult<Program> {
159+
) -> CompilationResult<(Program, Abi)> {
158160
let (mut context, crate_id) = nargo::prepare_package(file_manager, parsed_files, package);
159161
if options.disable_comptime_printing {
160162
context.disable_comptime_printing();
@@ -191,7 +193,10 @@ fn compile_into_program(
191193
println!("{program}");
192194
}
193195

194-
Ok((program, warnings))
196+
let error_types = BTreeMap::default();
197+
let abi = gen_abi(&context, &main_id, program.return_visibility(), error_types);
198+
199+
Ok(((program, abi), warnings))
195200
}
196201

197202
fn to_ssa_options(options: &CompileOptions) -> SsaEvaluatorOptions {

tooling/nargo_cli/tests/execute.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ mod tests {
322322
})
323323
}
324324

325+
fn interpret_execution_success(mut nargo: Command) {
326+
nargo.assert().success();
327+
}
328+
325329
fn nargo_expand_execute(test_program_dir: PathBuf) {
326330
// First run `nargo execute` on the original code to get the output
327331
let mut nargo = Command::cargo_bin("nargo").unwrap();

tooling/noirc_abi/src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub enum InputParserError {
2626
FieldElement::modulus()
2727
)]
2828
InputExceedsFieldModulus { arg_name: String, value: String },
29-
#[error("cannot parse value into {0:?}")]
30-
AbiTypeMismatch(AbiType),
29+
#[error("cannot parse value `{0}` into {1:?}")]
30+
AbiTypeMismatch(String, AbiType),
3131
#[error("Expected argument `{0}`, but none was found")]
3232
MissingArgument(String),
3333
}

tooling/noirc_abi/src/input_parser/json.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,12 @@ impl JsonTypes {
120120
JsonTypes::Array(fields)
121121
}
122122

123-
_ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())),
123+
_ => {
124+
return Err(InputParserError::AbiTypeMismatch(
125+
format!("{value:?}"),
126+
abi_type.clone(),
127+
));
128+
}
124129
};
125130
Ok(json_value)
126131
}
@@ -212,7 +217,12 @@ impl InputValue {
212217
InputValue::Vec(tuple_fields)
213218
}
214219

215-
(_, _) => return Err(InputParserError::AbiTypeMismatch(param_type.clone())),
220+
(value, _) => {
221+
return Err(InputParserError::AbiTypeMismatch(
222+
format!("{value:?}"),
223+
param_type.clone(),
224+
));
225+
}
216226
};
217227

218228
Ok(input_value)

tooling/noirc_abi/src/input_parser/toml.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,12 @@ impl TomlTypes {
118118
TomlTypes::Array(fields)
119119
}
120120

121-
_ => return Err(InputParserError::AbiTypeMismatch(abi_type.clone())),
121+
_ => {
122+
return Err(InputParserError::AbiTypeMismatch(
123+
format!("{value:?}"),
124+
abi_type.clone(),
125+
));
126+
}
122127
};
123128
Ok(toml_value)
124129
}
@@ -197,7 +202,12 @@ impl InputValue {
197202
InputValue::Vec(tuple_fields)
198203
}
199204

200-
(_, _) => return Err(InputParserError::AbiTypeMismatch(param_type.clone())),
205+
(value, _) => {
206+
return Err(InputParserError::AbiTypeMismatch(
207+
format!("{value:?}"),
208+
param_type.clone(),
209+
));
210+
}
201211
};
202212

203213
Ok(input_value)

tooling/noirc_abi_wasm/test/browser/errors.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ it('errors when an integer input overflows', async () => {
1616
it('errors when passing a field in place of an array', async () => {
1717
const { abi, inputs } = await import('../shared/field_as_array');
1818

19-
expect(() => abiEncode(abi, inputs)).to.throw('cannot parse value into Array { length: 2, typ: Field }');
19+
expect(() => abiEncode(abi, inputs)).to.throw(
20+
'cannot parse value `String("1")` into Array { length: 2, typ: Field }',
21+
);
2022
});
2123

2224
it('errors when passing an array in place of a field', async () => {
2325
const { abi, inputs } = await import('../shared/array_as_field');
2426

25-
expect(() => abiEncode(abi, inputs)).to.throw('cannot parse value into Field');
27+
expect(() => abiEncode(abi, inputs)).to.throw('cannot parse value `Array([String("1"), String("2")])` into Field');
2628
});

tooling/noirc_abi_wasm/test/node/errors.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ it('errors when an integer input overflows', async () => {
1212
it('errors when passing a field in place of an array', async () => {
1313
const { abi, inputs } = await import('../shared/field_as_array');
1414

15-
expect(() => abiEncode(abi, inputs)).to.throw('cannot parse value into Array { length: 2, typ: Field }');
15+
expect(() => abiEncode(abi, inputs)).to.throw(
16+
'cannot parse value `String("1")` into Array { length: 2, typ: Field }',
17+
);
1618
});
1719

1820
it('errors when passing an array in place of a field', async () => {
1921
const { abi, inputs } = await import('../shared/array_as_field');
2022

21-
expect(() => abiEncode(abi, inputs)).to.throw('cannot parse value into Field');
23+
expect(() => abiEncode(abi, inputs)).to.throw('cannot parse value `Array([String("1"), String("2")])` into Field');
2224
});

0 commit comments

Comments
 (0)