Skip to content

Commit 3396562

Browse files
authored
Base: bootstrap: eliminate Array-specific length methods (#57627)
Three methods of `length` are deleted. Made possible by moving the following methods to earlier within the bootstrapping: * `size(a::Array)` * `length(t::AbstractArray)` Improves abstract return type inference of `f(x::Array) = length(a)`, presumably because the method count is now low enough for the world-splitting optimization to kick in.
1 parent 7382b7a commit 3396562

File tree

4 files changed

+25
-6
lines changed

4 files changed

+25
-6
lines changed

base/abstractarray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ julia> length([1 2; 3 4])
312312
4
313313
```
314314
"""
315-
length(t::AbstractArray) = (@inline; prod(size(t)))
315+
length(t::AbstractArray)
316316

317317
# `eachindex` is mostly an optimization of `keys`
318318
eachindex(itrs...) = keys(itrs...)

base/array.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ function size(a::Array, d::Int)
191191
sz = getfield(a, :size)
192192
return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
193193
end
194-
size(a::Array) = getfield(a, :size)
195194

196195
asize_from(a::Array, n) = n > ndims(a) ? () : (size(a,n), asize_from(a, n+1)...)
197196

base/essentials.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ const Callable = Union{Function,Type}
77
const Bottom = Union{}
88

99
# Define minimal array interface here to help code used in macros:
10-
length(a::Array{T, 0}) where {T} = 1
11-
length(a::Array{T, 1}) where {T} = getfield(a, :size)[1]
12-
length(a::Array{T, 2}) where {T} = (sz = getfield(a, :size); sz[1] * sz[2])
13-
# other sizes are handled by generic prod definition for AbstractArray
10+
size(a::Array) = getfield(a, :size)
11+
length(t::AbstractArray) = (@inline; prod(size(t)))
1412
length(a::GenericMemory) = getfield(a, :length)
1513
throw_boundserror(A, I) = (@noinline; throw(BoundsError(A, I)))
1614

test/arrayops.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3273,6 +3273,28 @@ end
32733273
"BoundsError: attempt to access 2×2 Matrix{Float64} at index [10, \"bad index\"]"
32743274
end
32753275

3276+
@testset "return type inference of function that calls `length(::Array)`" begin
3277+
f(x) = length(x)
3278+
@test Int === Base.infer_return_type(f, Tuple{Array})
3279+
end
3280+
3281+
@testset "return type inference of `sizeof(::Array)`" begin
3282+
@test isconcretetype(Base.infer_return_type(sizeof, Tuple{Array}))
3283+
end
3284+
3285+
@testset "return type inference of `getindex(::Array, ::Colon)`" begin
3286+
f = a -> a[:]
3287+
@test Vector == Base.infer_return_type(f, Tuple{Array})
3288+
@test Vector{Float32} === Base.infer_return_type(f, Tuple{Array{Float32}})
3289+
end
3290+
3291+
@testset "return type inference of linear `eachindex` for `Array` and `Memory`" begin
3292+
f = a -> eachindex(IndexLinear(), a)
3293+
for typ in (Array, Memory, Union{Array, Memory})
3294+
@test isconcretetype(Base.infer_return_type(f, Tuple{typ}))
3295+
end
3296+
end
3297+
32763298
@testset "inference of Union{T,Nothing} arrays 26771" begin
32773299
f(a) = (v = [1, nothing]; [v[x] for x in a])
32783300
@test only(Base.return_types(f, (Int,))) === Union{Array{Int,0}, Array{Nothing,0}}

0 commit comments

Comments
 (0)