From 1884cb4e3b17e24a6e9f5ad0bd653cfe7cbf070f Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 27 Nov 2018 06:01:12 -0600 Subject: [PATCH] Use only safe axis types for Broadcast.combine_axes #30074 used the wrong notion of consistency since `OneTo(1)` is consistent (wrt broadcasting) with any range, but `OneTo` cannot handle `Slice(-1:1)`. --- base/broadcast.jl | 11 ++++------- test/offsetarray.jl | 4 ++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index 7a4801f0c2aac..b7e49c376b6a5 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -435,19 +435,16 @@ end _bcs1(a::Integer, b::Integer) = a == 1 ? b : (b == 1 ? a : (a == b ? a : throw(DimensionMismatch("arrays could not be broadcast to a common size")))) _bcs1(a::Integer, b) = a == 1 ? b : (first(b) == 1 && last(b) == a ? b : throw(DimensionMismatch("arrays could not be broadcast to a common size"))) _bcs1(a, b::Integer) = _bcs1(b, a) -_bcs1(a, b) = _bcsm(b, a) ? _sametype(b, a) : (_bcsm(a, b) ? _sametype(a, b) : throw(DimensionMismatch("arrays could not be broadcast to a common size"))) +_bcs1(a, b) = _bcsm(b, a) ? axistype(b, a) : (_bcsm(a, b) ? axistype(a, b) : throw(DimensionMismatch("arrays could not be broadcast to a common size"))) # _bcsm tests whether the second index is consistent with the first _bcsm(a, b) = a == b || length(b) == 1 _bcsm(a, b::Number) = b == 1 _bcsm(a::Number, b::Number) = a == b || b == 1 # Ensure inferrability when dealing with axes of different AbstractUnitRange types # (We may not want to define general promotion rules between, say, OneTo and Slice, but if -# we get here we know the axes are at least consistent) -_sametype(a::T, b::T) where T = a -_sametype(a::OneTo, b::OneTo) = OneTo{Int}(a) -_sametype(a::OneTo, b) = OneTo{Int}(a) -_sametype(a, b::OneTo) = OneTo{Int}(a) -_sametype(a, b) = UnitRange{Int}(a) +# we get here we know the axes are at least consistent for the purposes of broadcasting) +axistype(a::T, b::T) where T = a +axistype(a, b) = UnitRange{Int}(a) ## Check that all arguments are broadcast compatible with shape # comparing one input against a shape diff --git a/test/offsetarray.jl b/test/offsetarray.jl index 5aa58853179eb..e3104c015b6e9 100644 --- a/test/offsetarray.jl +++ b/test/offsetarray.jl @@ -470,6 +470,10 @@ A = OffsetArray(view(rand(4,4), 1:4, 4:-1:1), (-3,5)) a = [1] b = OffsetArray(a, (0,)) @test @inferred(a .+ b) == [2] +a = OffsetArray([1, -2, 1], (-2,)) +@test a .* a' == OffsetArray([ 1 -2 1; + -2 4 -2; + 1 -2 1], (-2,-2)) end # let