Skip to content

Commit 60b0ce1

Browse files
committed
Fix StackOverflowError when left and right do not promote to common type
This was adopted from AxisArrays
1 parent 5da8cf9 commit 60b0ce1

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/IntervalSets.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@ include("closed.jl")
1313
ordered{T}(a::T, b::T) = ifelse(a < b, (a, b), (b, a))
1414
ordered(a, b) = ordered(promote(a, b)...)
1515

16+
checked_conversion{T}(::Type{T}, a, b) = _checked_conversion(T, convert(T, a), convert(T, b))
17+
_checked_conversion{T}(::Type{T}, a::T, b::T) = a, b
18+
_checked_conversion{T}(::Type{T}, a, b) = throw(ArgumentError("$a and $b are not both of type $T"))
19+
1620
end # module

src/closed.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,20 @@ mathematical notation, the constructed range is `[left, right]`.
55
immutable ClosedInterval{T}
66
left::T
77
right::T
8+
9+
ClosedInterval(l::T, r::T) = new(l, r)
810
end
911

10-
ClosedInterval(left, right) = ClosedInterval(promote(left, right)...)
12+
ClosedInterval{T}(left::T, right::T) = ClosedInterval{T}(left, right)
13+
(::Type{ClosedInterval{T}}){T}(left, right) =
14+
ClosedInterval{T}(checked_conversion(T, left, right)...)
15+
16+
function ClosedInterval(left, right)
17+
# Defining this as ClosedInterval(promote(left, right)...) has one problem:
18+
# if left and right do not promote to a common type, it triggers a StackOverflow.
19+
T = promote_type(typeof(left), typeof(right))
20+
ClosedInterval{T}(checked_conversion(T, left, right)...)
21+
end
1122

1223
..(x, y) = ClosedInterval(x, y)
1324

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ using Base.Test
88
@test ordered(Float16(1), 2) == (1, 2)
99

1010
@testset "Closed Sets" begin
11+
@test_throws ArgumentError :a .. "b"
1112
I = 0..3
1213
print(io, I)
1314
@test String(io) == "0..3"

0 commit comments

Comments
 (0)