diff --git a/src/projection.jl b/src/projection.jl index be8268b8a..13d472879 100644 --- a/src/projection.jl +++ b/src/projection.jl @@ -223,6 +223,10 @@ function (project::ProjectTo{AbstractArray})(dx::AbstractArray{S,M}) where {S,M} # like dx = ones(4,1), where x = ones(4), but throw an error on dx = ones(1,4) etc. dy = if axes(dx) === project.axes dx + elseif project.axes isa Tuple{Vararg{Base.OneTo}} && axes(dx) isa typeof(project.axes) + # Same number of `OneTo` axes that are not identical: the sizes differ. Resolved from + # the types alone, so inference does not see the type-unstable `reshape` below. + throw(_projection_mismatch(project.axes, size(dx))) else for d in 1:max(M, length(project.axes)) if size(dx, d) != length(get(project.axes, d, 1)) diff --git a/test/projection.jl b/test/projection.jl index cf4ac3b17..2445b79bd 100644 --- a/test/projection.jl +++ b/test/projection.jl @@ -457,11 +457,16 @@ struct NoSuperType end @test 0 == @ballocated $pdiag(dx) setup = (dx = Diagonal(rand(10^3))) psymm = ProjectTo(Symmetric(rand(10^3, 10^3))) - # The Union{Symmetric{…,Matrix}, Symmetric{…,ReshapedArray}} return value is only - # unboxed since JuliaLang/julia#55045 (sret_union ABI for types containing pointers) - @test 0 == @ballocated($psymm(dx), setup = (dx = Symmetric(rand(10^3, 10^3)))) broken = ( - VERSION < v"1.14.0-DEV.1348" - ) + @test 0 == @ballocated $psymm(dx) setup = (dx = Symmetric(rand(10^3, 10^3))) + end + + @testset "#407" begin + @test @inferred(ProjectTo(rand(3, 3))(Diagonal(rand(3)))) isa Diagonal{Float64} + pupp = ProjectTo(UpperTriangular(rand(3, 3))) + @test @inferred(pupp(UpperTriangular(rand(3, 3)))) isa UpperTriangular{Float64} + psymm = ProjectTo(Symmetric(rand(3, 3))) + @test @inferred(psymm(Symmetric(rand(3, 3)))) isa Symmetric{Float64} + @test_throws DimensionMismatch ProjectTo(rand(3, 3))(Diagonal(rand(2))) end @testset "#685" begin