From c3042f51ecfff1cd63ed12fba078506031e0fe4e Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 16 Feb 2018 17:42:50 -0500 Subject: [PATCH] deprecate using the value of `.=`. fixes #25954 --- src/julia-syntax.scm | 11 ++++++++++- stdlib/LinearAlgebra/src/diagonal.jl | 22 ++++++++++++---------- test/broadcast.jl | 22 ++++++++++++++++++---- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 02bae99181038..e94b33e34eec3 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1917,7 +1917,12 @@ '.= (lambda (e) - (expand-fuse-broadcast (cadr e) (caddr e))) + `(ifvalue + ,(let ((temp (make-ssavalue))) + `(block ,(expand-forms `(= ,temp ,(caddr e))) + ,(expand-fuse-broadcast (cadr e) temp) + ,temp)) + ,(expand-fuse-broadcast (cadr e) (caddr e)))) '|<:| (lambda (e) (expand-forms `(call |<:| ,@(cdr e)))) @@ -3664,6 +3669,10 @@ f(x) = yt(x) (if value (compile (cadr e) break-labels value tail) #f)) + ((ifvalue) + (if value + (syntax-deprecation "using the value of `.=`" "" current-loc)) + (compile (caddr e) break-labels value tail)) ((if elseif) (let ((test `(gotoifnot ,(compile-cond (cadr e) break-labels) _)) (end-jump `(goto _)) diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 9f7fa754b01a0..98b8b93c6396c 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -242,8 +242,8 @@ end *(D::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Diagonal}) = Diagonal(transpose.(D.parent.diag) .* transpose.(B.parent.diag)) -rmul!(A::Diagonal, B::Diagonal) = Diagonal(A.diag .*= B.diag) -lmul!(A::Diagonal, B::Diagonal) = Diagonal(B.diag .= A.diag .* B.diag) +rmul!(A::Diagonal, B::Diagonal) = Diagonal((A.diag .*= B.diag; A.diag)) +lmul!(A::Diagonal, B::Diagonal) = Diagonal((B.diag .= A.diag .* B.diag; B.diag)) function lmul!(adjA::Adjoint{<:Any,<:Diagonal}, B::AbstractMatrix) A = adjA.parent @@ -264,13 +264,13 @@ function rmul!(A::AbstractMatrix, transB::Transpose{<:Any,<:Diagonal}) end # Get ambiguous method if try to unify AbstractVector/AbstractMatrix here using AbstractVecOrMat -mul!(out::AbstractVector, A::Diagonal, in::AbstractVector) = out .= A.diag .* in -mul!(out::AbstractVector, A::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = out .= adjoint.(A.parent.diag) .* in -mul!(out::AbstractVector, A::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = out .= transpose.(A.parent.diag) .* in +mul!(out::AbstractVector, A::Diagonal, in::AbstractVector) = (out .= A.diag .* in; out) +mul!(out::AbstractVector, A::Adjoint{<:Any,<:Diagonal}, in::AbstractVector) = (out .= adjoint.(A.parent.diag) .* in; out) +mul!(out::AbstractVector, A::Transpose{<:Any,<:Diagonal}, in::AbstractVector) = (out .= transpose.(A.parent.diag) .* in; out) -mul!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = out .= A.diag .* in -mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= adjoint.(A.parent.diag) .* in -mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = out .= transpose.(A.parent.diag) .* in +mul!(out::AbstractMatrix, A::Diagonal, in::AbstractMatrix) = (out .= A.diag .* in; out) +mul!(out::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, in::AbstractMatrix) = (out .= adjoint.(A.parent.diag) .* in; out) +mul!(out::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, in::AbstractMatrix) = (out .= transpose.(A.parent.diag) .* in; out) mul!(C::AbstractMatrix, A::Diagonal, B::Adjoint{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) mul!(C::AbstractMatrix, A::Diagonal, B::Transpose{<:Any,<:AbstractVecOrMat}) = mul!(C, A, copy(B)) @@ -292,8 +292,10 @@ mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:Abs *(adjD::Adjoint{<:Any,<:Diagonal}, adjA::Adjoint{<:Any,<:RealHermSymComplexHerm}) = adjD * adjA.parent mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexHerm}) = mul!(C, A, B.parent) mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexSym}) = mul!(C, A, B.parent) -mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexSym}) = C .= adjoint.(A.parent.diag) .* B -mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexHerm}) = C .= transpose.(A.parent.diag) .* B +mul!(C::AbstractMatrix, A::Adjoint{<:Any,<:Diagonal}, B::Adjoint{<:Any,<:RealHermSymComplexSym}) = + (C .= adjoint.(A.parent.diag) .* B; C) +mul!(C::AbstractMatrix, A::Transpose{<:Any,<:Diagonal}, B::Transpose{<:Any,<:RealHermSymComplexHerm}) = + (C .= transpose.(A.parent.diag) .* B; C) (/)(Da::Diagonal, Db::Diagonal) = Diagonal(Da.diag ./ Db.diag) diff --git a/test/broadcast.jl b/test/broadcast.jl index c3f5c8be4f81d..e1e4a0690f3a3 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -553,10 +553,11 @@ end # Test that broadcasting identity where the input and output Array shapes do not match # yields the correct result, not merely a partial copy. See pull request #19895 for discussion. let N = 5 - @test iszero(fill(1, N, N) .= zeros(N, N)) - @test iszero(fill(1, N, N) .= zeros(N, 1)) - @test iszero(fill(1, N, N) .= zeros(1, N)) - @test iszero(fill(1, N, N) .= zeros(1, 1)) + for rhs in (zeros(N, N), zeros(N, 1), zeros(1, N), zeros(1, 1)) + local o = fill(1, N, N) + o .= rhs + @test iszero(o) + end end @testset "test broadcast for matrix of matrices" begin @@ -612,3 +613,16 @@ let n = 1 @test ceil.(Int, n ./ (1,)) == (1,) @test ceil.(Int, 1 ./ (1,)) == (1,) end + +# issue #25954, value of `.=` +# TODO: use these if we want `.=` to return its RHS +#let a = zeros(2, 3), b = zeros(4, 5) +# a .= b .= 1 +# @test a == ones(2, 3) +# @test b == ones(4, 5) +# @test (b .= 1) === 1 +# c = [6, 7]; d = [8, 9] +# x = (a .= c.+d) +# @test a == [14 14 14; 16 16 16] +# @test x == [14, 16] +#end