Skip to content

Commit da437a4

Browse files
authored
Make unitrange_last not assume non-throwing behavior on subtraction, fixes #42528 (#42603)
This also fixes the behavior for unconstrained ranges. Co-authored-by: Sukera <[email protected]>
1 parent 0bc3d17 commit da437a4

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

base/range.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,10 +394,10 @@ UnitRange(start::T, stop::T) where {T<:Real} = UnitRange{T}(start, stop)
394394

395395
unitrange_last(::Bool, stop::Bool) = stop
396396
unitrange_last(start::T, stop::T) where {T<:Integer} =
397-
ifelse(stop >= start, stop, convert(T,start-oneunit(stop-start)))
397+
stop >= start ? stop : convert(T,start-oneunit(stop-start))
398398
unitrange_last(start::T, stop::T) where {T} =
399-
ifelse(stop >= start, convert(T,start+floor(stop-start)),
400-
convert(T,start-oneunit(stop-start)))
399+
stop >= start ? convert(T,start+floor(stop-start)) :
400+
convert(T,start-oneunit(stop-start))
401401

402402
unitrange(x) = UnitRange(x)
403403

test/ranges.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,3 +2186,23 @@ end
21862186
@test ((x - 1) in StepRangeLen(x, 0, rand(1:100))) == false
21872187
@test ((x + 1) in StepRangeLen(x, 0, rand(1:100))) == false
21882188
end
2189+
2190+
@testset "issue #42528" begin
2191+
struct Fix42528 <: Unsigned
2192+
val::UInt
2193+
end
2194+
Fix42528(a::Fix42528) = a
2195+
Base.:(<)(a::Fix42528, b::Fix42528) = a.val < b.val
2196+
Base.:(>=)(a::Fix42528, b::Fix42528) = a.val >= b.val
2197+
Base.:(+)(a::Fix42528, b::Fix42528) = a.val+b.val
2198+
Base.promote_rule(::Type{Fix42528}, ::Type{<:Unsigned}) = Fix42528
2199+
Base.show(io::IO, ::MIME"text/plain", a::Fix42528) = print(io, "Fix42528(", a.val, ')')
2200+
Base.show(io::IO, a::Fix42528) = print(io, "Fix42528(", a.val, ')')
2201+
function Base.:(-)(a::Fix42528, b::Fix42528)
2202+
a.val < b.val && throw(DomainError("Can't subtract, result outside of domain"))
2203+
return a.val - b.val
2204+
end
2205+
Base.one(::Type{Fix42528}) = Fix42528(0x1)
2206+
@test Fix42528(0x0):Fix42528(0x1) == [Fix42528(0x0), Fix42528(0x01)]
2207+
@test_throws DomainError Fix42528(0x0) - Fix42528(0x1)
2208+
end

0 commit comments

Comments
 (0)