Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Fixes incorrect warning of side-effects in #2393 #2394

Closed
wants to merge 6 commits into from

Conversation

trueadm
Copy link
Contributor

@trueadm trueadm commented Aug 7, 2018

Release notes: none

Fixes #2393. I created the test as a React test because I couldn't see any way of making a serializer test fail if there was a warning without making many other tests fail or without adding another // some config to the test (which I believe we said we would not add anymore as there's already too many). React tests will always fail on side-effect warnings, so this takes better advantage of this.

src/realm.js Outdated
@@ -1534,6 +1534,9 @@ export class Realm {
if (root instanceof FunctionEnvironmentRecord && func === root.$FunctionObject) {
return true;
}
if (root === env.environmentRecord) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If the loop below would start at env and not env.parent, then you wouldn't need this special case. Or is it important that this check runs before the next check around created objects that can return false? I don't get the full picture of what is being checked here and the significance of ordering.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good point, I found we can leverage env.destroyed and use that loop and it simplifies the code quite a bit.

Copy link
Contributor

@cblappert cblappert left a comment

Choose a reason for hiding this comment

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

You could change the // expected <Severity>: ... comment so that if you don't specify any error codes it verifies that there are no errors: https://github.com/facebook/prepack/blob/3e8c638071ca0bd429b4a45ebf464276dacd85c4/scripts/test-runner.js#L501

@trueadm
Copy link
Contributor Author

trueadm commented Aug 8, 2018

@cblappert I'm not sure that overloading the // expected comment to have no error really makes a lot of sense to those unfamiliar with that particular comment.

src/realm.js Outdated
while (env) {
if (env.environmentRecord === root) {
if (env.environmentRecord === root && !env.destroyed) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the intuition of why this is checking for whether "is defined inside pure function"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's checking that the environment record of the binding was that of the function we're in.

Copy link
Contributor

Choose a reason for hiding this comment

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

And why exclude destroyed envs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If they're excluded, it means we already executed that and destroyed the bindings in that scope so we don't check if that env anymore as it's bindings are no longer valid.

Copy link
Contributor

Choose a reason for hiding this comment

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

But if the matching lexical environment has been destroyed, then isDefinedInsidePureFn will return false, then below we would report side effect warnings? I am confused...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How can it be a pure function if the env has been destroyed? It should rightly report that there is a side-effect, as in the case of a pure function the env should never be destroyed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, I think I understand. The destroyed-aspect is the key in determining whether this modified binding represents a side effect.

This simplified version of the function also passes all the public tests in your PR. Anything wrong with that? If it looks right, can we go with this version?

    const isDefinedInsidePureFn = root => {
      let context = this.getRunningContext();
      let { lexicalEnvironment: env } = context;
      while (env) {
        if (env.environmentRecord === root) {
          // We can look at whether the lexical environment of the binding was destroyed to determine if it was defined outside the current pure running context.
          return !env.destroyed;
        }
        env = env.parent;
      }
      return false;
    };

Copy link
Contributor Author

@trueadm trueadm Aug 9, 2018

Choose a reason for hiding this comment

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

Updated PR with this code. :)

Copy link
Contributor

@hermanventer hermanventer left a comment

Choose a reason for hiding this comment

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

Looks good to me.

src/realm.js Outdated
return false;
}
env = env.parent;
let { lexicalEnvironment: env } = context;
while (env) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not your fault, but while you are here, would it be possible to change this to "env !== null". We avoid implicit conversions to boolean whenever possible.

Copy link

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

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

trueadm is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants