All of the expressions at the top should return true, and the NoReturn at the bottom should be B(Int32) since it simply swaps the order of the operands to && compared to the typeof immediately below:
class A; end
class B(T) < A; end
x = B(Int32).new.as(A)
x.is_a?(B ) && x.is_a?(B ) # => false
x.is_a?(B ) && x.is_a?(B(Int32)) # => false
x.is_a?(B(Int32)) && x.is_a?(B ) # => true
x.is_a?(B(Int32)) && x.is_a?(B(Int32)) # => true
typeof(x.is_a?(B ) && x.is_a?(B ) ? x : raise "") # => B(T)
typeof(x.is_a?(B ) && x.is_a?(B(Int32)) ? x : raise "") # => NoReturn
typeof(x.is_a?(B(Int32)) && x.is_a?(B ) ? x : raise "") # => B(Int32)
typeof(x.is_a?(B(Int32)) && x.is_a?(B(Int32)) ? x : raise "") # => B(Int32)
All the failures occur when x.is_a?(B) is used, which constrains the type of the x after the && to B(T).
All of the expressions at the top should return
true, and theNoReturnat the bottom should beB(Int32)since it simply swaps the order of the operands to&&compared to thetypeofimmediately below:All the failures occur when
x.is_a?(B)is used, which constrains the type of thexafter the&&toB(T).