Skip to content

Commit 059ae4d

Browse files
Fix recursivefill! failure with immutable StaticArrays (issue #461)
This commit fixes a bug where `recursivefill!` would fail when called on a `VectorOfArray` containing immutable `StaticArray` types like `SVector`. ## Problem The `Base.fill!` method for `AbstractVectorOfArray` attempted to call `fill!` on each element array, which fails for immutable arrays that don't support in-place modification via `setindex!`. ## Solution Modified `Base.fill!` to check if each element is mutable before attempting to fill it. For immutable arrays, we now create a new filled array using `StaticArraysCore.similar_type` and assign it, following the same pattern used in the existing `copyto!` implementation. ## Changes - Updated `Base.fill!` in `src/vector_of_array.jl` to handle both mutable and immutable arrays correctly - Added comprehensive tests in `test/utils_test.jl` to cover: - `VectorOfArray` with only immutable `SVector`s - `VectorOfArray` with mixed immutable and mutable `StaticArray`s - Both `recursivefill!` and `fill!` methods All existing tests continue to pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 711daaf commit 059ae4d

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/vector_of_array.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,12 @@ end
826826
function Base.fill!(VA::AbstractVectorOfArray, x)
827827
for i in 1:length(VA.u)
828828
if VA[:, i] isa AbstractArray
829-
fill!(VA[:, i], x)
829+
if ArrayInterface.ismutable(VA.u[i]) || VA.u[i] isa AbstractVectorOfArray
830+
fill!(VA[:, i], x)
831+
else
832+
# For immutable arrays like SVector, create a new filled array
833+
VA.u[i] = fill(x, StaticArraysCore.similar_type(VA.u[i]))
834+
end
830835
else
831836
VA[:, i] = x
832837
end

test/utils_test.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,35 @@ end
139139
@test u1.u[2] isa SVector
140140
end
141141

142+
# Test recursivefill! with immutable StaticArrays (issue #461)
143+
@testset "recursivefill! with immutable StaticArrays (issue #461)" begin
144+
# Test with only immutable SVectors
145+
x = VectorOfArray([SVector{2}(ones(2)), SVector{2}(ones(2))])
146+
recursivefill!(x, 0.0)
147+
@test all(x.u[i] == SVector{2}(zeros(2)) for i in 1:2)
148+
@test all(x.u[i] isa SVector for i in 1:2)
149+
150+
# Test with mixed immutable and mutable StaticArrays
151+
x = VectorOfArray([SVector{2}(ones(2)), MVector{2}(ones(2))])
152+
recursivefill!(x, 0.0)
153+
@test all(x.u[i] == [0.0, 0.0] for i in 1:2)
154+
@test x.u[1] isa SVector
155+
@test x.u[2] isa MVector
156+
157+
# Test fill! on VectorOfArray with immutable SVectors
158+
x = VectorOfArray([SVector{2}(ones(2)), SVector{2}(ones(2))])
159+
fill!(x, 0.0)
160+
@test all(x.u[i] == SVector{2}(zeros(2)) for i in 1:2)
161+
@test all(x.u[i] isa SVector for i in 1:2)
162+
163+
# Test fill! on VectorOfArray with mixed types
164+
x = VectorOfArray([SVector{2}(ones(2)), MVector{2}(ones(2))])
165+
fill!(x, 0.0)
166+
@test all(x.u[i] == [0.0, 0.0] for i in 1:2)
167+
@test x.u[1] isa SVector
168+
@test x.u[2] isa MVector
169+
end
170+
142171
import KernelAbstractions: get_backend
143172
@testset "KernelAbstractions" begin
144173
v = VectorOfArray([randn(2) for i in 1:10])

0 commit comments

Comments
 (0)