From 94e0fb612d9efb5ff80f0851d34c8857db226cd7 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Fri, 20 Oct 2017 10:48:05 -0500 Subject: [PATCH] Make no-index A[] check bounds like everyone else In #23628, we deprecated omitting indices over dimensions that are not of length 1. Unfortunately the 0-index case got left behind. This brings it into consistency. In short, once this deprecation is removed, `A[]` will _also_ assert that there is only one element in `A`. --- base/abstractarray.jl | 29 ++++++++--------------------- base/array.jl | 5 ++--- base/subarray.jl | 2 +- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 3ffb9657e3e34..d6b32e16c59a8 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -399,7 +399,6 @@ function checkbounds(A::AbstractArray, I...) checkbounds(Bool, A, I...) || throw_boundserror(A, I) nothing end -checkbounds(A::AbstractArray) = checkbounds(A, 1) # 0-d case """ checkbounds_indices(Bool, IA, I) @@ -943,7 +942,6 @@ _getindex(::IndexStyle, A::AbstractArray, I...) = ## IndexLinear Scalar indexing: canonical method is one Int _getindex(::IndexLinear, A::AbstractArray, i::Int) = (@_propagate_inbounds_meta; getindex(A, i)) -_getindex(::IndexLinear, A::AbstractArray) = (@_propagate_inbounds_meta; getindex(A, _to_linear_index(A))) function _getindex(::IndexLinear, A::AbstractArray, I::Vararg{Int,M}) where M @_inline_meta @boundscheck checkbounds(A, I...) # generally _to_linear_index requires bounds checking @@ -951,16 +949,11 @@ function _getindex(::IndexLinear, A::AbstractArray, I::Vararg{Int,M}) where M r end _to_linear_index(A::AbstractArray, i::Int) = i -_to_linear_index(A::AbstractVector, i::Int, I::Int...) = i # TODO: DEPRECATE FOR #14770 -_to_linear_index(A::AbstractArray{T,N}, I::Vararg{Int,N}) where {T,N} = (@_inline_meta; sub2ind(A, I...)) -_to_linear_index(A::AbstractArray) = 1 # TODO: DEPRECATE FOR #14770 -_to_linear_index(A::AbstractArray, I::Int...) = (@_inline_meta; sub2ind(A, I...)) # TODO: DEPRECATE FOR #14770 +_to_linear_index(A::AbstractVector, i::Int, I::Int...) = i +_to_linear_index(A::AbstractArray) = 1 +_to_linear_index(A::AbstractArray, I::Int...) = (@_inline_meta; sub2ind(A, I...)) ## IndexCartesian Scalar indexing: Canonical method is full dimensionality of Ints -function _getindex(::IndexCartesian, A::AbstractArray) - @_propagate_inbounds_meta - getindex(A, _to_subscript_indices(A)...) -end function _getindex(::IndexCartesian, A::AbstractArray, I::Vararg{Int,M}) where M @_inline_meta @boundscheck checkbounds(A, I...) # generally _to_subscript_indices requires bounds checking @@ -972,11 +965,11 @@ function _getindex(::IndexCartesian, A::AbstractArray{T,N}, I::Vararg{Int, N}) w getindex(A, I...) end _to_subscript_indices(A::AbstractArray, i::Int) = (@_inline_meta; _unsafe_ind2sub(A, i)) -_to_subscript_indices(A::AbstractArray{T,N}) where {T,N} = (@_inline_meta; fill_to_length((), 1, Val(N))) # TODO: DEPRECATE FOR #14770 -_to_subscript_indices(A::AbstractArray{T,0}) where {T} = () # TODO: REMOVE FOR #14770 -_to_subscript_indices(A::AbstractArray{T,0}, i::Int) where {T} = () # TODO: REMOVE FOR #14770 -_to_subscript_indices(A::AbstractArray{T,0}, I::Int...) where {T} = () # TODO: DEPRECATE FOR #14770 -function _to_subscript_indices(A::AbstractArray{T,N}, I::Int...) where {T,N} # TODO: DEPRECATE FOR #14770 +_to_subscript_indices(A::AbstractArray{T,N}) where {T,N} = (@_inline_meta; fill_to_length((), 1, Val(N))) +_to_subscript_indices(A::AbstractArray{T,0}) where {T} = () +_to_subscript_indices(A::AbstractArray{T,0}, i::Int) where {T} = () +_to_subscript_indices(A::AbstractArray{T,0}, I::Int...) where {T} = () +function _to_subscript_indices(A::AbstractArray{T,N}, I::Int...) where {T,N} @_inline_meta J, Jrem = IteratorsMD.split(I, Val(N)) _to_subscript_indices(A, J, Jrem) @@ -1019,7 +1012,6 @@ _setindex!(::IndexStyle, A::AbstractArray, v, I...) = ## IndexLinear Scalar indexing _setindex!(::IndexLinear, A::AbstractArray, v, i::Int) = (@_propagate_inbounds_meta; setindex!(A, v, i)) -_setindex!(::IndexLinear, A::AbstractArray, v) = (@_propagate_inbounds_meta; setindex!(A, v, _to_linear_index(A))) function _setindex!(::IndexLinear, A::AbstractArray, v, I::Vararg{Int,M}) where M @_inline_meta @boundscheck checkbounds(A, I...) @@ -1032,10 +1024,6 @@ function _setindex!(::IndexCartesian, A::AbstractArray{T,N}, v, I::Vararg{Int, N @_propagate_inbounds_meta setindex!(A, v, I...) end -function _setindex!(::IndexCartesian, A::AbstractArray, v) - @_propagate_inbounds_meta - setindex!(A, v, _to_subscript_indices(A)...) -end function _setindex!(::IndexCartesian, A::AbstractArray, v, I::Vararg{Int,M}) where M @_inline_meta @boundscheck checkbounds(A, I...) @@ -1072,7 +1060,6 @@ end get(A::AbstractArray, I::AbstractRange, default) = get!(similar(A, typeof(default), index_shape(I)), A, I, default) -# TODO: DEPRECATE FOR #14770 (just the partial linear indexing part) function get!(X::AbstractArray{T}, A::AbstractArray, I::RangeVecIntList, default::T) where T fill!(X, default) dst, src = indcopy(size(A), I) diff --git a/base/array.jl b/base/array.jl index 8647a64714379..3b7096fdd254b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -756,7 +756,7 @@ function getindex end # This is more complicated than it needs to be in order to get Win64 through bootstrap @eval getindex(A::Array, i1::Int) = arrayref($(Expr(:boundscheck)), A, i1) -@eval getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@_inline_meta; arrayref($(Expr(:boundscheck)), A, i1, i2, I...)) # TODO: REMOVE FOR #14770 +@eval getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@_inline_meta; arrayref($(Expr(:boundscheck)), A, i1, i2, I...)) # Faster contiguous indexing using copy! for UnitRange and Colon function getindex(A::Array, I::UnitRange{Int}) @@ -795,7 +795,7 @@ function setindex! end @eval setindex!(A::Array{T}, x, i1::Int) where {T} = arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1) @eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} = - (@_inline_meta; arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1, i2, I...)) # TODO: REMOVE FOR #14770 + (@_inline_meta; arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1, i2, I...)) # These are redundant with the abstract fallbacks but needed for bootstrap function setindex!(A::Array, x, I::AbstractVector{Int}) @@ -2231,7 +2231,6 @@ end findin(a, b) = _findin(a, b) # Copying subregions -# TODO: DEPRECATE FOR #14770 function indcopy(sz::Dims, I::Vector) n = length(I) s = sz[n] diff --git a/base/subarray.jl b/base/subarray.jl index 2f083abe5e399..608a2395d0963 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -100,7 +100,7 @@ parentindexes(a::AbstractArray) = ntuple(i->OneTo(size(a,i)), ndims(a)) _maybe_reshape_parent(A::AbstractArray, ::NTuple{1, Bool}) = reshape(A, Val(1)) _maybe_reshape_parent(A::AbstractArray{<:Any,1}, ::NTuple{1, Bool}) = reshape(A, Val(1)) _maybe_reshape_parent(A::AbstractArray{<:Any,N}, ::NTuple{N, Bool}) where {N} = A -_maybe_reshape_parent(A::AbstractArray, ::NTuple{N, Bool}) where {N} = reshape(A, Val(N)) # TODO: DEPRECATE FOR #14770 +_maybe_reshape_parent(A::AbstractArray, ::NTuple{N, Bool}) where {N} = reshape(A, Val(N)) """ view(A, inds...)