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
11 changes: 10 additions & 1 deletion tslang/lib/TypeScript/MLIRGenImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10010,7 +10010,16 @@ class MLIRGenImpl
if (type != receiverElementType)
{
value = builder.getUnitAttr();
itemValue = cast(location, receiverElementType, itemValue, genContext);
// a field that cannot be the receiver's (`kind: "ci"` for a `kind: "sq"`) is an error: its
// failed cast was a null value, the literal came out with no value at all, and an assignment
// of it stored nothing - with the cast's error postponed, and so never shown (#513)
auto castResult = cast(location, receiverElementType, itemValue, genContext);
if (castResult.failed_or_no_value())
{
return mlir::failure();
}

itemValue = V(castResult);
isConstValue = false;
}

Expand Down
15 changes: 15 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2608,6 +2608,21 @@ endforeach()
tslang_add_test(NAME test-jit-type-alias-not-circular COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/type-alias-circular/positive.ts")
tslang_add_test(NAME test-compile-type-alias-not-circular COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/type-alias-circular/positive.ts")

# An object literal with a field the receiver's type cannot hold (`kind: "ci"` for `kind: "sq"`) is an
# error (issue #513). The field's failed cast was dropped: the literal had no value, an assignment of it
# stored nothing, and the cast's error, postponed like every message, was never shown.
foreach(literal_field_mismatch_name assign declare argument return)
add_test(NAME test-compile-literal-field-mismatch-${literal_field_mismatch_name}
COMMAND $<TARGET_FILE:tslang> --emit=obj --no-default-lib -mm=none
"${PROJECT_SOURCE_DIR}/test/tester/literal-field-mismatch/${literal_field_mismatch_name}.ts"
-o "${CMAKE_CURRENT_BINARY_DIR}/literal-field-mismatch-${literal_field_mismatch_name}.obj")
set_tests_properties(test-compile-literal-field-mismatch-${literal_field_mismatch_name}
PROPERTIES PASS_REGULAR_EXPRESSION "can't cast from literal type: '\"ci\"' to '\"sq\"'"
FAIL_REGULAR_EXPRESSION "Expected 1 arguments|Stack dump|Assertion failed")
endforeach()
tslang_add_test(NAME test-jit-literal-field-match COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/literal-field-mismatch/positive.ts")
tslang_add_test(NAME test-compile-literal-field-match COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/literal-field-mismatch/positive.ts")

# An error reported by a pass that still returns success - a lowering pattern that cannot build a
# value, says so and carries on - fails the compile. It used to be printed and then ignored: the object
# file was written, and under --emit=jit the program ran and crashed. Two tests because one
Expand Down
10 changes: 10 additions & 0 deletions tslang/test/tester/literal-field-mismatch/argument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// reported "Expected 1 arguments, but got 0"
type Sq = { kind: "sq"; side: number };

function f(s: Sq) {
return s.kind;
}

function main() {
print(f({ kind: "ci", r: 1 }));
}
8 changes: 8 additions & 0 deletions tslang/test/tester/literal-field-mismatch/assign.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// #513: compiled with no error, and `s` kept "sq"
type Sq = { kind: "sq"; side: number };

function main() {
let s: Sq = { kind: "sq", side: 4 };
s = { kind: "ci", r: 1 };
print(s.kind, s.side);
}
7 changes: 7 additions & 0 deletions tslang/test/tester/literal-field-mismatch/declare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// compiled with no error, and `t` held garbage
type Sq = { kind: "sq"; side: number };

function main() {
let t: Sq = { kind: "ci", r: 1 };
print(t.kind);
}
26 changes: 26 additions & 0 deletions tslang/test/tester/literal-field-mismatch/positive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// literals that are the receiver's type still assign, declare, pass and return
type Sq = { kind: "sq"; side: number };
type Ci = { kind: "ci"; r: number };

function f(s: Sq) {
return s.side;
}

function g(): Sq {
return { kind: "sq", side: 3 };
}

function main() {
let u: Sq | Ci = { kind: "ci", r: 1 };
assert(u.kind == "ci", "union, declared");
u = { kind: "sq", side: 2 };
assert(u.kind == "sq", "union, assigned");

let s: Sq = { kind: "sq", side: 4 };
s = { kind: "sq", side: 6 };
assert(s.side == 6, "assigned");
assert(f({ kind: "sq", side: 5 }) == 5, "argument");
assert(g().side == 3, "returned");

print("done.");
}
10 changes: 10 additions & 0 deletions tslang/test/tester/literal-field-mismatch/return.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// a returned literal of the other member
type Sq = { kind: "sq"; side: number };

function g(): Sq {
return { kind: "ci", r: 1 };
}

function main() {
print(g().kind);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// @strict-null false
// `left: null` for a Point: null is not a Point under strict null checks
namespace A {

class Point {
Expand Down
Loading