From 0fc31bc2fa875e9120aa32ec0a4c35b6383d7516 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Thu, 28 May 2026 17:22:05 -0300 Subject: [PATCH 1/2] Fix ICE when reading an indexed ref mut array element A `ref mut` array argument is a pointer in IR, and storing it into a local adds another level of indirection, so the index-read path saw a pointer to a pointer to the array and aborted with `todo!()`. Peel the extra pointer levels before indexing, matching how the reassignment path already dereferences `ref mut` arguments. Closes #7602 --- sway-core/src/ir_generation/function.rs | 35 +++++++++++++++---- .../src/main.sw | 3 +- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index 79cd8c73610..b3158893fde 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -5276,12 +5276,32 @@ impl<'a> FnCompiler<'a> { index_expr: &ty::TyExpression, span_md_idx: Option, ) -> Result { - let prefix_value = return_on_termination_or_extract!(self.compile_expression_to_memory( - context, - md_mgr, - prefix_expr - )?) + let mut prefix_value = return_on_termination_or_extract!(self + .compile_expression_to_memory(context, md_mgr, prefix_expr)?) .expect_memory(); + + // When the prefix is a reference (e.g. a `ref mut self` argument), the compiled value + // is a pointer to the reference, i.e. a pointer to a pointer to the indexed aggregate. + // We need to dereference it, peeling off the extra levels of indirection, until we + // reach the pointer that actually points to the array or slice. + while let Some(TypeContent::TypedPointer(pointee)) = prefix_value + .get_type(context) + .map(|ty| ty.get_content(context)) + { + if matches!( + pointee.get_content(context), + TypeContent::TypedPointer(_) | TypeContent::Pointer + ) { + prefix_value = self + .current_block + .append(context) + .load(prefix_value) + .add_metadatum(context, span_md_idx); + } else { + break; + } + } + let prefix_type = prefix_value.get_type(context).unwrap(); let index_value = return_on_termination_or_extract!( @@ -5300,7 +5320,10 @@ impl<'a> FnCompiler<'a> { prefix_value, index_value, ), - _ => todo!(), + _ => Err(CompileError::Internal( + "Unsupported array value for index expression.", + prefix_expr.span.clone(), + )), }, TypeContent::TypedSlice(..) => self.compile_indexing_slices( context, diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics_array_in_reassignments/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics_array_in_reassignments/src/main.sw index 3fa52bbd21e..c109d295b8b 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics_array_in_reassignments/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/const_generics_array_in_reassignments/src/main.sw @@ -33,8 +33,7 @@ where let mut i = 0; while i < N { self[i] = default; - // TODO: Uncomment this `assert_eq` once https://github.com/FuelLabs/sway/issues/7602 is fixed. - // assert_eq(self[i], default); + assert_eq(self[i], default); i += 1; } } From b7bcec18e59da71847e29f1837b2037cfe815db6 Mon Sep 17 00:00:00 2001 From: Dnreikronos Date: Mon, 1 Jun 2026 19:16:10 -0300 Subject: [PATCH 2/2] Apply rustfmt formatting to compile_indexing --- sway-core/src/ir_generation/function.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sway-core/src/ir_generation/function.rs b/sway-core/src/ir_generation/function.rs index b3158893fde..830f3dd46cd 100644 --- a/sway-core/src/ir_generation/function.rs +++ b/sway-core/src/ir_generation/function.rs @@ -5276,8 +5276,9 @@ impl<'a> FnCompiler<'a> { index_expr: &ty::TyExpression, span_md_idx: Option, ) -> Result { - let mut prefix_value = return_on_termination_or_extract!(self - .compile_expression_to_memory(context, md_mgr, prefix_expr)?) + let mut prefix_value = return_on_termination_or_extract!( + self.compile_expression_to_memory(context, md_mgr, prefix_expr)? + ) .expect_memory(); // When the prefix is a reference (e.g. a `ref mut self` argument), the compiled value