Skip to content

Commit

Permalink
slightly better abstract definition
Browse files Browse the repository at this point in the history
but not reliably inferable for nested structures
  • Loading branch information
mbauman committed Jul 20, 2018
1 parent 8982f12 commit eee1b77
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
9 changes: 8 additions & 1 deletion base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,14 @@ parts can specialize this method to return the concatenation of the `dataids` of
their component parts. A typical definition for an array that wraps a parent is
`Base.dataids(C::CustomArray) = dataids(C.parent)`.
"""
dataids(A::AbstractArray) = (UInt(pointer_from_objref(A)),)
function dataids(A::AbstractArray)
@_inline_meta
ids = _splatmap(dataids, ntuple(i -> getfield(A, i), Val(nfields(A))))
if !isimmutable(A)
ids = (UInt(pointer_from_objref(A)), ids...)
end
return ids
end
dataids(A::Array) = (UInt(pointer(A)),)
dataids(::AbstractRange) = ()
dataids(x) = ()
Expand Down
53 changes: 53 additions & 0 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -902,3 +902,56 @@ end
@test hcat(1:2, fill(1, (2,1))) == hcat([1:2;], fill(1, (2,1))) == reshape([1,2,1,1],2,2)
@test [(1:3) (4:6); fill(1, (3,2))] == reshape([1,2,3,1,1,1,4,5,6,1,1,1], 6,2)
end

# Ensure dataids are inferrable for custom arrays
struct M0 <: AbstractArray{Int,2} end
struct M1{T} <: AbstractArray{Int,2}
x::T
end
struct M2{T,S} <: AbstractArray{Int,2}
x::T
y::S
end
struct M10{A,B,C,D,E,F,G,H,I,J} <: AbstractArray{Int,2}
a::A
b::B
c::C
d::D
e::E
f::F
g::G
h::H
i::I
j::J
end
@testset "dataids" begin
@test @inferred(Base.dataids(M0())) === ()
@test @inferred(Base.dataids(M1(1))) === ()
@test @inferred(Base.dataids(M1(1:10))) === ()
@test @inferred(Base.dataids(M10(1,2,3,4,5,6,7,8,9,0))) === ()

@test @inferred(Base.dataids(M1(M1([1])))) != Base.dataids(M1(M1([1])))
@test @inferred(Base.dataids(M1(M2([1],2)))) != Base.dataids(M1(M2([1],2)))
@test @inferred(Base.dataids(M1(M2([1],[2])))) != Base.dataids(M1(M2([1],[2])))
@test @inferred(Base.dataids(M10([1],[2],[3],[4],[5],[6],[7],[8],[9],[0]))) != Base.dataids(M10([1],[2],[3],[4],[5],[6],[7],[8],[9],[0]))

x = [1]
y = [1]
mx = M1(x)
mxx = M2(x,x)
mxy = M2(x,y)
@test @inferred(Base.mightalias(mx,mx))
@test @inferred(Base.mightalias(mx,mxx))
@test @inferred(Base.mightalias(mx,mxy))
@test @inferred(Base.mightalias(mxx,x))
@test @inferred(Base.mightalias(x,mxy))
@test !@inferred(Base.mightalias(mx, y))
@test !@inferred(Base.mightalias(mxx, y))
@test !@inferred(Base.mightalias(mxx, [1]))
@test !@inferred(Base.mightalias(mxy, 1:10))
@test !@inferred(Base.mightalias(mxy, M0()))
@test !@inferred(Base.mightalias(mxy, [1]))
@test !@inferred(Base.mightalias(mxy, M1(1:10)))
@test !@inferred(Base.mightalias(mxy, M1([1])))
end

0 comments on commit eee1b77

Please sign in to comment.