Skip to content

Commit 6bd6f52

Browse files
authored
Make fallback similar methods less specific in axes (#1176)
* Make fallback similar methods less specific in axes * Add 4 term test * Fix test
1 parent 89813ee commit 6bd6f52

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

src/abstractarray.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,8 @@ similar(::Type{A},::Type{T},s::Size{S}) where {A<:Array,T,S} = sizedarray_simila
139139
# by simply converting them to either a tuple of Ints or a Size, re-dispatching to either one
140140
# of the above methods (in the case of Size) or a base fallback (in the case of Ints).
141141
const HeterogeneousBaseShape = Union{Integer, Base.OneTo}
142-
const HeterogeneousShape = Union{Integer, Base.OneTo, SOneTo}
143-
const HeterogeneousShapeTuple = Union{
144-
Tuple{SOneTo, Vararg{HeterogeneousShape}},
145-
Tuple{HeterogeneousBaseShape, SOneTo, Vararg{HeterogeneousShape}},
146-
Tuple{HeterogeneousBaseShape, HeterogeneousBaseShape, SOneTo, Vararg{HeterogeneousShape}}
147-
}
142+
const HeterogeneousShape = Union{HeterogeneousBaseShape, SOneTo}
143+
const HeterogeneousShapeTuple = Tuple{Vararg{HeterogeneousShape}}
148144

149145
similar(A::AbstractArray, ::Type{T}, shape::HeterogeneousShapeTuple) where {T} = similar(A, T, homogenize_shape(shape))
150146
similar(::Type{A}, shape::HeterogeneousShapeTuple) where {A<:AbstractArray} = similar(A, homogenize_shape(shape))

test/abstractarray.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,38 @@ using StaticArrays, Test, LinearAlgebra
8080
@test isa(@inferred(similar(Diagonal{Int}, Size(2,2))), MArray{Tuple{2, 2}, Int, 2, 4})
8181
@test isa(@inferred(similar(SizedArray, Int, Size(2,2))), SizedArray{Tuple{2, 2}, Int, 2, 2})
8282
@test isa(@inferred(similar(Matrix{Int}, Int, Size(2,2))), SizedArray{Tuple{2, 2}, Int, 2, 2})
83+
84+
@testset "disambiguate similar" begin
85+
struct CustomArray{T} <: AbstractVector{T}
86+
sz :: Int
87+
end
88+
89+
Base.size(C::CustomArray) = (C.sz,)
90+
Base.getindex(C::CustomArray{T}, i::Int) where {T} = T(i)
91+
Base.similar(C::CustomArray, ::Type{T}, ax::Tuple{Vararg{Int}}) where {T} =
92+
Array{T}(undef, ax)
93+
function Base.similar(C::CustomArray, ::Type{T}, ax::Tuple{Vararg{Union{Int, SOneTo, Base.OneTo{Int}}}}) where {T}
94+
sz = last.(ax)
95+
Array{T}(undef, sz)
96+
end
97+
98+
c = CustomArray{Int}(4)
99+
for (ax, sz) in (((SOneTo(2), Base.OneTo(3)), (2,3)),
100+
((2, SOneTo(2), Base.OneTo(3)), (2,2,3)))
101+
for A in (similar(c, Float64, ax), similar(c, Float64, ax...))
102+
@test A isa Array{Float64, length(sz)}
103+
@test size(A) == sz
104+
end
105+
end
106+
107+
@test similar(c, ()) isa Array{Int,0}
108+
@test similar(c, Float64, ()) isa Array{Float64,0}
109+
110+
@test size(similar(zeros(), (1,1,1,SOneTo(1)))) == (1,1,1,1)
111+
112+
# ensure that the more specific Base method works
113+
@test similar(1:2, ()) isa AbstractArray{Int,0}
114+
end
83115
end
84116

85117
@testset "similar and Base.Slice/IdentityUnitRange (issues #548, #556)" begin

0 commit comments

Comments
 (0)