diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr index 488913311aa..a0460aafb40 100644 --- a/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/slices/src/main.nr @@ -5,7 +5,6 @@ fn main(x : Field, y : pub Field) { /// is not yet supported let mut slice: [Field] = [0; 2]; - assert(slice[0] == 0); assert(slice[0] != 1); slice[0] = x; diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/Nargo.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/Nargo.toml new file mode 100644 index 00000000000..7cae77988e3 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/Nargo.toml @@ -0,0 +1,5 @@ +[package] +authors = [""] +compiler_version = "0.7.1" + +[dependencies] \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/Prover.toml b/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/Prover.toml new file mode 100644 index 00000000000..f28f2f8cc48 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "10" diff --git a/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/src/main.nr b/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/src/main.nr new file mode 100644 index 00000000000..28187a4f619 --- /dev/null +++ b/crates/nargo_cli/tests/test_data_ssa_refactor/vectors/src/main.nr @@ -0,0 +1,32 @@ +use dep::std::collections::vec::Vec; + +fn main(x: Field, y: pub Field) { + let mut vector = Vec::new(); + + assert(vector.len() == 0); + for i in 0..5 { + vector.push(i); + } + assert(vector.len() == 5); + for i in 0..5 { + assert(i == vector.get(i)); + } + + let last_elem = vector.pop(); + assert(last_elem == 4); + assert(vector.len() == 4); + + vector.insert(2, 100); + assert(vector.get(2) == 100); + assert(vector.get(4) == 3); + assert(vector.len() == 5); + + let removed_elem = vector.remove(3); + assert(removed_elem == 2); + assert(vector.get(3) == 3); + assert(vector.len() == 4); + + let mut inputs_vector = Vec::from_slice([x, y]); + assert(inputs_vector.get(0) == x); + assert(inputs_vector.get(1) == y); +} diff --git a/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs b/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs index 796a5ef4643..25f06375732 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs @@ -300,7 +300,6 @@ impl Instruction { if let (Some((array, _)), Some(index)) = (array, index) { let index = index.try_to_u64().expect("Expected array index to fit in u64") as usize; - if index < array.len() { return SimplifiedTo(array[index]); } diff --git a/crates/noirc_frontend/src/hir/def_map/mod.rs b/crates/noirc_frontend/src/hir/def_map/mod.rs index eb2b8401e37..3997903a43e 100644 --- a/crates/noirc_frontend/src/hir/def_map/mod.rs +++ b/crates/noirc_frontend/src/hir/def_map/mod.rs @@ -93,7 +93,8 @@ impl CrateDefMap { .to_str() .expect("expected std path to be convertible to str"); assert_eq!(path_as_str, "std/lib"); - ast.module_decls.retain(|ident| ident.0.contents != "slice"); + ast.module_decls + .retain(|ident| ident.0.contents != "slice" && ident.0.contents != "collections"); } // Allocate a default Module for the root, giving it a ModuleId diff --git a/crates/noirc_frontend/src/lexer/token.rs b/crates/noirc_frontend/src/lexer/token.rs index 9dbf97f2d8a..16f8cfd3544 100644 --- a/crates/noirc_frontend/src/lexer/token.rs +++ b/crates/noirc_frontend/src/lexer/token.rs @@ -442,7 +442,6 @@ pub enum Keyword { Struct, Unconstrained, Use, - Vec, While, } @@ -478,7 +477,6 @@ impl fmt::Display for Keyword { Keyword::Struct => write!(f, "struct"), Keyword::Unconstrained => write!(f, "unconstrained"), Keyword::Use => write!(f, "use"), - Keyword::Vec => write!(f, "Vec"), Keyword::While => write!(f, "while"), } } @@ -517,7 +515,6 @@ impl Keyword { "struct" => Keyword::Struct, "unconstrained" => Keyword::Unconstrained, "use" => Keyword::Use, - "Vec" => Keyword::Vec, "while" => Keyword::While, "true" => return Some(Token::Bool(true)), diff --git a/noir_stdlib/src/collections/vec.nr b/noir_stdlib/src/collections/vec.nr new file mode 100644 index 00000000000..303dc4db029 --- /dev/null +++ b/noir_stdlib/src/collections/vec.nr @@ -0,0 +1,60 @@ +struct Vec { + slice: [T] +} + +// A mutable vector type implemented as a wrapper around immutable slices. +// A separate type is technically not needed but helps differentiate which operations are mutable. +impl Vec { + fn new() -> Self { + Self { slice: [] } + } + + // Create a Vec containing each element from the given slice. + // Mutations to the resulting Vec will not affect the original slice. + fn from_slice(slice: [T]) -> Self { + Self { slice } + } + + /// Get an element from the vector at the given index. + /// Panics if the given index + /// points beyond the end of the vector. + fn get(&mut self, index: Field) -> T { + self.slice[index] + } + + /// Push a new element to the end of the vector, returning a + /// new vector with a length one greater than the + /// original unmodified vector. + fn push(&mut self, elem: T) { + self.slice = self.slice.push_back(elem); + } + + /// Pop an element from the end of the given vector, returning + /// a new vector with a length of one less than the given vector, + /// as well as the popped element. + /// Panics if the given vector's length is zero. + fn pop(&mut self) -> T { + let (popped_slice, last_elem) = self.slice.pop_back(); + self.slice = popped_slice; + last_elem + } + + /// Insert an element at a specified index, shifting all elements + /// after it to the right + fn insert(&mut self, index: Field, elem: T) { + self.slice = self.slice.insert(index, elem); + } + + /// Remove an element at a specified index, shifting all elements + /// after it to the left, returning the removed element + fn remove(&mut self, index: Field) -> T { + let (new_slice, elem) = self.slice.remove(index); + self.slice = new_slice; + elem + } + + /// Returns the number of elements in the vector + fn len(self: Self) -> Field { + self.slice.len() + } +} \ No newline at end of file diff --git a/noir_stdlib/src/lib.nr b/noir_stdlib/src/lib.nr index 26a0492f2c5..7629634ac0a 100644 --- a/noir_stdlib/src/lib.nr +++ b/noir_stdlib/src/lib.nr @@ -12,6 +12,7 @@ mod sha512; mod field; mod ec; mod unsafe; +mod collections; mod compat; #[builtin(println)]