Preventing type instability from union nothing

I’m trying to understand parametric types and parametric methods with a simple example.
I have some discrete data w with some metadata t.
All I want to show is how many times different metadata values pop up for various values of w.

struct myunit{W<:Integer,T<:Integer}
  w::W
  t::T
end

function getNWK(d::AbstractArray{T},l::AbstractArray{U},k::Integer) where {T<:myunit,U<:Integer}
  nwk = zeros(k,length(l))
  for i in 1:length(d)
    nwk[d[i].t,d[i].w] += 1
  end
  nwk
end

@code_warntype
l = [1:100;]
x = rand(1:100,1000)
y = rand(1:3,1000)
arr = myunit.(x,y)
@code_warntype getNWK(arr,l)

Variables
  #self#::Core.Compiler.Const(getNWK, false)
  d::Array{myunit{Int64,Int64},1}
  l::Array{Int64,1}
  nwk::Array{Float64,1}
  @_5::Union{Nothing, Tuple{Int64,Int64}}
  i::Int64

Body::Array{Float64,1}
1 ─ %1  = Main.length(l)::Int64
β”‚         (nwk = Main.zeros(%1))
β”‚   %3  = Main.length(d)::Int64
β”‚   %4  = (1:%3)::Core.Compiler.PartialStruct(UnitRange{Int64}, Any[Core.Compiler.Const(1, false), Int64])
β”‚         (@_5 = Base.iterate(%4))
β”‚   %6  = (@_5 === nothing)::Bool
β”‚   %7  = Base.not_int(%6)::Bool
└──       goto #4 if not %7
2 β”„ %9  = @_5::Tuple{Int64,Int64}::Tuple{Int64,Int64}
β”‚         (i = Core.getfield(%9, 1))
β”‚   %11 = Core.getfield(%9, 2)::Int64
β”‚   %12 = Base.getindex(d, i)::myunit{Int64,Int64}
β”‚   %13 = Base.getproperty(%12, :t)::Int64
β”‚   %14 = Base.getindex(d, i)::myunit{Int64,Int64}
β”‚   %15 = Base.getproperty(%14, :w)::Int64
β”‚   %16 = Base.getindex(nwk, %13, %15)::Float64
β”‚   %17 = (%16 + 1)::Float64
β”‚         Base.setindex!(nwk, %17, %13, %15)
β”‚         (@_5 = Base.iterate(%4, %11))
β”‚   %20 = (@_5 === nothing)::Bool
β”‚   %21 = Base.not_int(%20)::Bool
└──       goto #4 if not %21
3 ─       goto #2
4 β”„       return nwk

Line 5 of the @code_warntype output was highlighted in yellow:

  @_5::Union{Nothing, Tuple{Int64,Int64}}

I’m still getting the hang of @code_warntype but it appears to be concerned that if k is 0 then the output array will have no rows, how do I tell the compiler that this will never happen?

The compiler splits unions of two so it’s perfect fine. That comes from the iterator.

4 Likes

perfect, thanks!