diff --git a/.github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/aztec-nr.failures.jsonl.does_not_compile b/.github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/aztec-nr.failures.jsonl similarity index 100% rename from .github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/aztec-nr.failures.jsonl.does_not_compile rename to .github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/aztec-nr.failures.jsonl diff --git a/.github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/noir-contracts.failures.jsonl.does_not_compile b/.github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/noir-contracts.failures.jsonl similarity index 100% rename from .github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/noir-contracts.failures.jsonl.does_not_compile rename to .github/critical_libraries_status/AztecProtocol/aztec-packages/noir-projects/noir-contracts.failures.jsonl diff --git a/compiler/noirc_evaluator/src/errors.rs b/compiler/noirc_evaluator/src/errors.rs index 1e484f8af59..94c0e0554a4 100644 --- a/compiler/noirc_evaluator/src/errors.rs +++ b/compiler/noirc_evaluator/src/errors.rs @@ -49,8 +49,8 @@ pub enum RuntimeError { StaticAssertDynamicMessage { call_stack: CallStack }, #[error("Argument is dynamic")] StaticAssertDynamicPredicate { call_stack: CallStack }, - #[error("Argument is false")] - StaticAssertFailed { call_stack: CallStack }, + #[error("{message}")] + StaticAssertFailed { message: String, call_stack: CallStack }, #[error("Nested slices, i.e. slices within an array or slice, are not supported")] NestedSlice { call_stack: CallStack }, #[error("Big Integer modulus do no match")] @@ -165,7 +165,7 @@ impl RuntimeError { | RuntimeError::AssertConstantFailed { call_stack } | RuntimeError::StaticAssertDynamicMessage { call_stack } | RuntimeError::StaticAssertDynamicPredicate { call_stack } - | RuntimeError::StaticAssertFailed { call_stack } + | RuntimeError::StaticAssertFailed { call_stack, .. } | RuntimeError::IntegerOutOfBounds { call_stack, .. } | RuntimeError::UnsupportedIntegerSize { call_stack, .. } | RuntimeError::InvalidBlackBoxInputBitSize { call_stack, .. } diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index 8425e4d5e56..57e833af7eb 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -525,6 +525,24 @@ impl DataFlowGraph { } } + /// If this value points to an array of constant bytes, returns a string + /// consisting of those bytes if they form a valid UTF-8 string. + pub(crate) fn get_string(&self, value: ValueId) -> Option { + let (value_ids, _typ) = self.get_array_constant(value)?; + + let mut bytes = Vec::new(); + for value_id in value_ids { + let field_value = self.get_numeric_constant(value_id)?; + let u64_value = field_value.try_to_u64()?; + if u64_value > 255 { + return None; + }; + let byte = u64_value as u8; + bytes.push(byte); + } + String::from_utf8(bytes).ok() + } + /// A constant index less than the array length is safe pub(crate) fn is_safe_index(&self, index: ValueId, array: ValueId) -> bool { #[allow(clippy::match_like_matches_macro)] diff --git a/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/compiler/noirc_evaluator/src/ssa/ir/printer.rs index 9bf26b8414d..d30fce170dc 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -274,22 +274,11 @@ pub(crate) fn try_to_extract_string_from_error_payload( values: &[ValueId], dfg: &DataFlowGraph, ) -> Option { - (is_string_type && (values.len() == 1)) - .then_some(()) - .and_then(|()| { - let (values, _) = &dfg.get_array_constant(values[0])?; - let values = values.iter().map(|value_id| dfg.get_numeric_constant(*value_id)); - values.collect::>>() - }) - .map(|fields| { - fields - .iter() - .map(|field| { - let as_u8 = field.try_to_u64().unwrap_or_default() as u8; - as_u8 as char - }) - .collect() - }) + if is_string_type && values.len() == 1 { + dfg.get_string(values[0]) + } else { + None + } } fn display_constrain_error( diff --git a/compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs b/compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs index 6936c7ad542..192c0f59344 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs @@ -122,7 +122,11 @@ fn evaluate_static_assert( } else { let call_stack = function.dfg.get_instruction_call_stack(instruction); if function.dfg.is_constant(arguments[0]) { - Err(RuntimeError::StaticAssertFailed { call_stack }) + let message = function + .dfg + .get_string(arguments[1]) + .expect("Expected second argument to be a string"); + Err(RuntimeError::StaticAssertFailed { message, call_stack }) } else { Err(RuntimeError::StaticAssertDynamicPredicate { call_stack }) } diff --git a/docs/docs/getting_started/quick_start.md b/docs/docs/getting_started/quick_start.md index 7deeae12fd9..c980b5e7ffc 100644 --- a/docs/docs/getting_started/quick_start.md +++ b/docs/docs/getting_started/quick_start.md @@ -98,7 +98,7 @@ bb prove -b ./target/hello_world.json -w ./target/hello_world.gz -o ./target/pro :::tip -Naming can be confusing, specially as you pass them to the `bb` commands. If unsure, it won't hurt to delete the target folder and start anew to make sure you're using the most recent versions of the compiled circuit and witness. +Naming can be confusing, specially as you pass them to the `bb` commands. If unsure, it won't hurt to delete the target folder and start fresh to make sure you're using the most recent versions of the compiled circuit and witness. ::: diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 2e743822ffb..fb073516d29 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -120,3 +120,10 @@ where #[builtin(as_witness)] pub fn as_witness(x: Field) {} + +mod tests { + #[test(should_fail_with = "custom message")] + fn test_static_assert_custom_message() { + super::static_assert(1 == 2, "custom message"); + } +}