Compiler issue with non-existent NIL conditions

There is a bug, or an improvement, depending on how you want to see it.

This:

def foo
  (2..).each do |x|
    return 1
  end
end

typeof(foo) # => Int32 | Nil

The bug is that for a loop that never ends, the compiler think it ends, then we get Nil in the type.

The compiler knows (2..).each { ... } will never end. It can even know that at compile time (the E in Range(B, E) is Nil, there are already some checks around that). If there’s no end, we can generate while true as a loop. Then the compiler knows the loop never ends. Then the type of foo becomes Int32.

Just replace std code with my code here and you’ll see that the code from @jzakiya start to compile without modifications: Compiler issue with non-existent NIL conditions

Maybe a bug, maybe a feature request, I don’t know. Something can be done to improve the situation.