Skip to content
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

Broadcasting breakage for non-1 indices #20569

Closed
timholy opened this issue Feb 11, 2017 · 5 comments
Closed

Broadcasting breakage for non-1 indices #20569

timholy opened this issue Feb 11, 2017 · 5 comments
Labels
regression Regression in behavior compared to a previous version types and dispatch Types, subtyping and method dispatch

Comments

@timholy
Copy link
Member

timholy commented Feb 11, 2017

julia> using OffsetArrays

julia> a = OffsetArray(1:3, -1:1)
OffsetArrays.OffsetArray{Int64,1,UnitRange{Int64}} with indices -1:1:
 1
 2
 3

julia> Float64.(a)
ERROR: MethodError: Cannot `convert` an object of type Tuple{UnitRange{Int64}} to an object of type Array{Float64,N} where N
This may have arisen from a call to the constructor Array{Float64,N} where N(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] Array{Float64,N} where N(::Tuple{UnitRange{Int64}}) at ./sysimg.jl:24
 [2] similar(::Type{T} where T, ::Tuple{UnitRange{Int64}}) at ./abstractarray.jl:508
 [3] broadcast_t(::Type{T} where T, ::Type{T} where T, ::Tuple{UnitRange{Int64}}, ::CartesianRange{CartesianIndex{1}}, ::OffsetArrays.OffsetArray{Int64,1,UnitRange{Int64}}) at ./broadcast.jl:265
 [4] broadcast_c(::Type{T} where T, ::Type{Array}, ::OffsetArrays.OffsetArray{Int64,1,UnitRange{Int64}}) at ./broadcast.jl:293
 [5] broadcast(::Type{T} where T, ::OffsetArrays.OffsetArray{Int64,1,UnitRange{Int64}}) at ./broadcast.jl:406
 [6] eval(::Module, ::Any) at ./boot.jl:235

Works in Julia 0.5.

AFAICT broken in #18642, d16d994. CC @pabloferz.

@timholy timholy added the regression Regression in behavior compared to a previous version label Feb 11, 2017
@pabloferz
Copy link
Contributor

pabloferz commented Feb 11, 2017

Hi Tim, this is a problem with similar as much as it is a problem with broadcast.

On master similar(Array{Float64}, (-1:1,)) gives the error above, but on 0.5 it calls similar(f::Union{DataType,Function}, shape::Tuple{UnitRange,Vararg{UnitRange,N<:Any}}) form OffsetArrays which returns an OffsetArray.

I'm not sure if this has to be fixed in master or in OffsetArrays, though.

@timholy
Copy link
Member Author

timholy commented Feb 11, 2017

That's interesting. For reference, the Base method is

similar(f, shape::Tuple) = f(to_shape(shape))

and the one in OffsetArrays is

Base.similar{T}(f::Union{Function,DataType}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(f(map(length, shape)), map(indexoffset, shape))

To me it seems the one in OffsetArrays is unambiguously more specific. So why isn't it called?

I'm going to classify this as a type system bug.

@timholy timholy added the types and dispatch Types, subtyping and method dispatch label Feb 11, 2017
@timholy
Copy link
Member Author

timholy commented Feb 11, 2017

I can confirm that splitting the Union fixes the problem:

Base.similar{T}(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) = _similar(T, shape)
Base.similar(f::Function, shape::Tuple{UnitRange,Vararg{UnitRange}}) = _similar(f, shape)
_similar(f, shape) = OffsetArray(f(map(length, shape)), map(indexoffset, shape))

@pabloferz
Copy link
Contributor

The problem is that Array{Float64} is now a UnionAll (Array{Float64,N} where N) which is not a subtype of DataType. This could be fixed in OffsetArrays by changing the signature to ::Union{Function,Type}.

@pabloferz
Copy link
Contributor

See JuliaArrays/OffsetArrays.jl#20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
regression Regression in behavior compared to a previous version types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

2 participants