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

Fix evaluation order with object spread #11412

Merged
merged 5 commits into from Apr 23, 2020
Merged

Fix evaluation order with object spread #11412

merged 5 commits into from Apr 23, 2020

Conversation

Zzzen
Copy link
Contributor

@Zzzen Zzzen commented Apr 13, 2020

Q                       A
Fixed Issues?
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

TLDR: currently, the code below is not transpiled correctly. REPL

var k = { a: 1, b: 2 };
var o = { a: 3, ...k, b: k.a++ };

expected o.a to be 1.

Long story: I found weird __assign js code generated by tsc. Out of curiosity, I checked the relevant transformer code and feed the test to babel 💥. This fix is migrated from TypeScript. Original Issue

@nicolo-ribaudo
Copy link
Member

Can we limit this deoptimization to when path.isPure() is false for some property after the spread?

@nicolo-ribaudo nicolo-ribaudo added the PR: Spec Compliance 👓 A type of pull request used for our changelog categories label Apr 14, 2020
@nicolo-ribaudo nicolo-ribaudo changed the title Fix object spread runtime semantics Fix evaluation order with object spread Apr 14, 2020
z = {
x,
w: _objectSpread({}, y)
w: _objectSpread(_objectSpread({}), y)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, scope.isPure is not working as intended. What's the difference between scope.isPure and path.isPure?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😵 My bad , scope.isPure is working.

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

I have left a comment for another bug, that we can fix in a separate PR.


}, pureB, {}, pureC, {}), impureFunc(), {}, pureD, {
pureD
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this output to be

var output = { ...pureA, get foo() {}, get bar() {}, ...pureB, ...pureC, ...impureFunc(), ...pureD, pureD }

var output = _objectSpread(
  _objectSpread(
    {},
    pureA,
    { get foo() {}, get bar() {} },
    pureB,
    {},
    pureC,
    {}
  ),
  impureFunc(),
  {},
  pureD,
  { pureD }
);

I think that it's a bug in the isPure implementation, that only handles isClassMethod instead of isMethod (that also catches object methods/accessors).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙆‍♂️ I'm gonna give it a try.

@babel-bot
Copy link
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/21217/

Copy link
Contributor

@JLHwung JLHwung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@JLHwung JLHwung merged commit af66929 into babel:master Apr 23, 2020
jridgewell added a commit to jridgewell/babel that referenced this pull request Apr 24, 2020
When reviewing babel#11412, I noticed there are more cases where the intermediate values can mutate the spread reference. It's best demonstrated in the [TypeScript](https://github.com/microsoft/TypeScript/blob/eb105efdcd6db8a73f5b983bf329cb7a5eee55e1/src/compiler/transformers/es2018.ts#L272) examples.
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Jul 24, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue PR: Spec Compliance 👓 A type of pull request used for our changelog categories Spec: Object Rest/Spread
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants