-
-
Notifications
You must be signed in to change notification settings - Fork 670
Fix variable initialization checks / revise flow logic #2578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Alright, this is the most annoying stuff I've seen in a while. Wraith of flows having grown somewhat organically. Good news is that I now know about why, bad news is that oh my god. |
While this PR supports definite assignments on globals (and static class fields, which are also globals in AS) now, there are two discrepancies here. One with a Wasm GC future: In Wasm, globals imply an initializer, so if we have something like var foo!: string; there is nothing we can initialize the respective Wasm global with in Wasm (global $index/foo (mut (ref string)) (???)) Two options: Either we represent the global off-type in the binary, as nullable Another is with TypeScript: In TS, static class fields cannot have definitive assignment class Foo {
static bar!: string; // TS1255
} though these become globals in AS. As such, in AS, this distinction doesn't make sense. That's all somewhat unfortunate, because one or another property must be sacrificed anyway. I tend to drop support for definitive assignment either now or later and instead focus on almost 1:1 roundtripping from source to Wasm, which then basically means that we'd mandate that variables are always initialized with some value, e.g. using a nullable type and assigning var foo!: string; is not supported and instead we require var foo: string | null = null; Wdyt? cc @MaxGraey |
Fine side-effect here is that now that flows cover all relevant termination cases the prior fixup code to insert |
Postponing the decision on definitive assignment for now. |
I think this broke I started looking into making a repro test case on |
It would be great to make a rule exception for function write<T>(variant: T) {
if (isArrayLike<T>()) {
let item: valueof<T>;
if (item instanceof Foo) {
// do something
}
}
} The problem is that if you try init |
Fixes #899. This has been a long-standing issue I apparently forgot about, and as it turns out there was quite a bit more attached to it. Specifically:
The last one isn't great, in that in the absence of full program analysis, we either need to enforce initializers on globals or introduce runtime checks where TS would not diagnose a problem. Decided to implement both, but limited it to non-nullable references since for other types there is a sound zero. POC in TS is:
Definitive assignment can be used as a fallback, then at the cost of runtime non-null checks when such a global is accessed:
Making a draft for now as it seems that there are more places to look at, closing #2573 which is included here, and perhaps there are thoughts about the changes to global initialization as explained above?