Skip to content

[dart2js] Global type inference uses infeasible path when there is try-catch #52166

Open
@rakudrama

Description

@rakudrama

Global type inference creates a graph for _SyncStarIterator.moveNext() is too conservative.

The graph has a return edge that 'falls out' of the while (true) { ...; return ...; ...} loop and off the end of the method, causing null to be a possible result. The path is statically not feasible and in modern Dart it is an error to have an implicit return like this so it should be possible to still be approximate with a union over all explicit returns.

The temporary (five years+) fix is to add an unreachable return that removes null from the inferred return type

return false; // TODO(sra): Fix type inference so that this is not needed.

The impact is that the program contains unnecessary boolConversionChecks on almost all calls to moveNext() because one of them possibly returns a legacy-nullable value (the inferred null is there even in sound mode since there is otherwise no reason to narrow return values).

Repro:

Iterable<int> foo() sync* { yield 1; }

main() {
  for (final x in foo()) print(x);
}

Compiled with the temporary fix and without:

...
2411c2411
<       for (var t1 = A.foo(), t1 = new A._SyncStarIterator(t1._outerHelper(), t1.$ti._eval$1("_SyncStarIterator<1>")); t1.moveNext$0();)
---
>       for (var t1 = A.foo(), t1 = new A._SyncStarIterator(t1._outerHelper(), t1.$ti._eval$1("_SyncStarIterator<1>")); A.boolConversionCheck(t1.moveNext$0());)
2739c2739
<             if (nestedIterator.moveNext$0()) {
---
>             if (A.boolConversionCheck(nestedIterator.moveNext$0())) {
2789d2788
<       return false;
2918c2917
<       for (count = 0; it.moveNext$0();)
---
>       for (count = 0; A.boolConversionCheck(it.moveNext$0());)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-web-jsIssues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop.dart2js-inferencedart2js-optimizationweb-dart2js

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions