Skip to content

Commit

Permalink
Remove tricky array/broadcasting/indexing deprecations (JuliaLang#28458)
Browse files Browse the repository at this point in the history
* Remove scalar .= deprecation

* Remove to_index(::Bool) deprecation

* broadcasting now falls back to iteration (fixes JuliaLang#23197, fixes JuliaLang#23746)
  • Loading branch information
mbauman authored and alyst committed Aug 9, 2018
1 parent 92dc908 commit 9b01d1a
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 84 deletions.
6 changes: 3 additions & 3 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,9 @@ broadcastable(x::Union{Symbol,AbstractString,Function,UndefInitializer,Nothing,R
broadcastable(x::Ptr) = Ref{Ptr}(x) # Cannot use Ref(::Ptr) until ambiguous deprecation goes through
broadcastable(::Type{T}) where {T} = Ref{Type{T}}(T)
broadcastable(x::Union{AbstractArray,Number,Ref,Tuple,Broadcasted}) = x
# In the future, default to collecting arguments. TODO: uncomment once deprecations are removed
# broadcastable(x) = collect(x)
# broadcastable(::Union{AbstractDict, NamedTuple}) = error("intentionally unimplemented to allow development in 1.x")
# Default to collecting iterables — which will error for non-iterables
broadcastable(x) = collect(x)
broadcastable(::Union{AbstractDict, NamedTuple}) = throw(ArgumentError("broadcasting over dictionaries and `NamedTuple`s is reserved"))

## Computation of inferred result type, for empty and concretely inferred cases only
_broadcast_getindex_eltype(bc::Broadcasted) = Base._return_type(bc.f, eltypes(bc.args))
Expand Down
58 changes: 0 additions & 58 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -575,33 +575,6 @@ function toc()
return t
end

# A[I...] .= with scalar indices should modify the element at A[I...]
function Broadcast.dotview(A::AbstractArray, args::Number...)
depwarn("the behavior of `A[I...] .= X` with scalar indices will change in the future. Use `A[I...] = X` instead.", :broadcast!)
view(A, args...)
end
Broadcast.dotview(A::AbstractArray{<:AbstractArray}, args::Integer...) = getindex(A, args...)
# Upon removing deprecations, also enable the @testset "scalar .=" in test/broadcast.jl

# indexing with A[true] will throw an argument error in the future
function to_index(i::Bool)
depwarn("indexing with Bool values is deprecated. Convert the index to an integer first with `Int(i)`.", (:getindex, :setindex!, :view))
convert(Int,i)::Int
end
# After deprecation is removed, enable the @testset "indexing by Bool values" in test/arrayops.jl
# Also un-comment the new definition in base/indices.jl

# Broadcast no longer defaults to treating its arguments as scalar (#)
@noinline function Broadcast.broadcastable(x)
depwarn("""
broadcast will default to iterating over its arguments in the future. Wrap arguments of
type `x::$(typeof(x))` with `Ref(x)` to ensure they broadcast as "scalar" elements.
""", (:broadcast, :broadcast!))
return Ref{typeof(x)}(x)
end
@eval Base.Broadcast Base.@deprecate_binding Scalar DefaultArrayStyle{0} false
# After deprecation is removed, enable the fallback broadcastable definitions in base/broadcast.jl

# deprecate BitArray{...}(shape...) constructors to BitArray{...}(undef, shape...) equivalents
@deprecate BitArray{N}(dims::Vararg{Int,N}) where {N} BitArray{N}(undef, dims)
@deprecate BitArray(dims::NTuple{N,Int}) where {N} BitArray(undef, dims...)
Expand Down Expand Up @@ -1376,28 +1349,6 @@ function slicedim(A::AbstractVector, d::Integer, i::Number)
end
end

# PR #26347: Deprecate implicit scalar broadcasting in setindex!
_axes(::Ref) = ()
_axes(x) = axes(x)
setindex_shape_check(X::Base.Iterators.Repeated, I...) = nothing
function deprecate_scalar_setindex_broadcast_message(v, I...)
value = (_axes(Base.Broadcast.broadcastable(v)) == () ? "x" : "(x,)")
"using `A[I...] = x` to implicitly broadcast `x` across many locations is deprecated. Use `A[I...] .= $value` instead."
end
deprecate_scalar_setindex_broadcast_message(v, ::Colon, ::Vararg{Colon}) =
"using `A[:] = x` to implicitly broadcast `x` across many locations is deprecated. Use `fill!(A, x)` instead."

function _iterable(v, I...)
depwarn(deprecate_scalar_setindex_broadcast_message(v, I...), :setindex!)
Iterators.repeated(v)
end
function setindex!(B::BitArray, x, I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...)
depwarn(deprecate_scalar_setindex_broadcast_message(x, I0, I...), :setindex!)
B[I0, I...] .= (x,)
B
end


# PR #26283
@deprecate contains(haystack, needle) occursin(needle, haystack)
@deprecate contains(s::AbstractString, r::Regex, offset::Integer) occursin(r, s, offset=offset)
Expand Down Expand Up @@ -1493,15 +1444,6 @@ end
depwarn("using similar(f, shape...) to call `f` with axes `shape` is deprecated; call `f` directly and/or add methods such that it supports axes", :similar)
f(to_shape(dims))
end
# Deprecate non-integer/axis arguments to zeros/ones to match fill/trues/falses
@deprecate zeros(::Type{T}, dims...) where {T} zeros(T, convert(Dims, dims)...)
@deprecate zeros(dims...) zeros(convert(Dims, dims)...)
@deprecate zeros(::Type{T}, dims::NTuple{N, Any}) where {T, N} zeros(T, convert(Dims, dims))
@deprecate zeros(dims::Tuple) zeros(convert(Dims, dims))
@deprecate ones(::Type{T}, dims...) where {T} ones(T, convert(Dims, dims)...)
@deprecate ones(dims...) ones(convert(Dims, dims)...)
@deprecate ones(::Type{T}, dims::NTuple{N, Any}) where {T, N} ones(T, convert(Dims, dims))
@deprecate ones(dims::Tuple) ones(convert(Dims, dims))

# Deprecate varargs size: PR #26862
@deprecate size(x, d1::Integer, d2::Integer) (size(x, d1), size(x, d2))
Expand Down
3 changes: 1 addition & 2 deletions base/indices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,7 @@ indexing behaviors. This must return either an `Int` or an `AbstractArray` of
`Int`s.
"""
to_index(i::Integer) = convert(Int,i)::Int
# TODO: Enable this new definition after the deprecations introduced in 0.7 are removed
# to_index(i::Bool) = throw(ArgumentError("invalid index: $i of type $(typeof(i))"))
to_index(i::Bool) = throw(ArgumentError("invalid index: $i of type $(typeof(i))"))
to_index(I::AbstractArray{Bool}) = LogicalIndex(I)
to_index(I::AbstractArray) = I
to_index(I::AbstractArray{<:Union{AbstractArray, Colon}}) =
Expand Down
3 changes: 1 addition & 2 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -632,11 +632,10 @@ function _setindex!(l::IndexStyle, A::AbstractArray, x, I::Union{Real, AbstractA
A
end

_iterable(X::AbstractArray, I...) = X
@generated function _unsafe_setindex!(::IndexStyle, A::AbstractArray, x, I::Union{Real,AbstractArray}...)
N = length(I)
quote
x′ = unalias(A, _iterable(x, I...))
x′ = unalias(A, x)
@nexprs $N d->(I_d = unalias(A, I[d]))
idxlens = @ncall $N index_lengths I
@ncall $N setindex_shape_check x′ (d->idxlens[d])
Expand Down
6 changes: 6 additions & 0 deletions stdlib/LinearAlgebra/test/uniformscaling.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,10 @@ end
@test (I - LL')\[[0], [0], [1]] == (I - LL)'\[[0], [0], [1]] == fill([1], 3)
end

# Ensure broadcasting of I is an error (could be made to work in the future)
@testset "broadcasting of I (#23197)" begin
@test_throws MethodError I .+ 1
@test_throws MethodError I .+ [1 1; 1 1]
end

end # module TestUniformscaling
12 changes: 6 additions & 6 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2388,7 +2388,8 @@ end
test_zeros(zeros(Int, (2, 3)), Matrix{Int}, (2,3))

# #19265"
@test_throws Any zeros(Float64, [1.]) # TODO: Tighten back up to MethodError once 0.7 deprecations are removed
@test_throws MethodError zeros(Float64, [1.])
@test_throws MethodError ones(Float64, [0, 0])
end

# issue #11053
Expand Down Expand Up @@ -2431,11 +2432,10 @@ end
@test_throws BoundsError checkbounds(zeros(2,3,0), 2, 3)
end

# TODO: Enable this testset after the deprecations introduced in 0.7 are removed
# @testset "indexing by Bool values" begin
# @test_throws ArgumentError zeros(2)[false]
# @test_throws ArgumentError zeros(2)[true]
# end
@testset "indexing by Bool values" begin
@test_throws ArgumentError zeros(Float64, 2)[false]
@test_throws ArgumentError zeros(Float64, 2)[true]
end

@testset "issue 24707" begin
@test eltype(Vector{Tuple{V}} where V<:Integer) >: Tuple{Integer}
Expand Down
35 changes: 23 additions & 12 deletions test/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,18 @@ end
@test broadcast(==, 1, AbstractArray) == false
end

@testset "broadcasting falls back to iteration (issues #26421, #19577, #23746)" begin
@test_throws ArgumentError broadcast(identity, Dict(1=>2))
@test_throws ArgumentError broadcast(identity, (a=1, b=2))
@test_throws ArgumentError length.(Dict(1 => BitSet(1:2), 2 => BitSet(1:3)))
@test_throws MethodError broadcast(identity, Base)

@test broadcast(identity, Iterators.filter(iseven, 1:10)) == 2:2:10
d = Dict([1,2] => 1.1, [3,2] => 0.1)
@test length.(keys(d)) == [2,2]
@test Set(exp.(Set([1,2,3]))) == Set(exp.([1,2,3]))
end

# Test that broadcasting identity where the input and output Array shapes do not match
# yields the correct result, not merely a partial copy. See pull request #19895 for discussion.
let N = 5
Expand Down Expand Up @@ -651,18 +663,17 @@ end
@test_throws DimensionMismatch (1, 2) .+ (1, 2, 3)
end

# TODO: Enable after deprecations introduced in 0.7 are removed.
# @testset "scalar .=" begin
# A = [[1,2,3],4:5,6]
# A[1] .= 0
# @test A[1] == [0,0,0]
# @test_throws ErrorException A[2] .= 0
# @test_throws MethodError A[3] .= 0
# A = [[1,2,3],4:5]
# A[1] .= 0
# @test A[1] == [0,0,0]
# @test_throws ErrorException A[2] .= 0
# end
@testset "scalar .=" begin
A = [[1,2,3],4:5,6]
A[1] .= 0
@test A[1] == [0,0,0]
@test_throws ErrorException A[2] .= 0
@test_throws MethodError A[3] .= 0
A = [[1,2,3],4:5]
A[1] .= 0
@test A[1] == [0,0,0]
@test_throws ErrorException A[2] .= 0
end

# Issue #22180
@test convert.(Any, [1, 2]) == [1, 2]
Expand Down
2 changes: 1 addition & 1 deletion test/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ f5575() = zeros5575(Type[Float64][1], 1)
@test Base.return_types(f5575, ())[1] == Vector

g5575() = zeros(Type[Float64][1], 1)
@test_broken Base.return_types(g5575, ())[1] == Vector # This should be fixed by removing deprecations
@test Base.return_types(g5575, ())[1] == Vector


# make sure Tuple{unknown} handles the possibility that `unknown` is a Vararg
Expand Down

0 comments on commit 9b01d1a

Please sign in to comment.