Skip to content

Commit

Permalink
Normalize indices in promote_shape error messages.
Browse files Browse the repository at this point in the history
Seeing implementation like `Base.OneTo` in error messages may be
confusing to some users (cf discussion in JuliaLang#39242,
[discourse](https://discourse.julialang.org/t/promote-shape-dimension-mismatch/57529/)).

This PR turns
```julia
julia> ones(2, 3) + ones(3, 2)
ERROR: DimensionMismatch("dimensions must match: a has dims (Base.OneTo(2), Base.OneTo(3)), b has dims (Base.OneTo(3), Base.OneTo(2)), mismatch at 1")
```
into
```julia
julia> ones(2, 3) + ones(3, 2)
ERROR: DimensionMismatch("dimensions must match: a has axes (1:2, 1:3), b has axes (1:3, 1:2), mismatch at 1")
```

Fixes JuliaLang#40118.

Acked-by: Tamas K. Papp <tkpapp@gmail.com>
  • Loading branch information
tpapp committed Mar 21, 2021
1 parent 6913f9c commit 762d659
Showing 1 changed file with 21 additions and 21 deletions.
42 changes: 21 additions & 21 deletions base/indices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,26 +106,34 @@ IndexStyle(::IndexStyle, ::IndexStyle) = IndexCartesian()

promote_shape(::Tuple{}, ::Tuple{}) = ()

function promote_shape(a::Tuple{Int,}, b::Tuple{Int,})
if a[1] != b[1]
throw(DimensionMismatch("dimensions must match: a has dims $a, b has dims $b"))
# Consistent error message for promote_shape mismatch, hiding implementation details like
# OneTo. When b ≡ nothing, it is omitted; i can be supplied for an index.
function throw_promote_shape_mismatch(a, b, i = nothing)
_normalize(d) = map(x -> x isa AbstractUnitRange ? (firstindex(x):lastindex(x)) : x, d)
msg = "dimensions must match: a has dims $(_normalize(a))"
if b nothing
msg *= ", b has dims $(_normalize(b))"
end
if i nothing
msg *= ", mismatch at $(i)"
end
throw(DimensionMismatch(msg))
end

function promote_shape(a::Tuple{Int,}, b::Tuple{Int,})
a[1] != b[1] && throw_promote_shape_mismatch(a, b)
return a
end

function promote_shape(a::Tuple{Int,Int}, b::Tuple{Int,})
if a[1] != b[1] || a[2] != 1
throw(DimensionMismatch("dimensions must match: a has dims $a, b has dims $b"))
end
(a[1] != b[1] || a[2] != 1) && throw_promote_shape_mismatch(a, b)
return a
end

promote_shape(a::Tuple{Int,}, b::Tuple{Int,Int}) = promote_shape(b, a)

function promote_shape(a::Tuple{Int, Int}, b::Tuple{Int, Int})
if a[1] != b[1] || a[2] != b[2]
throw(DimensionMismatch("dimensions must match: a has dims $a, b has dims $b"))
end
(a[1] != b[1] || a[2] != b[2]) && throw_promote_shape_mismatch(a, b)
return a
end

Expand Down Expand Up @@ -153,14 +161,10 @@ function promote_shape(a::Dims, b::Dims)
return promote_shape(b, a)
end
for i=1:length(b)
if a[i] != b[i]
throw(DimensionMismatch("dimensions must match: a has dims $a, b has dims $b, mismatch at $i"))
end
a[i] != b[i] && throw_promote_shape_mismatch(a, b, i)
end
for i=length(b)+1:length(a)
if a[i] != 1
throw(DimensionMismatch("dimensions must match: a has dims $a, must have singleton at dim $i"))
end
a[i] != 1 && throw_promote_shape_mismatch(a, nothing, i)
end
return a
end
Expand All @@ -174,14 +178,10 @@ function promote_shape(a::Indices, b::Indices)
return promote_shape(b, a)
end
for i=1:length(b)
if a[i] != b[i]
throw(DimensionMismatch("dimensions must match: a has dims $a, b has dims $b, mismatch at $i"))
end
a[i] != b[i] && throw_promote_shape_mismatch(a, b, i)
end
for i=length(b)+1:length(a)
if a[i] != 1:1
throw(DimensionMismatch("dimensions must match: a has dims $a, must have singleton at dim $i"))
end
a[i] != 1:1 && throw_promote_shape_mismatch(a, nothing, i)
end
return a
end
Expand Down

0 comments on commit 762d659

Please sign in to comment.