Skip to content

Commit f7c62f6

Browse files
authored
Merge ba0c6fa into 52daaec
2 parents 52daaec + ba0c6fa commit f7c62f6

File tree

1 file changed

+62
-61
lines changed
  • compiler/noirc_evaluator/src/ssa/acir_gen

1 file changed

+62
-61
lines changed

compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -658,75 +658,76 @@ impl Context {
658658
store_value: Option<ValueId>,
659659
) -> Result<bool, RuntimeError> {
660660
let index_const = dfg.get_numeric_constant(index);
661-
match dfg.type_of_value(array) {
662-
Type::Array(_, _) => {
663-
match self.convert_value(array, dfg) {
664-
AcirValue::Var(acir_var, _) => {
665-
return Err(RuntimeError::InternalError(InternalError::UnExpected {
666-
expected: "an array value".to_string(),
667-
found: format!("{acir_var:?}"),
668-
call_stack: self.acir_context.get_call_stack(),
669-
}))
670-
}
671-
AcirValue::Array(array) => {
672-
if let Some(index_const) = index_const {
673-
let array_size = array.len();
674-
let index = match index_const.try_to_u64() {
675-
Some(index_const) => index_const as usize,
676-
None => {
677-
let call_stack = self.acir_context.get_call_stack();
678-
return Err(RuntimeError::TypeConversion {
679-
from: "array index".to_string(),
680-
into: "u64".to_string(),
681-
call_stack,
682-
});
661+
let value_type = dfg.type_of_value(array);
662+
let (Type::Array(element_types, _) | Type::Slice(element_types)) = &value_type else {
663+
unreachable!("ICE: expected array or slice type");
664+
665+
};
666+
667+
// TODO(#3188): Need to be able to handle constant index for slices to seriously reduce
668+
// constraint sizes of nested slices
669+
// This can only be done if we accurately flatten nested slices as otherwise we will reach
670+
// index out of bounds errors. If the slice is already flat then we can treat them similarly to arrays.
671+
if matches!(value_type, Type::Slice(_))
672+
&& element_types.iter().any(|element| element.contains_slice_element())
673+
{
674+
return Ok(false);
675+
}
676+
677+
match self.convert_value(array, dfg) {
678+
AcirValue::Var(acir_var, _) => {
679+
return Err(RuntimeError::InternalError(InternalError::UnExpected {
680+
expected: "an array value".to_string(),
681+
found: format!("{acir_var:?}"),
682+
call_stack: self.acir_context.get_call_stack(),
683+
}))
684+
}
685+
AcirValue::Array(array) => {
686+
if let Some(index_const) = index_const {
687+
let array_size = array.len();
688+
let index = match index_const.try_to_u64() {
689+
Some(index_const) => index_const as usize,
690+
None => {
691+
let call_stack = self.acir_context.get_call_stack();
692+
return Err(RuntimeError::TypeConversion {
693+
from: "array index".to_string(),
694+
into: "u64".to_string(),
695+
call_stack,
696+
});
697+
}
698+
};
699+
if self.acir_context.is_constant_one(&self.current_side_effects_enabled_var) {
700+
// Report the error if side effects are enabled.
701+
if index >= array_size {
702+
let call_stack = self.acir_context.get_call_stack();
703+
return Err(RuntimeError::IndexOutOfBounds {
704+
index,
705+
array_size,
706+
call_stack,
707+
});
708+
} else {
709+
let value = match store_value {
710+
Some(store_value) => {
711+
let store_value = self.convert_value(store_value, dfg);
712+
AcirValue::Array(array.update(index, store_value))
683713
}
714+
None => array[index].clone(),
684715
};
685-
if self
686-
.acir_context
687-
.is_constant_one(&self.current_side_effects_enabled_var)
688-
{
689-
// Report the error if side effects are enabled.
690-
if index >= array_size {
691-
let call_stack = self.acir_context.get_call_stack();
692-
return Err(RuntimeError::IndexOutOfBounds {
693-
index,
694-
array_size,
695-
call_stack,
696-
});
697-
} else {
698-
let value = match store_value {
699-
Some(store_value) => {
700-
let store_value = self.convert_value(store_value, dfg);
701-
AcirValue::Array(array.update(index, store_value))
702-
}
703-
None => array[index].clone(),
704-
};
705716

706-
self.define_result(dfg, instruction, value);
707-
return Ok(true);
708-
}
709-
}
710-
// If there is a predicate and the index is not out of range, we can directly perform the read
711-
else if index < array_size && store_value.is_none() {
712-
self.define_result(dfg, instruction, array[index].clone());
713-
return Ok(true);
714-
}
717+
self.define_result(dfg, instruction, value);
718+
return Ok(true);
715719
}
716720
}
717-
AcirValue::DynamicArray(_) => (),
721+
// If there is a predicate and the index is not out of range, we can directly perform the read
722+
else if index < array_size && store_value.is_none() {
723+
self.define_result(dfg, instruction, array[index].clone());
724+
return Ok(true);
725+
}
718726
}
719727
}
720-
Type::Slice(_) => {
721-
// TODO(#3188): Need to be able to handle constant index for slices to seriously reduce
722-
// constraint sizes of nested slices
723-
// This can only be done if we accurately flatten nested slices as other we will reach
724-
// index out of bounds errors.
728+
AcirValue::DynamicArray(_) => (),
729+
};
725730

726-
// Do nothing we only want dynamic checks for slices
727-
}
728-
_ => unreachable!("ICE: expected array or slice type"),
729-
}
730731
Ok(false)
731732
}
732733

0 commit comments

Comments
 (0)