HoriSun / closure-compiler

Automatically exported from code.google.com/p/closure-compiler
0 stars 0 forks source link

Feature request: better type inference across strict equality #1018

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Compile the following program with type checking:

/**
 * @param {*} x
 * @param {*} y
 */
function test(x, y) {
  if (y === x && x === 0)
    return y - 1;
}

You find 'y - 1' generates a type warning, as y has type '*' within the 
conditional, not 'number'.

Swapping the order of the two conditions around && causes type inference to 
work as expected.

Original issue reported on code.google.com by ndkrem...@google.com on 5 Jun 2013 at 6:02

GoogleCodeExporter commented 9 years ago

Original comment by dim...@google.com on 5 Jun 2013 at 6:09

GoogleCodeExporter commented 9 years ago
This is probably not a bug but a real limitation of the type inferencer.

My guess is that the ReverseAbstractInterpreter basically stuff y's Slot with 
x's type (still * at that point) when it was invoked on the first condition but 
it never brother to go back to change y.

What we could do is set y to 'depend' on x's type for a bit. But then we need 
to invalid it when y is re-assigned. This is sounding like we *need* data flow 
analysis within conditions. Something that Closure Compiler team decided to not 
to for performance reasons. That design decision on the type system can always 
be revisited of cause.

-Alan

Original comment by acle...@google.com on 5 Jun 2013 at 6:52

GoogleCodeExporter commented 9 years ago
yes, this would require back-tracking over the data-flow graph, which would 
quickly become O(N!). Let's not do this.

Original comment by Nicholas.J.Santos on 5 Jun 2013 at 7:14

GoogleCodeExporter commented 9 years ago
Agree, backtracking the graph is a bad idea.

If we are going to fix this (just for discussion sake, since this is probably 
way too low on the current team's priority). We should be tackling this in the 
forward flow.

Consider this case:

/**
 * @param {*} x
 * @param {*} y
 */
function test(x, y) {
  if (y === x) {
    if (x === 0) {
      return y - 1;
    }
  }
}

We could easily set y to 'depend on x's type'. If y is reassigned, a new 
FlowScope would have been on top of it.

Original comment by acle...@google.com on 5 Jun 2013 at 7:33

GoogleCodeExporter commented 9 years ago
Issue tracking has been migrated to github. Please make any further comments on 
this issue through https://github.com/google/closure-compiler/issues

Original comment by blic...@google.com on 1 May 2014 at 6:31

GoogleCodeExporter commented 9 years ago

Original comment by blic...@google.com on 1 May 2014 at 6:34