Repository navigation
A number, string, boolean or array is not an interface with members - #543
Merged
Merged
Conversation
Passed where an interface with members is expected, such a value compiled without a word: castToInterfaceSpecialCases had no case for it, so it became a plain cast that lowering could not make (at most a "<unknown>:0: warning: invalid cast"), and the callee read garbage. It is now an error naming the type and the interface. An interface without members still takes any value, as in TypeScript. Found by docs/bugs/array_of_ifaces_cast.ts, whose intended error (IStateToken[] passed for an IState) was never reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e-cast-check # Conflicts: # tslang/test/tester/CMakeLists.txt
ASDAlexander77
added a commit
that referenced
this pull request
Oct 12, 2026
…558) Every repro in docs/bugs passes on main, or fails as TypeScript does: the native_ts_graphics findings were fixed by #535-#544 and #549 (the `let s = 0` one by design, with a warning since #544), testFallThrough, generic_in_generic and array_of_ifaces_cast by #538, #542 and #543, and bug14 and bug21 aren't valid TypeScript. Each fix has its regression test in tslang/test/tester, and the findings document is in the history and in those PRs, so the folder goes. Its interop notes stay, in docs/c-cpp-header-import.md: a `string` returned by a C function is its `char*`, not a copy; `number` is a `double`; and a nullable `Ref<T>` field is spelled `Ref<T> | null`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A value that can't be an interface, i.e. a number, string, boolean or array, compiled without any error when passed where an interface with members is expected:
TypeScript rejects all of these.
docs/bugs/array_of_ifaces_cast.tsexists for this case: it says that passingIStateToken[]for an interface parameter "should produce an error". tslang never reported it. That file fails earlier on unrelated errors, but a cleaned-up version compiled, with at most<unknown>:0: warning: invalid cast from '!llvm.ptr' to '!llvm.struct<(ptr, ptr, ptr)>'.Cause
castToInterfaceSpecialCaseshandles classes, tuples and objects. For anything else it returned nothing, so the value fell through to a plaints.Castto the interface type. Lowering can't build an interface value from an array or a scalar, so it produced garbage.Fix
For a numeric type (any width),
number,string,boolean,char,bigint, an array or a const array cast to an interface that has members (getVTableSize() > 0), report:An interface without members still accepts any value, as in TypeScript.
Testing
test-compile-interface-cast-{number,string,boolean,array}(each requires the message), plustest-compile-interface-cast-empty, which must compile cleanly. The current release compiles all five without an error.🤖 Generated with Claude Code