diff --git a/docs/src/basics/built_in_types.md b/docs/src/basics/built_in_types.md index 5ee06e8a07d..640105d3cdb 100644 --- a/docs/src/basics/built_in_types.md +++ b/docs/src/basics/built_in_types.md @@ -94,7 +94,7 @@ let w: (u64) = (42,); // type error ## Arrays -An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types include non-primitive types. +An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types including non-primitive types. An array is written as a comma-separated list inside square brackets: @@ -106,8 +106,13 @@ Arrays are allocated on the stack since their size is known. An array's size is Arrays can be iterated over, unlike tuples. An array's type is written as the type the array contains followed by the number of elements, semicolon-separated and within square brackets, e.g. `[u64; 5]`. To access an element in an array, use the _array indexing syntax_, i.e. square brackets. +Array elements can also be mutated if the underlying array is declared as mutable: + ```sway -{{#include ../../../examples/arrays/src/main.sw}} +let mut x = [1, 2, 3, 4, 5]; +x[0] = 0; ``` -> **Note**: Arrays are currently immutable which means that changing elements of an array once initialized is not yet possible. +```sway +{{#include ../../../examples/arrays/src/main.sw}} +``` diff --git a/examples/arrays/src/main.sw b/examples/arrays/src/main.sw index dc2133dd6b9..f03e75bfec3 100644 --- a/examples/arrays/src/main.sw +++ b/examples/arrays/src/main.sw @@ -25,6 +25,10 @@ fn main() { ]; // Accessing an element of an array - let array_of_bools: [bool; 2] = [true, false]; + let mut array_of_bools: [bool; 2] = [true, false]; assert(array_of_bools[0]); + + // Mutating the element of an array + array_of_bools[1] = true; + assert(array_of_bools[1]); } diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index f67ceaf17b6..ec0e66aa0b1 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -12,7 +12,10 @@ use crate::{ ir_generation::const_eval::{ compile_constant_expression, compile_constant_expression_to_constant, }, - language::{ty, *}, + language::{ + ty::{self, ProjectionKind}, + *, + }, metadata::MetadataManager, type_system::{LogId, TypeId, TypeInfo}, PartialEqWithTypeEngine, TypeEngine, @@ -1580,7 +1583,7 @@ impl<'te> FnCompiler<'te> { .expect("All local symbols must be in the lexical symbol map."); // First look for a local ptr with the required name - let val = match self.function.get_local_ptr(context, name) { + let mut val = match self.function.get_local_ptr(context, name) { Some(ptr) => { let ptr_ty = *ptr.get_type(context); self.current_block @@ -1614,6 +1617,51 @@ impl<'te> FnCompiler<'te> { .ins(context) .store(val, reassign_val) .add_metadatum(context, span_md_idx); + } else if ast_reassignment + .lhs_indices + .iter() + .any(|f| matches!(f, ProjectionKind::ArrayIndex { .. })) + { + let it = &mut ast_reassignment.lhs_indices.iter().peekable(); + while let Some(ProjectionKind::ArrayIndex { index, .. }) = it.next() { + let index_val = self.compile_expression(context, md_mgr, *index.clone())?; + if index_val.is_diverging(context) { + return Ok(index_val); + } + + let ty = match val.get_stripped_ptr_type(context).unwrap() { + Type::Array(aggregate) => aggregate, + _otherwise => { + let spans = ast_reassignment + .lhs_indices + .iter() + .fold(ast_reassignment.lhs_base_name.span(), |acc, lhs| { + Span::join(acc, lhs.span()) + }); + return Err(CompileError::Internal( + "Array index reassignment to non-array.", + spans, + )); + } + }; + + // When handling nested array indexing, we should keep extracting the first + // elements up until the last, and insert into the last element. + let is_last_index = it.peek().is_none(); + if is_last_index { + val = self + .current_block + .ins(context) + .insert_element(val, ty, reassign_val, index_val) + .add_metadatum(context, span_md_idx); + } else { + val = self + .current_block + .ins(context) + .extract_element(val, ty, index_val) + .add_metadatum(context, span_md_idx); + } + } } else { // An aggregate. Iterate over the field names from the left hand side and collect // field indices. The struct type from the previous iteration is used to determine the diff --git a/sway-core/src/language/ty/expression/expression_variant.rs b/sway-core/src/language/ty/expression/expression_variant.rs index a4d4c43bf16..b74dd03bf49 100644 --- a/sway-core/src/language/ty/expression/expression_variant.rs +++ b/sway-core/src/language/ty/expression/expression_variant.rs @@ -800,6 +800,9 @@ impl DisplayWithTypeEngine for TyExpressionVariant { ProjectionKind::TupleField { index, .. } => { write!(&mut place, "{}", index).unwrap(); } + ProjectionKind::ArrayIndex { index, .. } => { + write!(&mut place, "{:#?}", index).unwrap(); + } } } format!("reassignment to {}", place) diff --git a/sway-core/src/language/ty/expression/reassignment.rs b/sway-core/src/language/ty/expression/reassignment.rs index 1f02c6d7603..fd237b79862 100644 --- a/sway-core/src/language/ty/expression/reassignment.rs +++ b/sway-core/src/language/ty/expression/reassignment.rs @@ -23,7 +23,7 @@ impl PartialEqWithTypeEngine for TyReassignment { fn eq(&self, rhs: &Self, type_engine: &TypeEngine) -> bool { self.lhs_base_name == rhs.lhs_base_name && self.lhs_type == rhs.lhs_type - && self.lhs_indices == rhs.lhs_indices + && self.lhs_indices.eq(&rhs.lhs_indices, type_engine) && self.rhs.eq(&rhs.rhs, type_engine) } } @@ -48,10 +48,52 @@ impl ReplaceDecls for TyReassignment { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug)] pub enum ProjectionKind { - StructField { name: Ident }, - TupleField { index: usize, index_span: Span }, + StructField { + name: Ident, + }, + TupleField { + index: usize, + index_span: Span, + }, + ArrayIndex { + index: Box, + index_span: Span, + }, +} + +impl EqWithTypeEngine for ProjectionKind {} +impl PartialEqWithTypeEngine for ProjectionKind { + fn eq(&self, other: &Self, type_engine: &TypeEngine) -> bool { + match (self, other) { + ( + ProjectionKind::StructField { name: l_name }, + ProjectionKind::StructField { name: r_name }, + ) => l_name == r_name, + ( + ProjectionKind::TupleField { + index: l_index, + index_span: l_index_span, + }, + ProjectionKind::TupleField { + index: r_index, + index_span: r_index_span, + }, + ) => l_index == r_index && l_index_span == r_index_span, + ( + ProjectionKind::ArrayIndex { + index: l_index, + index_span: l_index_span, + }, + ProjectionKind::ArrayIndex { + index: r_index, + index_span: r_index_span, + }, + ) => l_index.eq(r_index, type_engine) && l_index_span == r_index_span, + _ => false, + } + } } impl Spanned for ProjectionKind { @@ -59,6 +101,7 @@ impl Spanned for ProjectionKind { match self { ProjectionKind::StructField { name } => name.span(), ProjectionKind::TupleField { index_span, .. } => index_span.clone(), + ProjectionKind::ArrayIndex { index_span, .. } => index_span.clone(), } } } @@ -68,6 +111,7 @@ impl ProjectionKind { match self { ProjectionKind::StructField { name } => Cow::Borrowed(name.as_str()), ProjectionKind::TupleField { index, .. } => Cow::Owned(index.to_string()), + ProjectionKind::ArrayIndex { index, .. } => Cow::Owned(format!("{:#?}", index)), } } } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index f4713ebe303..24acb1ef42d 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -1683,10 +1683,10 @@ impl ty::TyExpression { let mut warnings = vec![]; let type_engine = ctx.type_engine; - let ctx = ctx + let mut ctx = ctx .with_type_annotation(type_engine.insert_type(TypeInfo::Unknown)) .with_help_text(""); - // ensure that the lhs is a variable expression or struct field access + // ensure that the lhs is a supported expression kind match lhs { ReassignmentTarget::VariableExpression(var) => { let mut expr = var; @@ -1732,6 +1732,20 @@ impl ty::TyExpression { names_vec.push(ty::ProjectionKind::TupleField { index, index_span }); expr = prefix; } + ExpressionKind::ArrayIndex(ArrayIndexExpression { prefix, index }) => { + let ctx = ctx.by_ref().with_help_text(""); + let typed_index = check!( + ty::TyExpression::type_check(ctx, index.as_ref().clone()), + ty::TyExpression::error(span.clone(), type_engine), + warnings, + errors + ); + names_vec.push(ty::ProjectionKind::ArrayIndex { + index: Box::new(typed_index), + index_span: index.span(), + }); + expr = prefix; + } _ => { errors.push(CompileError::InvalidExpressionOnLhs { span }); return err(warnings, errors); diff --git a/sway-core/src/semantic_analysis/namespace/items.rs b/sway-core/src/semantic_analysis/namespace/items.rs index 3df82a7ba79..1738c556d36 100644 --- a/sway-core/src/semantic_analysis/namespace/items.rs +++ b/sway-core/src/semantic_analysis/namespace/items.rs @@ -338,6 +338,15 @@ impl Items { full_name_for_error.push_str(&index.to_string()); full_span_for_error = Span::join(full_span_for_error, index_span.clone()); } + ( + TypeInfo::Array(elem_ty, _count, _), + ty::ProjectionKind::ArrayIndex { index_span, .. }, + ) => { + parent_rover = symbol; + symbol = elem_ty; + symbol_span = index_span.clone(); + full_span_for_error = index_span.clone(); + } (actually, ty::ProjectionKind::StructField { .. }) => { errors.push(CompileError::FieldAccessOnNonStruct { span: full_span_for_error, @@ -353,6 +362,14 @@ impl Items { }); return err(warnings, errors); } + (actually, ty::ProjectionKind::ArrayIndex { .. }) => { + errors.push(CompileError::NotIndexable { + name: full_name_for_error, + span: full_span_for_error, + actually: type_engine.help_out(actually).to_string(), + }); + return err(warnings, errors); + } } } ok((symbol, parent_rover), warnings, errors) diff --git a/sway-error/src/error.rs b/sway-error/src/error.rs index cd56b8f3707..a939a3a7489 100644 --- a/sway-error/src/error.rs +++ b/sway-error/src/error.rs @@ -253,6 +253,12 @@ pub enum CompileError { span: Span, actually: String, }, + #[error("\"{name}\" is a {actually}, which is not an indexable expression.")] + NotIndexable { + name: String, + span: Span, + actually: String, + }, #[error("\"{name}\" is a {actually}, not an enum.")] NotAnEnum { name: String, @@ -750,6 +756,7 @@ impl Spanned for CompileError { ModuleNotFound { span, .. } => span.clone(), NotATuple { span, .. } => span.clone(), NotAStruct { span, .. } => span.clone(), + NotIndexable { span, .. } => span.clone(), FieldAccessOnNonStruct { span, .. } => span.clone(), FieldNotFound { field_name, .. } => field_name.span(), SymbolNotFound { name, .. } => name.span(), diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/Forc.lock new file mode 100644 index 00000000000..4c1e64c3037 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'mutable_arrays' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/Forc.toml new file mode 100644 index 00000000000..fcc1891a08b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/src/main.sw new file mode 100644 index 00000000000..95064daf407 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/src/main.sw @@ -0,0 +1,21 @@ +script; + +fn main() -> bool { + let mut b = false; + b[0] = true; + + let my_array: [u64; 1] = [1]; + my_array[0] = 0; + + takes_ref_mut_arr(my_array); + + let mut my_array_2: [u64; 1] = [1]; + my_array_2[0] = false; + my_array_2[0][1] = false; + + false +} + +fn takes_ref_mut_arr(ref mut arr: [u64; 1]) { + +} diff --git a/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/test.toml b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/test.toml new file mode 100644 index 00000000000..e0a36d4032d --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_fail/mutable_arrays/test.toml @@ -0,0 +1,11 @@ +category = "fail" + +# check: $()"b" is a bool, which is not an indexable expression. + +# check: $()Assignment to immutable variable. Variable my_array is not declared as mutable. + +# check: $()Cannot pass immutable argument to mutable parameter. + +# check: $()Mismatched types. + +# check: $()"my_array_2" is a u64, which is not an indexable expression. diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/Forc.lock new file mode 100644 index 00000000000..4c1e64c3037 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'mutable_arrays' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/Forc.toml new file mode 100644 index 00000000000..bbb3ae34983 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/Forc.toml @@ -0,0 +1,7 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays" +entry = "main.sw" +implicit-std = false + diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/src/main.sw new file mode 100644 index 00000000000..752739111d7 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/src/main.sw @@ -0,0 +1,7 @@ +script; + +fn main() -> u64 { + let mut my_array: [u64; 1] = [1]; + my_array[0] = 10; + my_array[0] +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/test.toml new file mode 100644 index 00000000000..bc08a79dc35 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 10 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/Forc.lock new file mode 100644 index 00000000000..427d522d31b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/Forc.lock @@ -0,0 +1,8 @@ +[[package]] +name = 'core' +source = 'path+from-root-B216E59DF5F0BD4C' + +[[package]] +name = 'mutable_arrays_enum' +source = 'member' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/Forc.toml new file mode 100644 index 00000000000..e13f5edee7e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/Forc.toml @@ -0,0 +1,9 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays_enum" +entry = "main.sw" + + +[dependencies] +core = { path = "../../../../../../../sway-lib-core" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/src/main.sw new file mode 100644 index 00000000000..04ea1c9bec2 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/src/main.sw @@ -0,0 +1,17 @@ +script; + +struct X { + value: u64 +} + +enum Foo { + Bar: X, +} + +fn main() -> u64 { + let mut my_array: [Foo; 1] = [Foo::Bar(X{value: 10})]; + my_array[0] = Foo::Bar(X{value: 20}); + match my_array[0] { + Foo::Bar(x) => x.value, + } +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/test.toml new file mode 100644 index 00000000000..802e5fab8a4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_enum/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 20 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/Forc.lock new file mode 100644 index 00000000000..383f0ad353b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'mutable_arrays_multiple_nested' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/Forc.toml new file mode 100644 index 00000000000..88a25c1bdd3 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays_multiple_nested" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/src/main.sw new file mode 100644 index 00000000000..cdb59201507 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/src/main.sw @@ -0,0 +1,7 @@ +script; + +fn main() -> u64 { + let mut a = [[0,1]]; + a[0][0] = 1; + a[0][0] +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/test.toml new file mode 100644 index 00000000000..bb916e5c72e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_multiple_nested/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 1 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/Forc.lock new file mode 100644 index 00000000000..69264348a01 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'mutable_arrays_nested' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/Forc.toml new file mode 100644 index 00000000000..b49063b01f2 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays_nested" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/src/main.sw new file mode 100644 index 00000000000..5f7b5e7800a --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/src/main.sw @@ -0,0 +1,7 @@ +script; + +fn main() -> u64 { + let mut a = [[0,1]]; + a[0] = [1, 0]; + a[0][0] +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/test.toml new file mode 100644 index 00000000000..bb916e5c72e --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_nested/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 1 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/Forc.lock new file mode 100644 index 00000000000..40a8a1a6525 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'mutable_arrays_struct' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/Forc.toml new file mode 100644 index 00000000000..12d72b26eca --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/Forc.toml @@ -0,0 +1,7 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays_struct" +entry = "main.sw" +implicit-std = false + diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/src/main.sw new file mode 100644 index 00000000000..0c89f522e37 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/src/main.sw @@ -0,0 +1,11 @@ +script; + +struct Foo { + value: u64 +} + +fn main() -> u64 { + let mut my_array: [Foo; 1] = [Foo{value: 10}]; + my_array[0] = Foo{value: 20}; + my_array[0].value +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/test.toml new file mode 100644 index 00000000000..802e5fab8a4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_struct/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 20 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/Forc.lock new file mode 100644 index 00000000000..e6f4c509d47 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'mutable_arrays_swap' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/Forc.toml new file mode 100644 index 00000000000..667b9ee0dc1 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "mutable_arrays_swap" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/src/main.sw new file mode 100644 index 00000000000..58fbe6afc73 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/src/main.sw @@ -0,0 +1,12 @@ +script; + +fn main() -> u64 { + let mut my_array_0: [u64; 1] = [1]; + my_array_0[0] = 10; + + let mut my_array_1: [u64; 1] = [1]; + my_array_1[0] = 20; + + my_array_0[0] = my_array_1[0]; + my_array_0[0] +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/test.toml new file mode 100644 index 00000000000..802e5fab8a4 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/mutable_arrays_swap/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 20 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/Forc.lock new file mode 100644 index 00000000000..156dc26430b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'ref_mutable_arrays' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/Forc.toml new file mode 100644 index 00000000000..6fb53669e6b --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "ref_mutable_arrays" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/src/main.sw new file mode 100644 index 00000000000..5354eaa3ae5 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/src/main.sw @@ -0,0 +1,11 @@ +script; + +fn main() -> u64 { + let mut arr: [u64; 1] = [1]; + takes_ref_mut_array(arr); + arr[0] +} + +fn takes_ref_mut_array(ref mut arr: [u64; 1]) { + arr[0] = 10; +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/test.toml new file mode 100644 index 00000000000..bc08a79dc35 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 10 } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/Forc.lock new file mode 100644 index 00000000000..2391a5c909f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/Forc.lock @@ -0,0 +1,3 @@ +[[package]] +name = 'ref_mutable_arrays_inline' +source = 'member' diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/Forc.toml new file mode 100644 index 00000000000..a23cf48ae2f --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/Forc.toml @@ -0,0 +1,6 @@ +[project] +authors = ["Fuel Labs "] +license = "Apache-2.0" +name = "ref_mutable_arrays_inline" +entry = "main.sw" +implicit-std = false diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/src/main.sw new file mode 100644 index 00000000000..798d5423087 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/src/main.sw @@ -0,0 +1,12 @@ +script; + +fn main() -> u64 { + let mut arr: [u64; 1] = [1]; + takes_ref_mut_array(arr); + arr[0] +} + +#[inline(always)] +fn takes_ref_mut_array(ref mut arr: [u64; 1]) { + arr[0] = 10; +} diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/test.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/test.toml new file mode 100644 index 00000000000..bc08a79dc35 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/ref_mutable_arrays_inline/test.toml @@ -0,0 +1,2 @@ +category = "run" +expected_result = { action = "return", value = 10 }