Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion compiler/noirc_evaluator/src/acir/call/intrinsics/vector_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ impl Context<'_> {
let vector_typ = dfg.type_of_value(vector_contents);
let block_id = self.ensure_array_is_initialized(vector_contents, dfg)?;

// Check if we're trying to pop from an empty vector
// Check if we're trying to pop from a known empty vector.
if self.has_zero_length(vector_contents, dfg) {
// Make sure this code is disabled, or fail with "Index out of bounds".
let msg = "cannot pop from a vector with length 0".to_string();
Expand All @@ -388,6 +388,19 @@ impl Context<'_> {
return Ok(results);
}

// Check that the vector length is not zero.
// This is different from the previous check as this is a runtime check.
let zero = self.acir_context.add_constant(FieldElement::zero());
let assert_message = self.acir_context.generate_assertion_message_payload(
"Attempt to pop_front from an empty vector".to_string(),
);
self.acir_context.assert_neq_var(
vector_length,
zero,
self.current_side_effects_enabled_var,
Some(assert_message),
)?;

let one = self.acir_context.add_constant(FieldElement::one());
let new_vector_length = self.acir_context.sub_var(vector_length, one)?;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "conditional_pop_back_from_empty_vector"
type = "bin"
authors = [""]
compiler_version = ">=0.23.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
input = [1]
b = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub fn main(input: [u32; 1], b: bool) -> pub u32 {
let mut s = input.as_vector();

if (b) {
let (new_slice, _) = s.pop_back();
s = new_slice;
} else {
s = s.push_front(5);
}

let (_, ret) = s.pop_back();

ret
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "conditional_pop_front_from_empty_vector"
type = "bin"
authors = [""]
compiler_version = ">=0.23.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
input = [1]
b = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub fn main(input: [u32; 1], b: bool) -> pub u32 {
let mut s = input.as_vector();

if (b) {
let (_, new_slice) = s.pop_front();
s = new_slice;
} else {
s = s.push_front(5);
}

let (ret, _) = s.pop_front();

ret
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "conditional_remove_from_empty_vector"
type = "bin"
authors = [""]
compiler_version = ">=0.23.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
input = [1]
b = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub fn main(input: [u32; 1], b: bool) -> pub u32 {
let mut s = input.as_vector();

if (b) {
let (new_slice, _) = s.remove(0);
s = new_slice;
} else {
s = s.push_front(5);
}

let (_, ret) = s.remove(0);

ret
}