diff --git a/base/subarray.jl b/base/subarray.jl index e9660b9dee639..656628bb40382 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -115,11 +115,14 @@ function unaliascopy(V::SubArray{T,N,A,I,LD}) where {T,N,A<:Array,I<:Tuple{Varar trimmedpind = _trimmedpind(V.indices...) vdest = trimmedpind isa Tuple{Vararg{Union{Slice,Colon}}} ? dest : view(dest, trimmedpind...) copyto!(vdest, view(V, _trimmedvind(V.indices...)...)) - SubArray{T,N,A,I,LD}(dest, map(_trimmedindex, V.indices), 0, Int(LD)) + indices = map(_trimmedindex, V.indices) + stride1 = LD ? compute_stride1(dest, indices) : 0 + offset1 = LD ? compute_offset1(dest, stride1, indices) : 0 + SubArray{T,N,A,I,LD}(dest, indices, offset1, stride1) end # Get the proper trimmed shape _trimmedshape(::ScalarIndex, rest...) = (1, _trimmedshape(rest...)...) -_trimmedshape(i::AbstractRange, rest...) = (maximum(i), _trimmedshape(rest...)...) +_trimmedshape(i::AbstractRange, rest...) = (isempty(i) ? zero(eltype(i)) : maximum(i), _trimmedshape(rest...)...) _trimmedshape(i::Union{UnitRange,StepRange,OneTo}, rest...) = (length(i), _trimmedshape(rest...)...) _trimmedshape(i::AbstractArray{<:ScalarIndex}, rest...) = (length(i), _trimmedshape(rest...)...) _trimmedshape(i::AbstractArray{<:AbstractCartesianIndex{0}}, rest...) = _trimmedshape(rest...) diff --git a/test/subarray.jl b/test/subarray.jl index eedf28539d72b..0c29c6a784efd 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -827,6 +827,25 @@ end @test @inferred(Base.unaliascopy(V))::typeof(V) == V == A[i1, 1:5, i2, i3] V = view(A, i1, 1:5, i3, i2) @test @inferred(Base.unaliascopy(V))::typeof(V) == V == A[i1, 1:5, i3, i2] + + @testset "custom ranges" begin + struct MyStepRange{T} <: OrdinalRange{T,T} + r::StepRange{T,T} + end + + for f in (:first, :last, :step, :length, :size) + @eval Base.$f(r::MyStepRange) = $f(r.r) + end + Base.getindex(r::MyStepRange, i::Int) = r.r[i] + + a = rand(6) + V = view(a, MyStepRange(2:2:4)) + @test @inferred(Base.unaliascopy(V))::typeof(V) == V + + # empty range + V = view(a, MyStepRange(2:2:1)) + @test @inferred(Base.unaliascopy(V))::typeof(V) == V + end end @testset "issue #27632" begin