Skip to content

Commit

Permalink
fix: let static_assert fail with the provided message (#7005)
Browse files Browse the repository at this point in the history
Co-authored-by: jfecher <[email protected]>
Co-authored-by: Tom French <[email protected]>
  • Loading branch information
3 people authored Jan 10, 2025
1 parent 24433fe commit 268229e
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 20 deletions.
6 changes: 3 additions & 3 deletions compiler/noirc_evaluator/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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, .. }
Expand Down
18 changes: 18 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/dfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> {
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)]
Expand Down
21 changes: 5 additions & 16 deletions compiler/noirc_evaluator/src/ssa/ir/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,22 +274,11 @@ pub(crate) fn try_to_extract_string_from_error_payload(
values: &[ValueId],
dfg: &DataFlowGraph,
) -> Option<String> {
(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::<Option<Vec<_>>>()
})
.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(
Expand Down
6 changes: 5 additions & 1 deletion compiler/noirc_evaluator/src/ssa/opt/assert_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
}
Expand Down
7 changes: 7 additions & 0 deletions noir_stdlib/src/lib.nr
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

0 comments on commit 268229e

Please sign in to comment.