-
-
Notifications
You must be signed in to change notification settings - Fork 670
BREAKING CHANGE: fix: detect the premature usage of @global
variant
#2624
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
BREAKING CHANGE: fix: detect the premature usage of @global
variant
#2624
Conversation
The bug will cause compile result is incorrect. // index.ts
import {} from "./a";
import {} from "./b";
// a.ts
class T {
a: i32;
}
let a = t;
// b.ts
class T {}
@global export const t = new T();
const b = new T(); the compile result is (func $start:assembly/a
global.get $~lib/memory/__heap_base
i32.const 4
i32.add
i32.const 15
i32.add
i32.const 15
i32.const -1
i32.xor
i32.and
i32.const 4
i32.sub
global.set $~lib/rt/stub/startOffset
global.get $~lib/rt/stub/startOffset
global.set $~lib/rt/stub/offset
i32.const 0
call $assembly/a/T#constructor
global.set $assembly/b/t
global.get $assembly/b/t
global.set $assembly/a/a
) It use assign |
Interesting find, hmm. Appears that the issue arises because, in this particular situation with a custom Hence I wonder if it would be preferable to detect this situation and raise an error that Example of such a side-effect: // index.ts
import {} from "./a";
import {} from "./b";
// a.ts
t += 41;
// b.ts
@global export let t = 1;
const b = t; // on a glimpse one would expect b = 1, but is 42 Similarly: // index.ts
import {} from "./a";
import {} from "./b";
// a.ts
console.log(t.toString()); // one could expect "42", but is "1"
// b.ts
@global export let t = 1;
t = 42; |
@global
variant
I am wondering how to handle |
If both |
if (!global.hasDecorator(DecoratorFlags.Lazy) && global.hasDecorator(DecoratorFlags.Global) && !global.is(CommonFlags.Compiled)) { | ||
this.error( | ||
DiagnosticCode.Variable_0_used_before_its_declaration, | ||
expression.range, | ||
global.internalName | ||
); | ||
return module.unreachable(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this cover all possible cases? For example, if the global is not read (a = t1
), but assigned (t1 = something
), it looks like this branch alone would not suffice.
replaced by #2632 |
fix #2622