{"push_id":3950662135,"size":1,"distinct_size":1,"ref":"refs/heads/strict-eq","head":"f2c4237d98668cefef5cd32d8bf46c52a7d42aab","before":"d0bd81d23a59778145368175ad9c378c2c9a1a8c","commits":[{"sha":"f2c4237d98668cefef5cd32d8bf46c52a7d42aab","author":{"name":"Sébastien Doeraene","email":"2832a3611e91a3b35b084da8a16440b68c3bd8c7@gmail.com"},"message":"Fix the spec of eq/ne for NaN and +0.0 v -0.0.\n\nPreviously, `x eq x` would answer `false` if `x` was `NaN`; and\n`+0.0 eq -0.0` would answer `true`, although `+0.0.equals(-0.0)`\nanswers `false`.\n\nThat behavior was intentionally spec'ed, but arguably the spec had\nbeen wrong all along. It was specified like that because we\ncouldn't possibly incur the performance hit of a strict identity\nfunction for every single `eq` in the world, an operation that is\nsupposed to be virtually free.\n\nNevertheless, the spec'ed behavior caused a number of issues, for\nexample when using `eq` to cheaply test whether two values were\ndefinitely equal (that was incorrect for +0.0 and -0.0), or when\nusing `eq` to find the exact occurrence of a value in a data\nstructure by reference (that was incorrect for NaN).\n\nIn this commit, we change the spec to the much more clearly correct\nalternative where `NaN eq NaN` is true, and `+0.0 eq -0.0` is\nfalse. The full check is implemented with the ES 2015 builtin\nfunction `Object.is(x, y)`, which we polyfill when emitting ES 5.1.\n\nIn order not to have performance issues, the optimizer is enhanced\nto optimize `eq` down to JavaScript's `===` when it can prove that\nit is safe to do so. This happens when one of the following\napplies:\n\n* Either operand can be proven not to be a primitive number, which\n  can often be done by looking at its type. This is a *very* common\n  scenario, notably in all tests of the form `x eq null` or of the\n  form `someNode eq x` (where `someNode` is a value of some type\n  `Node` of a data structure, for example).\n* Both operands are known to be whole primitive numbers: `x eq y`\n  can become `x === y` when `x` and `y` are both `int`s, for\n  example.\n\nThese optimizations leave very few uses of `eq` as the full check\nwith `Object.is`, all of which are actually desirable fixes. In\nthe test suite, the optimization applies to 99.8% of the use sites\nof `eq` and `ne`.\n\nThis change means that there is no way to write user code\ncorresponding to ECMAScript's `x === y` for arbitrary `x` and `y`\nanymore. Although it is possible to write it by hand on top of\n`eq`, it is a bit absurd to undo the effects of `Object.is` to\nrecover the behavior of `===`. We add a new builtin\n`js.special.strictEquals(x, y)` for that purpose. It is used in\nthe fast path of `BoxesRunTime.equals(x, y)`, which was the only\nplace in the codebase where we really meant `===` when writing\n`eq`.","distinct":true,"url":"https://api.github.com/repos/sjrd/scala-js/commits/f2c4237d98668cefef5cd32d8bf46c52a7d42aab"}]}
{"actor":{"display_login":"sjrd"}}