diff --git a/Cargo.lock b/Cargo.lock index 73be34e3ff3..0e5481d6272 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,7 @@ dependencies = [ "criterion", "flate2", "fxhash", + "insta", "noir_protobuf", "num-bigint", "pprof", @@ -2571,6 +2572,19 @@ dependencies = [ "smallvec", ] +[[package]] +name = "insta" +version = "1.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084" +dependencies = [ + "console", + "linked-hash-map", + "once_cell", + "pin-project", + "similar", +] + [[package]] name = "is-terminal" version = "0.4.15" @@ -2890,6 +2904,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.15" diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml index 5d7b347c511..ae8d0db36c9 100644 --- a/acvm-repo/acir/Cargo.toml +++ b/acvm-repo/acir/Cargo.toml @@ -46,6 +46,7 @@ fxhash.workspace = true criterion.workspace = true pprof.workspace = true num-bigint.workspace = true +insta = "1.42.2" acir = { path = ".", features = ["arb"] } # Self to turn on `arb`. diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs index d11680ed0f4..0e31e6f9080 100644 --- a/acvm-repo/acir/src/circuit/opcodes.rs +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -175,7 +175,9 @@ impl std::fmt::Display for Opcode { BlockType::CallData(id) => write!(f, "INIT CALLDATA {} ", id)?, BlockType::ReturnData => write!(f, "INIT RETURNDATA ")?, } - write!(f, "(id: {}, len: {}) ", block_id.0, init.len()) + let witnesses = + init.iter().map(|w| format!("_{}", w.0)).collect::>().join(", "); + write!(f, "(id: {}, len: {}, witnesses: [{witnesses}])", block_id.0, init.len()) } // We keep the display for a BrilligCall and circuit Call separate as they // are distinct in their functionality and we should maintain this separation for debugging. @@ -204,3 +206,43 @@ impl std::fmt::Debug for Opcode { std::fmt::Display::fmt(self, f) } } + +#[cfg(test)] +mod tests { + use acir_field::FieldElement; + + use crate::{ + circuit::opcodes::{BlackBoxFuncCall, BlockId, BlockType, FunctionInput}, + native_types::Witness, + }; + + use super::Opcode; + + #[test] + fn mem_init_display_snapshot() { + let mem_init: Opcode = Opcode::MemoryInit { + block_id: BlockId(42), + init: (0..10u32).map(Witness).collect(), + block_type: BlockType::Memory, + }; + + insta::assert_snapshot!( + mem_init.to_string(), + @"INIT (id: 42, len: 10, witnesses: [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9])" + ); + } + + #[test] + fn blackbox_snapshot() { + let xor: Opcode = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::XOR { + lhs: FunctionInput::witness(0.into(), 32), + rhs: FunctionInput::witness(1.into(), 32), + output: Witness(3), + }); + + insta::assert_snapshot!( + xor.to_string(), + @"BLACKBOX::XOR [(_0, 32), (_1, 32)] [_3]" + ); + } +} diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 04655ef4a50..9fd1587d0f5 100644 --- a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -85,8 +85,12 @@ impl FunctionInput { impl std::fmt::Display for FunctionInput { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.input { - ConstantOrWitnessEnum::Constant(constant) => write!(f, "{constant}"), - ConstantOrWitnessEnum::Witness(witness) => write!(f, "{}", witness.0), + ConstantOrWitnessEnum::Constant(constant) => { + write!(f, "({constant}, {})", self.num_bits) + } + ConstantOrWitnessEnum::Witness(witness) => { + write!(f, "(_{}, {})", witness.0, self.num_bits) + } } } } @@ -463,80 +467,33 @@ impl BlackBoxFuncCall { } } -const ABBREVIATION_LIMIT: usize = 5; - -fn get_inputs_string(inputs: &[FunctionInput]) -> String { - // Once a vectors length gets above this limit, - // instead of listing all of their elements, we use ellipses - // to abbreviate them - let should_abbreviate_inputs = inputs.len() <= ABBREVIATION_LIMIT; - - if should_abbreviate_inputs { - let mut result = String::new(); - for (index, inp) in inputs.iter().enumerate() { - result += &format!("({})", inp); - // Add a comma, unless it is the last entry - if index != inputs.len() - 1 { - result += ", "; - } - } - result - } else { - let first = inputs.first().unwrap(); - let last = inputs.last().unwrap(); - - let mut result = String::new(); - result += &format!("({})...({})", first, last,); - - result - } -} - -fn get_outputs_string(outputs: &[Witness]) -> String { - let should_abbreviate_outputs = outputs.len() <= ABBREVIATION_LIMIT; - - if should_abbreviate_outputs { - let mut result = String::new(); - for (index, output) in outputs.iter().enumerate() { - result += &format!("_{}", output.witness_index()); - // Add a comma, unless it is the last entry - if index != outputs.len() - 1 { - result += ", "; - } - } - result - } else { - let first = outputs.first().unwrap(); - let last = outputs.last().unwrap(); - - let mut result = String::new(); - result += &format!("(_{},...,_{})", first.witness_index(), last.witness_index()); - result - } -} - impl std::fmt::Display for BlackBoxFuncCall { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let uppercase_name = self.name().to_uppercase(); write!(f, "BLACKBOX::{uppercase_name} ")?; // INPUTS - write!(f, "[")?; - let inputs_str = get_inputs_string(&self.get_inputs_vec()); + let inputs_str = &self + .get_inputs_vec() + .iter() + .map(|i| i.to_string()) + .collect::>() + .join(", "); - write!(f, "{inputs_str}")?; - write!(f, "] ")?; + write!(f, "[{inputs_str}]")?; - // OUTPUTS - write!(f, "[ ")?; + write!(f, " ")?; - let outputs_str = get_outputs_string(&self.get_outputs_vec()); - - write!(f, "{outputs_str}")?; + // OUTPUTS - write!(f, "]")?; + let outputs_str = &self + .get_outputs_vec() + .iter() + .map(|i| format!("_{}", i.0)) + .collect::>() + .join(", "); - write!(f, "") + write!(f, "[{outputs_str}]") } } diff --git a/cspell.json b/cspell.json index cda513ca994..810d3163673 100644 --- a/cspell.json +++ b/cspell.json @@ -128,6 +128,7 @@ "indexmap", "injective", "Inlines", + "insta", "instrumenter", "interner", "interners",