Skip to content

Commit

Permalink
move things around and add further description to the code
Browse files Browse the repository at this point in the history
  • Loading branch information
torfjelde committed Oct 26, 2023
1 parent 764e744 commit 2d34ad8
Showing 1 changed file with 18 additions and 9 deletions.
27 changes: 18 additions & 9 deletions src/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -481,23 +481,27 @@ Base.@propagate_inbounds _setindex!(xs, v, I...) = (setindex!(xs, v, I...); xs)

pure(::typeof(_setindex!)) = NoBang._setindex
possible(::typeof(_setindex!), ::Union{Tuple,NamedTuple,Empty}, ::Vararg) = false
possible(::typeof(_setindex!), ::C, ::T, ::Vararg) where {C <: AbstractArray, T} =
implements(setindex!, C) && promote_type(eltype(C), T) <: eltype(C)
possible(::typeof(_setindex!), ::C, ::V, ::K) where {C <: AbstractDict, V, K} =
implements(setindex!, C) &&
promote_type(keytype(C), K) <: keytype(C) &&
promote_type(valtype(C), V) <: valtype(C)

# Need to support a wide range of indexing behaviors.
# - Tuples of indices
# - Colon
# - AbstractUnitRange
# - Indexing with arrays
# Default implementation for `_setindex!` with `AbstractArray`.
# But this will return `false` even in cases such as
#
# setindex!!([1, 2, 3], [4, 5, 6], :)
#
# because `promote_type(eltype(C), T) <: eltype(C)` is `false`.
possible(::typeof(_setindex!), ::C, ::T, ::Vararg) where {C <: AbstractArray, T} =
implements(setindex!, C) && promote_type(eltype(C), T) <: eltype(C)

# To address this, we specialize on the case where `T<:AbstractArray`.
# In addition, we need to support a wide range of indexing behaviors:
#
# Also need to ensure that the dimensionality of the index is
# We also need to ensure that the dimensionality of the index is
# valid, i.e. that we're not returning `true` in cases such as
#
# setindex!!([1, 2, 3], 1, [4, 5])
# setindex!!([1, 2, 3], [4, 5], 1)
#
# which should return `false`.
_index_dimension(::Any) = 0
Expand All @@ -513,6 +517,11 @@ function possible(
) where {M, C <: AbstractArray{<:Real}, T <: AbstractArray{<:Real,M}}
return implements(setindex!, C) &&
promote_type(eltype(C), eltype(T)) <: eltype(C) &&
# This will still return `false` for scenarios such as
#
# setindex!!([1, 2, 3], [4, 5, 6], :, 1)
#
# which are in fact valid. However, this case is rare.
(_index_dimension(indices) == M || _index_dimension(indices) == 1)
end

Expand Down

0 comments on commit 2d34ad8

Please sign in to comment.