Why does stateful iterators restrict length to `Signed`?

Iterators.Stateful has the definition

mutable struct Stateful{T, VS, N<:Integer}
    itr::T
    # A bit awkward right now, but adapted to the new iteration protocol
    nextvalstate::Union{VS, Nothing}

    # Number of remaining elements, if itr is HasLength or HasShape.
    # if not, store -1 - number_of_consumed_elements.
    # This allows us to defer calculating length until asked for.
    # See PR #45924
    remaining::N
    @inline function Stateful{<:Any, Any}(itr::T) where {T}
        itl = iterlength(itr)
        new{T, Any, typeof(itl)}(itr, iterate(itr), itl)
    end
    @inline function Stateful(itr::T) where {T}
        VS = approx_iter_type(T)
        itl = iterlength(itr)
        return new{T, VS, typeof(itl)}(itr, iterate(itr)::VS, itl)
    end
end

In the constructor, it calls

function iterlength(it)::Signed
    if IteratorSize(it) isa Union{HasShape, HasLength}
       return length(it)
    else
        -1
    end
end

but what’s the point of this Signed restriction? Subtypes of Integer that aren’t subtypes of Signed are ruled out as the length. For example, this doesn’t work:

julia> using Infinities

julia> x = 1:∞
1:∞

julia> Iterators.Stateful(axes(x,1))
ERROR: MethodError: no method matching Signed(::InfiniteCardinal{0})

Closest candidates are:
  (::Type{T})(::T) where T<:Number
   @ Core boot.jl:792
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
   @ Base char.jl:50
  (::Type{T})(::Base.TwicePrecision) where T<:Number
   @ Base twiceprecision.jl:266
  ...

Stacktrace:
 [1] convert(#unused#::Type{Signed}, x::InfiniteCardinal{0})
   @ Base ./number.jl:7
 [2] iterlength(it::InfiniteArrays.OneToInf{Int64})
   @ Base.Iterators ./iterators.jl:1413
 [3] Base.Iterators.Stateful(itr::InfiniteArrays.OneToInf{Int64})
   @ Base.Iterators ./iterators.jl:1406
 [4] top-level scope
   @ REPL[47]:1

The fact that this is infinite is a red herring, as this would rule out static integers and such as well.

That’s an assertion, declaring something about a value, not a type restriction for method signatures.

As for the branch you pasted above, note that the iteration interface distinguishes finite and infinite iterators (and those with unknown length). For Union{HasShape, HasLength}, the length should really be finite.

I understand that it’s a conversion, which will fail in general for subtypes of Integer that don’t define a method for Signed. Also, I was merely looking for an example of an Integer that isn’t a subtype of Signed and can’t be converted to one. This doesn’t need to be infinite, as in the example.