-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed the bug referenced in #43551 and added tests #43646
Conversation
…itarray promotion
Wait, are we sure we actually want this? |
I mean we already promote 'native' Bool-Arrays to Int-Arrays: julia> promote([false,true],[1.3, 2.6])
([0.0, 1.0], [1.3, 2.6]) So why not BitArrays? |
Because promotion, as it is now, is intended to make an object of a "lesser" type A into an object of a "larger" type B - in the sense that values of type A can always be represented in type B, but not necessarily vice versa. (this is not entirely true - most The problem here is that |
Since
I'm also not sure what to do if both eltypes are |
How about something like: function promote_rule(::Type{BitArray{N}},::Type{Array{T,N}}) where {T,N}
typejoin(Bool,T) == Any && return promote_rule(Bool,T)
Array{T,N}
end Im not sure the It still works for our intended use-cases: julia> promote(BitArray([false,true]),[1.3,2.6])
([0.0, 1.0], [1.3, 2.6])
julia> typeof(ans)
Tuple{Vector{Float64}, Vector{Float64}} And correctly throws an error when used 'incorrectly': julia> promote(BitArray([false,true]),[[1.3,2.6]])
ERROR: promotion of types BitVector and Vector{Vector{Float64}} failed to change any arguments
Stacktrace:
[...]
julia> promote(BitArray([false,true]),["test"])
ERROR: promotion of types BitVector and Vector{String} failed to change any arguments
Stacktrace:
[...] Which is identical to the established behavior for normal julia> promote([false,true],[[1.3,2.6]])
ERROR: promotion of types Vector{Bool} and Vector{Vector{Float64}} failed to change any arguments
Stacktrace:
[...]
julia> promote([false,true],["test"])
ERROR: promotion of types Vector{Bool} and Vector{String} failed to change any arguments
Stacktrace:
[...] |
typejoin(Bool,T) == Any && return promote_rule(Bool,T) | ||
Array{T,N} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typejoin(Bool,T) == Any && return promote_rule(Bool,T) | |
Array{T,N} | |
return Array{promote_type(Bool, T), N} |
function promote_rule(::Type{BitArray{N}},::Type{Array{T,N}}) where {T,N} | ||
typejoin(Bool,T) == Any && return promote_rule(Bool,T) | ||
Array{T,N} | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function promote_rule(::Type{BitArray{N}},::Type{Array{T,N}}) where {T,N} | |
typejoin(Bool,T) == Any && return promote_rule(Bool,T) | |
Array{T,N} | |
end | |
function promote_rule(a::Type{BitArray{N}}, b::Type{Array{T, N}}) where {T, N} | |
return el_same(promote_type(Bool, T), a, b) | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But perhaps a better option is relax the existing method:
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
to accepting ::Type{<:AbstractArray{S,n}}
for a
and b
EDIT: and if so, need to protect against:
julia> promote([false,true],BitArray(undef,2))
ERROR: StackOverflowError:
Stacktrace:
[1] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{Vector{Bool}}, #unused#::Type{BitVector})
@ Base ./promotion.jl:308
[2] promote_type(#unused#::Type{Vector{Bool}}, #unused#::Type{BitVector})
@ Base ./promotion.jl:294
--- the last 2 lines are repeated 39990 more times ---
[79983] promote_result(#unused#::Type, #unused#::Type, #unused#::Type{Vector{Bool}}, #unused#::Type{BitVector})
@ Base ./promotion.jl:308
By fixing the definition of el_same
:
$ git diff -U0 base/range.jl
diff --git a/base/range.jl b/base/range.jl
index 5c777c57fa..b4d87ec927 100644
--- a/base/range.jl
+++ b/base/range.jl
@@ -1259 +1259 @@ end
-el_same(::Type{T}, a::Type{<:AbstractArray{T,n}}, b::Type{<:AbstractArray{T,n}}) where {T,n} = a
+el_same(::Type{T}, a::Type{<:AbstractArray{T,n}}, b::Type{<:AbstractArray{T,n}}) where {T,n} = a === b ? a : Array{T,n}
Added a
proute_rule
for Bitarrays and added tests for it