Skip to content
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

Side effect bugs with logical assignment #39172

Closed
evanw opened this issue Jun 20, 2020 · 1 comment · Fixed by #39174
Closed

Side effect bugs with logical assignment #39172

evanw opened this issue Jun 20, 2020 · 1 comment · Fixed by #39174
Labels
Bug A bug in TypeScript

Comments

@evanw
Copy link
Contributor

evanw commented Jun 20, 2020

TypeScript Version: Nightly

Search Terms: logical assignment side effect

Code

This code is from lgcl-nullish-assignment-operator-lhs-before-rhs.js, a test262 conformance test.

var assert = {
  sameValue(a, b, error) {
    if (a !== b) throw new Error(`${error}: ${a} !== ${b}`)
  }
}

var count = 0;
var obj = {};
function incr() {
  return ++count;
}

assert.sameValue(obj[incr()] ??= incr(), 2, "obj[incr()] ??= incr()");
assert.sameValue(obj[1], 2, "obj[1]");
assert.sameValue(count, 2, "count");

Expected behavior: This code should exit cleanly

Actual behavior: This code crashes with Uncaught Error: obj[incr()] ??= incr(): 3 !== 2

The problem is that TypeScript evaluates the property key in the property access twice instead of capturing the value and only evaluating it once.

TypeScript generates this (incorrect):

(_a = (_b = obj)[incr()]) !== null && _a !== void 0 ? _a : (_b[incr()] = incr());

Babel generates this (correct):

(_a = obj[_b = incr()]) !== null && _a !== void 0 ? _a : obj[_b] = incr();

Playground Link: link

Related Issues: #37255 #37727

@Kingwl
Copy link
Contributor

Kingwl commented Jun 20, 2020

Good catch. I'll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants