From b02d0c6ac52d98615a850c0b24e3f10a3c4317e4 Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Wed, 27 Aug 2025 14:19:45 +0200 Subject: [PATCH 1/2] `eachindex` for linear indexing for `Array` and `Memory`: typeassert The method return type is known concretely as `OneTo{Int}`, however the compiler can't tell because there are too many methods matching `length(::Array)`, over the world-splitting threshold, `max_methods`. Cross-reference WIP PR #57627, which might help here in another way by decreasing the number of unnecessary methods, however merging that PR would also cause regressions if world-splitting is not disabled first for `length` (xref WIP PR #59377). Fix that by asserting the return type of the `length` call as `Int`. The `typeassert` should improve abstract return type inference, and consequently make the sysimage more resistant to invalidation. --- base/abstractarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 3773502f0cd26..fd615a535cb80 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -387,7 +387,7 @@ function eachindex(A::AbstractArray, B::AbstractArray...) @inline eachindex(IndexStyle(A,B...), A, B...) end -eachindex(::IndexLinear, A::Union{Array, Memory}) = unchecked_oneto(length(A)) +eachindex(::IndexLinear, A::Union{Array, Memory}) = unchecked_oneto(length(A)::Int) eachindex(::IndexLinear, A::AbstractArray) = (@inline; oneto(length(A))) eachindex(::IndexLinear, A::AbstractVector) = (@inline; axes1(A)) function eachindex(::IndexLinear, A::AbstractArray, B::AbstractArray...) From a5494486d6c1aceacc2383a6c64564abd19f8514 Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Wed, 27 Aug 2025 15:24:06 +0200 Subject: [PATCH 2/2] add return type inference test --- test/arrayops.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/arrayops.jl b/test/arrayops.jl index f9c592e672973..007dc87fd5a8d 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -2654,6 +2654,13 @@ let A = zeros(Int, 2, 2), B = zeros(Float64, 2, 2) end end +@testset "return type inference of linear `eachindex` for `Array` and `Memory`" begin + f = a -> eachindex(IndexLinear(), a) + for typ in (Array, Memory, Union{Array, Memory}) + @test isconcretetype(Base.infer_return_type(f, Tuple{typ})) + end +end + # issue #14482 @inferred map(Int8, Int[0])