From 3a49b3a016627be4bb044aea3a016ded6fb5bd45 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 14:01:22 -0400 Subject: [PATCH 01/10] Fix several broadcast issues --- src/broadcast.jl | 6 ++++-- test/broadcast.jl | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index e892fd48..4c66c105 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -10,6 +10,7 @@ import Base.Broadcast: # This isn't the precise output type, just a placeholder to return from # promote_containertype, which will control dispatch to our broadcast_c. _containertype(::Type{<:StaticArray}) = StaticArray +_containertype(::Type{<:RowVector{<:Any,<:SVector}}) = StaticArray # With the above, the default promote_containertype gives reasonable defaults: # StaticArray, StaticArray -> StaticArray @@ -32,6 +33,7 @@ broadcast_indices(::Type{StaticArray}, A) = indices(A) _broadcast(f, broadcast_sizes(as...), as...) end +@inline broadcast_sizes(a::RowVector{<:Any,<:SVector}, as...) = (Size(a), broadcast_sizes(as...)...) @inline broadcast_sizes(a::StaticArray, as...) = (Size(a), broadcast_sizes(as...)...) @inline broadcast_sizes(a, as...) = (Size(), broadcast_sizes(as...)...) @inline broadcast_sizes() = () @@ -66,9 +68,9 @@ end for i = 1:length(sizes) s = sizes[i] for j = 1:length(s) - if newsize[j] == 1 || newsize[j] == s[j] + if newsize[j] == 1 newsize[j] = s[j] - else + elseif newsize[j] ≠ s[j] && s[j] ≠ 1 throw(DimensionMismatch("Tried to broadcast on inputs sized $sizes")) end end diff --git a/test/broadcast.jl b/test/broadcast.jl index b80708a4..f680ba9a 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -45,16 +45,16 @@ end @testset "2x2 StaticMatrix with 1x2 StaticMatrix" begin m1 = @SMatrix [1 2; 3 4] m2 = @SMatrix [1 4] - @test_broken @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 - @test_broken @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 + @test @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 + @test @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 @test @inferred(m2 .+ m1) === @SMatrix [2 6; 4 8] - @test_broken @inferred(m1 .* m2) === @SMatrix [1 8; 3 16] #197 + @test @inferred(m1 .* m2) === @SMatrix [1 8; 3 16] #197 @test @inferred(m2 .* m1) === @SMatrix [1 8; 3 16] - @test_broken @inferred(m1 ./ m2) === @SMatrix [1 1/2; 3 1] #197 + @test @inferred(m1 ./ m2) === @SMatrix [1 1/2; 3 1] #197 @test @inferred(m2 ./ m1) === @SMatrix [1 2; 1/3 1] - @test_broken @inferred(m1 .- m2) === @SMatrix [0 -2; 2 0] #197 + @test @inferred(m1 .- m2) === @SMatrix [0 -2; 2 0] #197 @test @inferred(m2 .- m1) === @SMatrix [0 2; -2 0] - @test_broken @inferred(m1 .^ m2) === @SMatrix [1 16; 1 256] #197 + @test @inferred(m1 .^ m2) === @SMatrix [1 16; 3 256] #197 end @testset "1x2 StaticMatrix with StaticVector" begin @@ -62,15 +62,15 @@ end v = SVector(1, 4) @test @inferred(broadcast(+, m, v)) === @SMatrix [2 3; 5 6] @test @inferred(m .+ v) === @SMatrix [2 3; 5 6] - @test_broken @inferred(v .+ m) === @SMatrix [2 3; 5 6] #197 + @test @inferred(v .+ m) === @SMatrix [2 3; 5 6] #197 @test @inferred(m .* v) === @SMatrix [1 2; 4 8] - @test_broken @inferred(v .* m) === @SMatrix [1 2; 4 8] #197 + @test @inferred(v .* m) === @SMatrix [1 2; 4 8] #197 @test @inferred(m ./ v) === @SMatrix [1 2; 1/4 1/2] - @test_broken @inferred(v ./ m) === @SMatrix [1 1/2; 4 2] #197 + @test @inferred(v ./ m) === @SMatrix [1 1/2; 4 2] #197 @test @inferred(m .- v) === @SMatrix [0 1; -3 -2] - @test_broken @inferred(v .- m) === @SMatrix [0 -1; 3 2] #197 + @test @inferred(v .- m) === @SMatrix [0 -1; 3 2] #197 @test @inferred(m .^ v) === @SMatrix [1 2; 1 16] - @test_broken @inferred(v .^ m) === @SMatrix [1 1; 4 16] #197 + @test @inferred(v .^ m) === @SMatrix [1 1; 4 16] #197 end @testset "StaticVector with StaticVector" begin @@ -89,9 +89,9 @@ end @test @inferred(v2 .^ v1) === SVector(1, 16) # test case issue #199 @test @inferred(SVector(1) .+ SVector()) === SVector() - @test_broken @inferred(SVector() .+ SVector(1)) === SVector() + @test @inferred(SVector() .+ SVector(1)) === SVector() # test case issue #200 - @test_broken @inferred(v1 .+ v2') === @SMatrix [2 5; 3 5] + @test @inferred(v1 .+ v2') === @SMatrix [2 5; 3 6] end @testset "StaticVector with Scalar" begin From e45d995354db8de11c533870d76eaf5d13f339f8 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 15:56:31 -0400 Subject: [PATCH 02/10] Additionally fix #198 by using Base.promote_op --- src/broadcast.jl | 2 +- src/mapreduce.jl | 2 +- test/broadcast.jl | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index 4c66c105..0be38a38 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -103,7 +103,7 @@ end end eltype_exprs = [t <: AbstractArray ? :($(eltype(t))) : :($t) for t ∈ a] - newtype_expr = :(Core.Inference.return_type(f, Tuple{$(eltype_exprs...)})) + newtype_expr = prod(newsize) > 0 ? :(Base.promote_op(f, $(eltype_exprs...))) : :(Union{}) return quote @_inline_meta diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 447c435d..c7225895 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -17,7 +17,7 @@ end exprs[i] = :(f($(tmp...))) end eltypes = [eltype(a[j]) for j ∈ 1:length(a)] # presumably, `eltype` is "hyperpure"? - newT = :(Core.Inference.return_type(f, Tuple{$(eltypes...)})) + newT = :(Base.promote_op(f, $(eltypes...))) return quote @_inline_meta @inbounds return similar_type(typeof(_first(a...)), $newT, Size(S))(tuple($(exprs...))) diff --git a/test/broadcast.jl b/test/broadcast.jl index f680ba9a..388dadc3 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -136,22 +136,22 @@ end @testset "eltype after broadcast" begin # test cases issue #198 let a = SVector{4, Number}(2, 2.0, 4//2, 2+0im) - @test_broken eltype(a + 2) == Number - @test_broken eltype(a - 2) == Number - @test_broken eltype(a * 2) == Number - @test_broken eltype(a / 2) == Number + @test eltype(a + 2) == Number + @test eltype(a - 2) == Number + @test eltype(a * 2) == Number + @test eltype(a / 2) == Number end let a = SVector{3, Real}(2, 2.0, 4//2) - @test_broken eltype(a + 2) == Real - @test_broken eltype(a - 2) == Real - @test_broken eltype(a * 2) == Real - @test_broken eltype(a / 2) == Real + @test eltype(a + 2) == Real + @test eltype(a - 2) == Real + @test eltype(a * 2) == Real + @test eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) - @test_broken eltype(a + 2.0) == Float64 - @test_broken eltype(a - 2.0) == Float64 - @test_broken eltype(a * 2.0) == Float64 - @test_broken eltype(a / 2.0) == Float64 + @test eltype(a + 2.0) == Real + @test eltype(a - 2.0) == Real + @test eltype(a * 2.0) == Real + @test eltype(a / 2.0) == Real end let a = broadcast(Float32, SVector(3, 4, 5)) @test eltype(a) == Float32 From 815860aea858eb3bf4b78fd82ca3d9eeda7724f2 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 16:38:48 -0400 Subject: [PATCH 03/10] Revert some @test for #198 to @test_broken --- test/broadcast.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/broadcast.jl b/test/broadcast.jl index 388dadc3..860c621a 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -148,10 +148,10 @@ end @test eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) - @test eltype(a + 2.0) == Real - @test eltype(a - 2.0) == Real - @test eltype(a * 2.0) == Real - @test eltype(a / 2.0) == Real + @test_broken eltype(a + 2.0) == Float64 + @test_broken eltype(a - 2.0) == Float64 + @test_broken eltype(a * 2.0) == Float64 + @test_broken eltype(a / 2.0) == Float64 end let a = broadcast(Float32, SVector(3, 4, 5)) @test eltype(a) == Float32 From 6c94be90b1a6c55d0bfa1f56e25f93305f243165 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 14:01:22 -0400 Subject: [PATCH 04/10] Fix several broadcast issues --- src/broadcast.jl | 6 ++++-- test/broadcast.jl | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index e892fd48..4c66c105 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -10,6 +10,7 @@ import Base.Broadcast: # This isn't the precise output type, just a placeholder to return from # promote_containertype, which will control dispatch to our broadcast_c. _containertype(::Type{<:StaticArray}) = StaticArray +_containertype(::Type{<:RowVector{<:Any,<:SVector}}) = StaticArray # With the above, the default promote_containertype gives reasonable defaults: # StaticArray, StaticArray -> StaticArray @@ -32,6 +33,7 @@ broadcast_indices(::Type{StaticArray}, A) = indices(A) _broadcast(f, broadcast_sizes(as...), as...) end +@inline broadcast_sizes(a::RowVector{<:Any,<:SVector}, as...) = (Size(a), broadcast_sizes(as...)...) @inline broadcast_sizes(a::StaticArray, as...) = (Size(a), broadcast_sizes(as...)...) @inline broadcast_sizes(a, as...) = (Size(), broadcast_sizes(as...)...) @inline broadcast_sizes() = () @@ -66,9 +68,9 @@ end for i = 1:length(sizes) s = sizes[i] for j = 1:length(s) - if newsize[j] == 1 || newsize[j] == s[j] + if newsize[j] == 1 newsize[j] = s[j] - else + elseif newsize[j] ≠ s[j] && s[j] ≠ 1 throw(DimensionMismatch("Tried to broadcast on inputs sized $sizes")) end end diff --git a/test/broadcast.jl b/test/broadcast.jl index b80708a4..f680ba9a 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -45,16 +45,16 @@ end @testset "2x2 StaticMatrix with 1x2 StaticMatrix" begin m1 = @SMatrix [1 2; 3 4] m2 = @SMatrix [1 4] - @test_broken @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 - @test_broken @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 + @test @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 + @test @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 @test @inferred(m2 .+ m1) === @SMatrix [2 6; 4 8] - @test_broken @inferred(m1 .* m2) === @SMatrix [1 8; 3 16] #197 + @test @inferred(m1 .* m2) === @SMatrix [1 8; 3 16] #197 @test @inferred(m2 .* m1) === @SMatrix [1 8; 3 16] - @test_broken @inferred(m1 ./ m2) === @SMatrix [1 1/2; 3 1] #197 + @test @inferred(m1 ./ m2) === @SMatrix [1 1/2; 3 1] #197 @test @inferred(m2 ./ m1) === @SMatrix [1 2; 1/3 1] - @test_broken @inferred(m1 .- m2) === @SMatrix [0 -2; 2 0] #197 + @test @inferred(m1 .- m2) === @SMatrix [0 -2; 2 0] #197 @test @inferred(m2 .- m1) === @SMatrix [0 2; -2 0] - @test_broken @inferred(m1 .^ m2) === @SMatrix [1 16; 1 256] #197 + @test @inferred(m1 .^ m2) === @SMatrix [1 16; 3 256] #197 end @testset "1x2 StaticMatrix with StaticVector" begin @@ -62,15 +62,15 @@ end v = SVector(1, 4) @test @inferred(broadcast(+, m, v)) === @SMatrix [2 3; 5 6] @test @inferred(m .+ v) === @SMatrix [2 3; 5 6] - @test_broken @inferred(v .+ m) === @SMatrix [2 3; 5 6] #197 + @test @inferred(v .+ m) === @SMatrix [2 3; 5 6] #197 @test @inferred(m .* v) === @SMatrix [1 2; 4 8] - @test_broken @inferred(v .* m) === @SMatrix [1 2; 4 8] #197 + @test @inferred(v .* m) === @SMatrix [1 2; 4 8] #197 @test @inferred(m ./ v) === @SMatrix [1 2; 1/4 1/2] - @test_broken @inferred(v ./ m) === @SMatrix [1 1/2; 4 2] #197 + @test @inferred(v ./ m) === @SMatrix [1 1/2; 4 2] #197 @test @inferred(m .- v) === @SMatrix [0 1; -3 -2] - @test_broken @inferred(v .- m) === @SMatrix [0 -1; 3 2] #197 + @test @inferred(v .- m) === @SMatrix [0 -1; 3 2] #197 @test @inferred(m .^ v) === @SMatrix [1 2; 1 16] - @test_broken @inferred(v .^ m) === @SMatrix [1 1; 4 16] #197 + @test @inferred(v .^ m) === @SMatrix [1 1; 4 16] #197 end @testset "StaticVector with StaticVector" begin @@ -89,9 +89,9 @@ end @test @inferred(v2 .^ v1) === SVector(1, 16) # test case issue #199 @test @inferred(SVector(1) .+ SVector()) === SVector() - @test_broken @inferred(SVector() .+ SVector(1)) === SVector() + @test @inferred(SVector() .+ SVector(1)) === SVector() # test case issue #200 - @test_broken @inferred(v1 .+ v2') === @SMatrix [2 5; 3 5] + @test @inferred(v1 .+ v2') === @SMatrix [2 5; 3 6] end @testset "StaticVector with Scalar" begin From c96363a0fc0822393e4426c5c2443776f80df4ab Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 15:56:31 -0400 Subject: [PATCH 05/10] Additionally fix #198 by using Base.promote_op --- src/broadcast.jl | 2 +- src/mapreduce.jl | 2 +- test/broadcast.jl | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index 4c66c105..0be38a38 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -103,7 +103,7 @@ end end eltype_exprs = [t <: AbstractArray ? :($(eltype(t))) : :($t) for t ∈ a] - newtype_expr = :(Core.Inference.return_type(f, Tuple{$(eltype_exprs...)})) + newtype_expr = prod(newsize) > 0 ? :(Base.promote_op(f, $(eltype_exprs...))) : :(Union{}) return quote @_inline_meta diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 12188c3e..bc9ff4ec 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -17,7 +17,7 @@ end exprs[i] = :(f($(tmp...))) end eltypes = [eltype(a[j]) for j ∈ 1:length(a)] # presumably, `eltype` is "hyperpure"? - newT = :(Core.Inference.return_type(f, Tuple{$(eltypes...)})) + newT = :(Base.promote_op(f, $(eltypes...))) return quote @_inline_meta @inbounds return similar_type(typeof(_first(a...)), $newT, Size(S))(tuple($(exprs...))) diff --git a/test/broadcast.jl b/test/broadcast.jl index f680ba9a..388dadc3 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -136,22 +136,22 @@ end @testset "eltype after broadcast" begin # test cases issue #198 let a = SVector{4, Number}(2, 2.0, 4//2, 2+0im) - @test_broken eltype(a + 2) == Number - @test_broken eltype(a - 2) == Number - @test_broken eltype(a * 2) == Number - @test_broken eltype(a / 2) == Number + @test eltype(a + 2) == Number + @test eltype(a - 2) == Number + @test eltype(a * 2) == Number + @test eltype(a / 2) == Number end let a = SVector{3, Real}(2, 2.0, 4//2) - @test_broken eltype(a + 2) == Real - @test_broken eltype(a - 2) == Real - @test_broken eltype(a * 2) == Real - @test_broken eltype(a / 2) == Real + @test eltype(a + 2) == Real + @test eltype(a - 2) == Real + @test eltype(a * 2) == Real + @test eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) - @test_broken eltype(a + 2.0) == Float64 - @test_broken eltype(a - 2.0) == Float64 - @test_broken eltype(a * 2.0) == Float64 - @test_broken eltype(a / 2.0) == Float64 + @test eltype(a + 2.0) == Real + @test eltype(a - 2.0) == Real + @test eltype(a * 2.0) == Real + @test eltype(a / 2.0) == Real end let a = broadcast(Float32, SVector(3, 4, 5)) @test eltype(a) == Float32 From c0be60ed7a8411cb5e77daaed0b7722c79e3837e Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 16:38:48 -0400 Subject: [PATCH 06/10] Revert some @test for #198 to @test_broken --- test/broadcast.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/broadcast.jl b/test/broadcast.jl index 388dadc3..860c621a 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -148,10 +148,10 @@ end @test eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) - @test eltype(a + 2.0) == Real - @test eltype(a - 2.0) == Real - @test eltype(a * 2.0) == Real - @test eltype(a / 2.0) == Real + @test_broken eltype(a + 2.0) == Float64 + @test_broken eltype(a - 2.0) == Float64 + @test_broken eltype(a * 2.0) == Float64 + @test_broken eltype(a / 2.0) == Float64 end let a = broadcast(Float32, SVector(3, 4, 5)) @test eltype(a) == Float32 From 5b6665f9ab3e84d2cb1c05359377be38f1046cc3 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 17:55:04 -0400 Subject: [PATCH 07/10] Revert Base.promote_op to Core.Inference.return_type --- src/broadcast.jl | 2 +- src/mapreduce.jl | 6 +++--- test/broadcast.jl | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index 0be38a38..4c66c105 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -103,7 +103,7 @@ end end eltype_exprs = [t <: AbstractArray ? :($(eltype(t))) : :($t) for t ∈ a] - newtype_expr = prod(newsize) > 0 ? :(Base.promote_op(f, $(eltype_exprs...))) : :(Union{}) + newtype_expr = :(Core.Inference.return_type(f, Tuple{$(eltype_exprs...)})) return quote @_inline_meta diff --git a/src/mapreduce.jl b/src/mapreduce.jl index bc9ff4ec..90144256 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -17,7 +17,7 @@ end exprs[i] = :(f($(tmp...))) end eltypes = [eltype(a[j]) for j ∈ 1:length(a)] # presumably, `eltype` is "hyperpure"? - newT = :(Base.promote_op(f, $(eltypes...))) + newT = :(Core.Inference.return_type(f, Tuple{$(eltypes...)})) return quote @_inline_meta @inbounds return similar_type(typeof(_first(a...)), $newT, Size(S))(tuple($(exprs...))) @@ -105,7 +105,7 @@ end N = length(S) Snew = ([n==D ? 1 : S[n] for n = 1:N]...) T0 = eltype(a) - T = :((T1 = Base.promote_op(f, $T0); Base.promote_op(op, T1, T1))) + T = :((T1 = Core.Inference.return_type(f, Tuple{$T0}); Core.Inference.return_type(op, Tuple{T1,T1}))) exprs = Array{Expr}(Snew) itr = [1:n for n ∈ Snew] @@ -235,7 +235,7 @@ end @generated function _diff(::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D} N = length(S) Snew = ([n==D ? S[n]-1 : S[n] for n = 1:N]...) - T = Base.promote_op(-, eltype(a), eltype(a)) + T = Core.Inference.return_type(-, Tuple{eltype(a),eltype(a)}) exprs = Array{Expr}(Snew) itr = [1:n for n = Snew] diff --git a/test/broadcast.jl b/test/broadcast.jl index 860c621a..f680ba9a 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -136,16 +136,16 @@ end @testset "eltype after broadcast" begin # test cases issue #198 let a = SVector{4, Number}(2, 2.0, 4//2, 2+0im) - @test eltype(a + 2) == Number - @test eltype(a - 2) == Number - @test eltype(a * 2) == Number - @test eltype(a / 2) == Number + @test_broken eltype(a + 2) == Number + @test_broken eltype(a - 2) == Number + @test_broken eltype(a * 2) == Number + @test_broken eltype(a / 2) == Number end let a = SVector{3, Real}(2, 2.0, 4//2) - @test eltype(a + 2) == Real - @test eltype(a - 2) == Real - @test eltype(a * 2) == Real - @test eltype(a / 2) == Real + @test_broken eltype(a + 2) == Real + @test_broken eltype(a - 2) == Real + @test_broken eltype(a * 2) == Real + @test_broken eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) @test_broken eltype(a + 2.0) == Float64 From 8a265e8f4dd2551102c6b4568bdfcd297c4eef40 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Tue, 8 Aug 2017 17:55:04 -0400 Subject: [PATCH 08/10] Revert Base.promote_op to Core.Inference.return_type --- src/broadcast.jl | 2 +- src/mapreduce.jl | 2 +- test/broadcast.jl | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index 0be38a38..4c66c105 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -103,7 +103,7 @@ end end eltype_exprs = [t <: AbstractArray ? :($(eltype(t))) : :($t) for t ∈ a] - newtype_expr = prod(newsize) > 0 ? :(Base.promote_op(f, $(eltype_exprs...))) : :(Union{}) + newtype_expr = :(Core.Inference.return_type(f, Tuple{$(eltype_exprs...)})) return quote @_inline_meta diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 7cd0906b..90144256 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -17,7 +17,7 @@ end exprs[i] = :(f($(tmp...))) end eltypes = [eltype(a[j]) for j ∈ 1:length(a)] # presumably, `eltype` is "hyperpure"? - newT = :(Base.promote_op(f, $(eltypes...))) + newT = :(Core.Inference.return_type(f, Tuple{$(eltypes...)})) return quote @_inline_meta @inbounds return similar_type(typeof(_first(a...)), $newT, Size(S))(tuple($(exprs...))) diff --git a/test/broadcast.jl b/test/broadcast.jl index 860c621a..f680ba9a 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -136,16 +136,16 @@ end @testset "eltype after broadcast" begin # test cases issue #198 let a = SVector{4, Number}(2, 2.0, 4//2, 2+0im) - @test eltype(a + 2) == Number - @test eltype(a - 2) == Number - @test eltype(a * 2) == Number - @test eltype(a / 2) == Number + @test_broken eltype(a + 2) == Number + @test_broken eltype(a - 2) == Number + @test_broken eltype(a * 2) == Number + @test_broken eltype(a / 2) == Number end let a = SVector{3, Real}(2, 2.0, 4//2) - @test eltype(a + 2) == Real - @test eltype(a - 2) == Real - @test eltype(a * 2) == Real - @test eltype(a / 2) == Real + @test_broken eltype(a + 2) == Real + @test_broken eltype(a - 2) == Real + @test_broken eltype(a * 2) == Real + @test_broken eltype(a / 2) == Real end let a = SVector{3, Real}(2, 2.0, 4//2) @test_broken eltype(a + 2.0) == Float64 From 1fb202473ed698c6446328869d4e3fb7e48ab90c Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Thu, 10 Aug 2017 15:18:31 -0400 Subject: [PATCH 09/10] Avoid using Core.Inference.return_type when possible --- src/mapreduce.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 90144256..aa2af46d 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -235,7 +235,7 @@ end @generated function _diff(::Size{S}, a::StaticArray, ::Type{Val{D}}) where {S,D} N = length(S) Snew = ([n==D ? S[n]-1 : S[n] for n = 1:N]...) - T = Core.Inference.return_type(-, Tuple{eltype(a),eltype(a)}) + T = typeof(one(eltype(a)) - one(eltype(a))) exprs = Array{Expr}(Snew) itr = [1:n for n = Snew] From 9cf3d2a756818f308a9348fe9d61103821ebdd90 Mon Sep 17 00:00:00 2001 From: Wonseok Shin Date: Thu, 10 Aug 2017 15:20:01 -0400 Subject: [PATCH 10/10] Use more descriptive comments in test/broadcast.jl --- test/broadcast.jl | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/test/broadcast.jl b/test/broadcast.jl index f680ba9a..b22916d3 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -43,34 +43,36 @@ end end @testset "2x2 StaticMatrix with 1x2 StaticMatrix" begin + # Issues #197, #242: broadcast between SArray and row-like SMatrix m1 = @SMatrix [1 2; 3 4] m2 = @SMatrix [1 4] - @test @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] #197 - @test @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] #197 + @test @inferred(broadcast(+, m1, m2)) === @SMatrix [2 6; 4 8] + @test @inferred(m1 .+ m2) === @SMatrix [2 6; 4 8] @test @inferred(m2 .+ m1) === @SMatrix [2 6; 4 8] - @test @inferred(m1 .* m2) === @SMatrix [1 8; 3 16] #197 + @test @inferred(m1 .* m2) === @SMatrix [1 8; 3 16] @test @inferred(m2 .* m1) === @SMatrix [1 8; 3 16] - @test @inferred(m1 ./ m2) === @SMatrix [1 1/2; 3 1] #197 + @test @inferred(m1 ./ m2) === @SMatrix [1 1/2; 3 1] @test @inferred(m2 ./ m1) === @SMatrix [1 2; 1/3 1] - @test @inferred(m1 .- m2) === @SMatrix [0 -2; 2 0] #197 + @test @inferred(m1 .- m2) === @SMatrix [0 -2; 2 0] @test @inferred(m2 .- m1) === @SMatrix [0 2; -2 0] - @test @inferred(m1 .^ m2) === @SMatrix [1 16; 3 256] #197 + @test @inferred(m1 .^ m2) === @SMatrix [1 16; 3 256] end @testset "1x2 StaticMatrix with StaticVector" begin + # Issues #197, #242: broadcast between SVector and row-like SMatrix m = @SMatrix [1 2] v = SVector(1, 4) @test @inferred(broadcast(+, m, v)) === @SMatrix [2 3; 5 6] @test @inferred(m .+ v) === @SMatrix [2 3; 5 6] - @test @inferred(v .+ m) === @SMatrix [2 3; 5 6] #197 + @test @inferred(v .+ m) === @SMatrix [2 3; 5 6] @test @inferred(m .* v) === @SMatrix [1 2; 4 8] - @test @inferred(v .* m) === @SMatrix [1 2; 4 8] #197 + @test @inferred(v .* m) === @SMatrix [1 2; 4 8] @test @inferred(m ./ v) === @SMatrix [1 2; 1/4 1/2] - @test @inferred(v ./ m) === @SMatrix [1 1/2; 4 2] #197 + @test @inferred(v ./ m) === @SMatrix [1 1/2; 4 2] @test @inferred(m .- v) === @SMatrix [0 1; -3 -2] - @test @inferred(v .- m) === @SMatrix [0 -1; 3 2] #197 + @test @inferred(v .- m) === @SMatrix [0 -1; 3 2] @test @inferred(m .^ v) === @SMatrix [1 2; 1 16] - @test @inferred(v .^ m) === @SMatrix [1 1; 4 16] #197 + @test @inferred(v .^ m) === @SMatrix [1 1; 4 16] end @testset "StaticVector with StaticVector" begin @@ -87,10 +89,10 @@ end @test @inferred(v2 .- v1) === SVector(0, 2) @test @inferred(v1 .^ v2) === SVector(1, 16) @test @inferred(v2 .^ v1) === SVector(1, 16) - # test case issue #199 + # Issue #199: broadcast with empty SArray @test @inferred(SVector(1) .+ SVector()) === SVector() @test @inferred(SVector() .+ SVector(1)) === SVector() - # test case issue #200 + # Issue #200: broadcast with RowVector @test @inferred(v1 .+ v2') === @SMatrix [2 5; 3 6] end