Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ julia> length([1 2; 3 4])
4
```
"""
length(t::AbstractArray) = (@inline; prod(size(t)))
length(t::AbstractArray)

# `eachindex` is mostly an optimization of `keys`
eachindex(itrs...) = keys(itrs...)
Expand Down
1 change: 0 additions & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ function size(a::Array, d::Int)
sz = getfield(a, :size)
return d > length(sz) ? 1 : getfield(sz, d, false) # @inbounds
end
size(a::Array) = getfield(a, :size)

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

Expand Down
6 changes: 2 additions & 4 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ const Callable = Union{Function,Type}
const Bottom = Union{}

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

Expand Down
22 changes: 22 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3273,6 +3273,28 @@ end
"BoundsError: attempt to access 2×2 Matrix{Float64} at index [10, \"bad index\"]"
end

@testset "return type inference of function that calls `length(::Array)`" begin
f(x) = length(x)
@test Int === Base.infer_return_type(f, Tuple{Array})
end

@testset "return type inference of `sizeof(::Array)`" begin
@test isconcretetype(Base.infer_return_type(sizeof, Tuple{Array}))
end

@testset "return type inference of `getindex(::Array, ::Colon)`" begin
f = a -> a[:]
@test Vector == Base.infer_return_type(f, Tuple{Array})
@test Vector{Float32} === Base.infer_return_type(f, Tuple{Array{Float32}})
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

@testset "inference of Union{T,Nothing} arrays 26771" begin
f(a) = (v = [1, nothing]; [v[x] for x in a])
@test only(Base.return_types(f, (Int,))) === Union{Array{Int,0}, Array{Nothing,0}}
Expand Down
Loading