Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions tslang/lib/TypeScript/MLIRGenImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3307,6 +3307,16 @@ class MLIRGenImpl
else
{
if (inverse) return mlir::failure();

// `typeof x === "function"` (also "class", "interface", "object") names no type, only Opaque.
// The type x already has is more precise: casting would lose it - a function could no longer
// be called in the branch - and for a generic function nobody instantiated it references a
// function that is never emitted.
if (isa<mlir_ts::OpaqueType>(safeType))
{
return mlir::success();
}

CAST_A(result, location, safeType, exprValue, genContext);
castedValue = V(result);
}
Expand Down
3 changes: 3 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ add_test(NAME test-compile-00-funcs-nesting-generic COMMAND test-runner "${PROJE
add_test(NAME test-compile-00-funcs-nesting-capture COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00funcs_nesting_capture.ts")
add_test(NAME test-compile-00-funcs-hybrid-null-this COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00funcs_hybrid_null_this.ts")
add_test(NAME test-compile-00-typeof-static-fold COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00typeof_static_fold.ts")
add_test(NAME test-compile-00-typeof-function-narrowing COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00typeof_function_narrowing.ts")
add_test(NAME test-compile-00-typeof-static-fold-conditions COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00typeof_static_fold_conditions.ts")
add_test(NAME test-compile-00-array-move-wide-elements COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_move_wide_elements.ts")
add_test(NAME test-compile-00-funcs-expression-generic COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00funcs_expression_generic.ts")
Expand Down Expand Up @@ -589,6 +590,7 @@ add_test(NAME test-jit-00-funcs-nesting-generic COMMAND test-runner -jit "${PROJ
add_test(NAME test-jit-00-funcs-nesting-capture COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00funcs_nesting_capture.ts")
add_test(NAME test-jit-00-funcs-hybrid-null-this COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00funcs_hybrid_null_this.ts")
add_test(NAME test-jit-00-typeof-static-fold COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00typeof_static_fold.ts")
add_test(NAME test-jit-00-typeof-function-narrowing COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00typeof_function_narrowing.ts")
add_test(NAME test-jit-00-typeof-static-fold-conditions COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00typeof_static_fold_conditions.ts")
add_test(NAME test-jit-00-array-move-wide-elements COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00array_move_wide_elements.ts")
add_test(NAME test-jit-00-funcs-expression-generic COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00funcs_expression_generic.ts")
Expand Down Expand Up @@ -1576,6 +1578,7 @@ set(TSLANG_CORPUS
00type_aliases_in_generics.ts
00type_guard_function.ts
00typed_array.ts
00typeof_function_narrowing.ts
00typeof_static_fold.ts
00typeof_static_fold_conditions.ts
00types_indexedaccesstype.ts
Expand Down
41 changes: 41 additions & 0 deletions tslang/test/tester/tests/00typeof_function_narrowing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// `typeof f === "function"` names no type of its own, only Opaque. A value whose type is known is
// not narrowed to it: that lost the function type, so the function could not be called in the
// branch, and for a generic function nobody instantiated it referenced a function never emitted.
function one() {
return 1;
}

function id<T>(x: T) {
return x;
}

function main() {
let calls = 0;

if (typeof one === "function") {
assert(one() == 1, "plain function is still callable");
calls++;
}

if (typeof id === "function") {
calls++;
}

if (typeof id === "function") {
assert(id(2) == 2, "generic function is still callable");
calls++;
}

const f = () => 3;
assert(typeof f === "function" ? f() == 3 : false, "arrow function in ?:");

// `any` is still narrowed at run time
let a: any = one;
if (typeof a === "function") {
calls++;
}

assert(calls == 4, "every branch ran");

print("done.");
}
Loading