You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
instanceof is always false for a class value held in a union or an optional #450
x instanceof C is false whenever x is typed as a union or an optional that holds a class, even when it holds a C, and even after narrowing. Every memory model (gc, rc, none), JIT and AOT, with and without --opt.
C: true
C | D: false
C | null: false
C | null, narrowed: false
C | number: false
Expected true on every line.
Cause
mlirGenInstanceOfLogic (tslang/lib/TypeScript/MLIRGenImpl.h) dispatches on the left operand's type: a class calls .instanceOf with the RTTI, any checks typeof and goes through the vtable, and opaque and interface values have paths of their own. A union or an optional matches none of them and falls through to the "default logic", which emits a compile-time constant leftType == rightType. That is false for union<C, null> against C. The MLIR shows "ts.Constant"() <{value = false}> where the test should be. Narrowing with if (e) doesn't change the type the expression is generated with, so the narrowed case folds the same way.
A fix would handle a union or optional on the left at run time: for an optional, test HasValue and run the class path on the value; for a union, run it on each class member's payload, selected by the union's type tag. Non-class members (null, number) give false.
Found while writing -mm=own phase 6 tests (#449); own_declared_constant.ts tests its union value with typeof instead.
Activity
instanceof asks a union or an optional that may hold a class at run t…