-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
Split from #58846; I think it's putatively a bug that we're not doing this. Constructing such a range violates so many assumptions of AbstractRange
that they are quite the broken object. It feels like it should be possible to detect such a thing, but I don't know that it is (without demanding some new method implementations).
The biggest problem is that the constructor is not constrained by any particular types beyond len::Integer
.
In fact, all we know is that the all currently constructable StepRangeLen(ref::T, step::S, len::Integer)
s have types that support:
*(::S, ::Integer)::R1
+(::T, ::R1)::R2
T(::R2)
(although perhaps this should beconvert(::Type{T}, ::R2)
)
That's... it. If you do subsequent arithmetic on the range itself there are a few other conversions and arithmetic, but those aren't obvious to exercise. The above is all you need to construct, index, and collect... and that's all that underpins a lot of the high-level functionality that can go sideways (like extrema
, for example).
If we define that T(::R2)
constructor for Time
(as in #58846), the StepRangeLen(::Time, ::Hour, ::Integer)
becomes quite the adversarial case:
julia> using Dates
julia> @eval Dates Time(t::Time) = t
Time
julia> StepRangeLen(Time(0), Hour(13), 4)
Time(0):Hour(13):Time(15)
julia> println(collect(range(Time(0), step=Hour(13), length=4)))
Time[Time(0), Time(13), Time(2), Time(15)]
julia> Hour(13)*3
39 hours
julia> Time(0) + Hour(39)
15:00:00
I have absolutely no idea how we could ever generically detect this — even if we assumed the availability of more arithmetic or comparisons or typemax
— unless we iterate the entire range upon construction to demand monotonicity.
We could require these types implement Base.Checked
arithmetic, but I'm quite certain that would be highly breaking for existing non-broken functionality in packages like Mods
and Furlongs
and Unitful
. Or we could alternatively take a tiered strategy:
- We know that all the builtin integers can use
Checked.mul_with_overflow
andChecked.add_with_overflow
- We know that all AbstractFloats won't wrap around (but there are indeed many other potential problems there)
- Some
::Number
s can usewiden
(Unitful does define this, butFurlongs
andMods
do not) - Everything else? Perhaps demand
Checked
arithmetic? Or just do a best-effort thing?