diff --git a/base/range.jl b/base/range.jl index f2f3e26edf2f2..3bd5ffe55455a 100644 --- a/base/range.jl +++ b/base/range.jl @@ -1125,19 +1125,23 @@ function show(io::IO, r::StepRangeLen) end function ==(r::T, s::T) where {T<:AbstractRange} + isequal(firstindex(r), firstindex(s)) || return false isempty(r) && return isempty(s) _has_length_one(r) && return _has_length_one(s) & (first(r) == first(s)) (first(r) == first(s)) & (step(r) == step(s)) & (last(r) == last(s)) end function ==(r::OrdinalRange, s::OrdinalRange) + isequal(firstindex(r), firstindex(s)) || return false isempty(r) && return isempty(s) _has_length_one(r) && return _has_length_one(s) & (first(r) == first(s)) (first(r) == first(s)) & (step(r) == step(s)) & (last(r) == last(s)) end -==(r::AbstractUnitRange, s::AbstractUnitRange) = - (isempty(r) & isempty(s)) | ((first(r) == first(s)) & (last(r) == last(s))) +function ==(r::AbstractUnitRange, s::AbstractUnitRange) + isequal(firstindex(r), firstindex(s)) || return false + return (isempty(r) & isempty(s)) | ((first(r) == first(s)) & (last(r) == last(s))) +end ==(r::OneTo, s::OneTo) = last(r) == last(s) @@ -1154,6 +1158,7 @@ _has_length_one(r::OrdinalRange) = first(r) == last(r) _has_length_one(r::AbstractRange) = isone(length(r)) function ==(r::AbstractRange, s::AbstractRange) + isequal(firstindex(r), firstindex(s)) || return false lr = length(r) if lr != length(s) return false diff --git a/test/ranges.jl b/test/ranges.jl index 9bad12e6692d2..de2f053120ada 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -1147,6 +1147,28 @@ end @test (r==s) == (ar==as) end end + + struct WrapRange{T} <: AbstractRange{T} r::AbstractRange{T} end + Base.firstindex(w::WrapRange) = firstindex(w.r) + Base.isempty(w::WrapRange) = isempty(w.r) + Base.first(w::WrapRange) = first(w.r) + Base.last(w::WrapRange) = last(w.r) + Base.step(w::WrapRange) = step(w.r) + Base.length(w::WrapRange) = length(w.r) + @testset "empty offset ranges" begin + r1 = Base.IdentityUnitRange(2:1) + r2 = Base.IdentityUnitRange(3:2) + r3 = OffsetArrays.IdOffsetRange(1:0, -1) + r4 = OffsetArrays.IdOffsetRange(1:0, -2) + range_list = AbstractRange[r1, r2, r3, r4] + append!(range_list, map(WrapRange, range_list)) + for (a, b) in Iterators.product(range_list, range_list) + @test r1 != r2 + @test !(@invoke ==(r1::AbstractUnitRange, r2::AbstractUnitRange)) + @test !(@invoke ==(r1::OrdinalRange, r2::OrdinalRange)) + @test !(@invoke ==(r1::AbstractRange, r2::AbstractRange)) + end + end end @testset "comparing UnitRanges and OneTo" begin