diff --git a/tslang/lib/TypeScript/MLIRGenImpl.h b/tslang/lib/TypeScript/MLIRGenImpl.h index b62a7b92e..d1100f5e8 100644 --- a/tslang/lib/TypeScript/MLIRGenImpl.h +++ b/tslang/lib/TypeScript/MLIRGenImpl.h @@ -4615,6 +4615,26 @@ class MLIRGenImpl EXIT_IF_FAILED_OR_NO_VALUE(result) caseValue = V(result); + // a case of another kind of primitive than the switch's (`switch (5) { case "a": }`) + // can never match: the cast made one out of the other instead + auto primitiveKind = [&](mlir::Type type) { + auto baseType = mth.getBaseType(type); + if (mth.isNumericType(baseType)) return 1; + if (isa(baseType)) return 2; + if (isa(baseType)) return 3; + if (isa(baseType)) return 4; + return 0; + }; + + auto switchKind = primitiveKind(switchValue.getType()); + auto caseKind = primitiveKind(caseValue.getType()); + if (switchKind && caseKind && switchKind != caseKind) + { + emitError(loc(caseExpr)) << "Type '" << to_print(caseValue.getType()) << "' is not comparable to type '" + << to_print(switchValue.getType()) << "'"; + return mlir::failure(); + } + auto switchValueEffective = switchValue; auto actualCaseType = mth.stripLiteralType(caseValue.getType()); if (switchValue.getType() != actualCaseType) diff --git a/tslang/test/tester/CMakeLists.txt b/tslang/test/tester/CMakeLists.txt index e92db2eb9..c8ad23e39 100644 --- a/tslang/test/tester/CMakeLists.txt +++ b/tslang/test/tester/CMakeLists.txt @@ -2719,6 +2719,16 @@ add_test(NAME test-compile-integer-literal-truncation-quiet set_tests_properties(test-compile-integer-literal-truncation-quiet PROPERTIES FAIL_REGULAR_EXPRESSION "warning:|error:|Stack dump|Assertion failed") +# A switch's case of another kind of primitive (a string for a number) is an error, as it can never +# match: the switch's value was cast to the case's type instead. +add_test(NAME test-compile-diagnostic-location-switch-case-type + COMMAND $ --emit=obj --no-default-lib -mm=none + "${PROJECT_SOURCE_DIR}/test/tester/diagnostic-location/switch_case_type.ts" + -o "${CMAKE_CURRENT_BINARY_DIR}/diagnostic-location-switch-case-type.obj") +set_tests_properties(test-compile-diagnostic-location-switch-case-type + PROPERTIES PASS_REGULAR_EXPRESSION "switch_case_type\\.ts:8:14: error: Type '\"a\"' is not comparable to type '5'" + FAIL_REGULAR_EXPRESSION "Stack dump|Assertion failed|switch_case_type\\.ts:7:") + # A store to an indexed Ref (`bytes[i] = x`) names the form that stores, `Deref(bytes[i]) = x`, # instead of "saving to constant object". add_test(NAME test-compile-ref-index-store diff --git a/tslang/test/tester/diagnostic-location/switch_case_type.ts b/tslang/test/tester/diagnostic-location/switch_case_type.ts new file mode 100644 index 000000000..70ec7dfc3 --- /dev/null +++ b/tslang/test/tester/diagnostic-location/switch_case_type.ts @@ -0,0 +1,10 @@ +// A case of another kind of primitive than the switch's could never match: the number was made +// a string to compare, with no error. + +function main() { + const n = 5; + switch (n) { + case 5: print("five"); break; + case "a": print("a"); break; + } +}