Skip to content

Array.insertManyAt returns original array for empty insertion #18352

Description

@albert-du

When calling Array.insertManyAt, if the values inserted are empty, the source array is always returned, rather than a copy.

Documented behavior is "Return a new array with new items inserted before the given index." however returning the original source can create unexpected side effects when the values being inserted are empty.

Consider:

letoriginal=[|1;2;3|]letnewArr= Array.insertManyAt 3[|4;5|] original
printfn $"%b{original = newArr}"// false
printfn $"%A{original}"
printfn $"%A{newArr}"// [|1; 2; 3|]// [|1; 2; 3; 4; 5|]// do some weird things to newArr
newArr[0]<-987654321
printfn $"%A{original}"
printfn $"%A{newArr}"// [|1; 2; 3|]// [|987654321; 2; 3; 4; 5|]// original is unaffected

sharplab

and when the values inserted are empty

letoriginal=[|1;2;3|]// insert empty arrayletnewArr= Array.insertManyAt 3[||] original
printfn $"%b{original = newArr}"// true (that's strange)
printfn $"%A{original}"
printfn $"%A{newArr}"// [|1; 2; 3|]// [|1; 2; 3|]// do some weird things to newArr
newArr[0]<-987654321
printfn $"%A{original}"
printfn $"%A{newArr}"// [|987654321; 2; 3|]// [|987654321; 2; 3|]// original has been affected by a mutation on the 'new' array

sharplab

Expected behavior

Always create a new array.

Actual behavior

When the inserted values are empty, the original array, rather than a copy, is returned.

Known workarounds

Preemptively copy the source array, or copy the returned value.

Related information

I believe the cause is

if valuesArray.Length =0then
source
else

Fix would be adding a call to Array.copy in this branch.

This does not affect Seq.insertManyAt and List.insertManyAt as seq and list immutable.

Provide any related information (optional):

.NET / FSharp.Core 9.0

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions