Skip to content

CFE produces compile time error on language/async_star/await_pauses_test.dart #41559

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

Closed
nshahan opened this issue Apr 17, 2020 · 6 comments
Closed
Labels
legacy-area-front-end Legacy: Use area-dart-model instead. NNBD Issues related to NNBD Release vm-nnbd-sdk-complete All new NNBD and ported NNBD tests pass web-dev-compiler

Comments

@nshahan
Copy link
Contributor

nshahan commented Apr 17, 2020

@johnniwinther @stereotype441

The analyzer has no issue with the test language/async_star/await_pauses_test.dart but the CFE reports the error:

org-dartlang-app:/tests/language/async_star/await_pauses_test.dart:25:9: Error: A value of type 'num' can't be assigned to a variable of type 'int'.
      r += await new Future.delayed(new Duration(milliseconds: 10), () => i);

Inspecting the test it looks like all the types here should be inferred as ints but somehow the CFE believes the Future being created is of type Future<num>.

A simple fix for the test is to explicitly type the Future:

new Future<int>.delayed(new Duration(milliseconds: 10), () => i);

but I thought I should report something here since the tools disagree. Which one is correct?

cc @liamappelbe @alexmarkov

@nshahan nshahan added web-dev-compiler legacy-area-front-end Legacy: Use area-dart-model instead. NNBD Issues related to NNBD Release vm-nnbd-sdk-complete All new NNBD and ported NNBD tests pass labels Apr 17, 2020
@johnniwinther
Copy link
Member

The CFE is wrong.

@johnniwinther
Copy link
Member

Taking a further look this is actually related to the unspecified/underspecified/incoherent inference of + and +=:

We currently have the special-casing that e1 + e2 has type int if e1 and e2 both have type int (and similar for double). For the inference of e2 in e0 = e1 + e2 we don't have the requirement above (since we don't have a type for e2 yet). If e1 has type int then, by the definition of operator + on int the type context for e2 is num. In the above example this makes us infer that await new Future.delayed(new Duration(milliseconds: 10), () => i); has type num (as required by the type context) and this in turn leads to the implicit downcast of e1 + e2 from num to int. With NNBD this is not allowed so we now have a compile-time error.

@eernstg @lrhn: We discussed this case a while ago but I don't think we ever got a conclusion.

@leafpetersen: Should we adjust the inference to support the special-casing of the typing of +? Maybe something like: If the type context for e1 + e2 is int then the type context for e1 and e2 is also int. (Similarly for when the type context is double).

@lrhn
Copy link
Member

lrhn commented Apr 18, 2020

We currently have the special-casing that e1 + e2 has type int if e1 and e2 both have type int (and similar for double).

Not sure the "similar for double" is in the specification. The rule is just that double.operator+ has return type double, but num x = 1.0; var y = x + 1; would give y the type num in the current specification.

We may need to also add that if e1 has static type int or num and e2 has static type double, then the addition has static type double. That allows 1 + 1.0 to have type double instead of num, same for someNumber + 1.0.

The rule for context typing would be:

  • If e1 + e2 has context type int and e1 has static type int, then e2 has context type int.
  • if e1 + e2 has context type double and e1 has static type int, then e2 has context type double.

We can't provide a context type for e1 because it might be MyFancyThing with an int operator+(MyFancyThing other). We can only use the spec-special-casing of + in the situations where it applies, and that's currently where the receiver is an int.

If we add more rules, as suggested above, we can also make more deductions:

  • If e1 + e2 has context type double and e1 has static type int or num, then e2 has context type double.
    (because otherwise the static type of the addition would be num or int and not assignable to double)

@johnniwinther
Copy link
Member

Do we have any progress on this? Should we have a language issue for the inference of + and friends?

@lrhn
Copy link
Member

lrhn commented Jun 2, 2020

No progress. The language issue is probably dart-lang/language#725.

@leafpetersen
Copy link
Member

@johnniwinther I will look into this. I need to wrap up the initialization assignment proposal and related tests first, but I should be able to get to this this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
legacy-area-front-end Legacy: Use area-dart-model instead. NNBD Issues related to NNBD Release vm-nnbd-sdk-complete All new NNBD and ported NNBD tests pass web-dev-compiler
Projects
None yet
Development

No branches or pull requests

4 participants