Skip to content
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

Possibly incorrect desugaring of compound assignment with explicit extension method invocations #39527

Closed
eernstg opened this issue Nov 26, 2019 · 2 comments
Assignees
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Milestone

Comments

@eernstg
Copy link
Member

eernstg commented Nov 26, 2019

Consider the following program:

class C {
  int value = 0;
}

extension Extension1 on C {
  C operator [](int index) => this..value += index + 1;
  void operator []=(int index, C other) =>
      this.value += other.value + index + 1;
  C operator -(int val) => this;
}

main() {
  C c = C();
  // Original term that produces an unexpected error.
  --Extension1(c)[42];

  // The pre-decrement desugars as follows, which is also flagged as an error.
  Extension1(c)[42] -= 1;

  // The compound assignment desugars as follows, which is accepted.
  Extension1(c)[42] = Extension1(c)[42] - 1;
}

This program is accepted by the analyzer, but rejected by dart from commit ee8d9d2, with the following error:

n056.dart:15:19: Error: A value of type 'int' can't be assigned to a variable of type 'C'.
 - 'C' is from 'n056.dart'.
  --Extension1(c)[42];
                  ^
n056.dart:18:17: Error: A value of type 'int' can't be assigned to a variable of type 'C'.
 - 'C' is from 'n056.dart'.
  Extension1(c)[42] -= 1;
                ^

The comments indicate why this should not be an error: The two-step desugaring of the pre-increment produces Extension1(c)[42] = Extension1(c)[42] - 1. This is an explicit invocation of the operator []= from Extension1; the second argument is Extension1(c)[42] - 1, which is an explicit invocation of operator [] from Extension1, yielding a result of type C, on which we call operator -(int) (an implicitly resolved method from Extension1). All the types add up as they should, and I believe this is a bug in the front end (presumably in the desugaring steps, because the manual desugaring eliminates the error).

@eernstg eernstg added type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) area-front-end Use area-front-end for front end / CFE / kernel format related issues. labels Nov 26, 2019
@eernstg
Copy link
Member Author

eernstg commented Nov 26, 2019

Note that the outcome is identical for the case shown above and the case where operator -(int) is an instance member.

Also worth noting: There are no errors when the program is adjusted to perform all extension method invocations implicitly:

class C {
  int value = 0;
}

extension Extension1 on C {
  C operator [](int index) => this..value += index + 1;
  void operator []=(int index, C other) =>
      this.value += other.value + index + 1;
  C operator -(int val) => this;
}

main() {
  C c = C();
  --c[42];
  c[42] -= 1;
  c[42] = c[42] - 1;
}

dart-bot pushed a commit that referenced this issue Nov 26, 2019
Initial import of co19 (nnbd) at 8767031866e8243eafdb46011d4d8a7b5705019d.

Roll co19_2 to 368bfa9e877a2df003547f64bb17e30596af10c7:
2019-11-22 irina.arkhipets@gmail.com Issue 501 fixed: correct expected result adjusted.
2019-11-22 irina.arkhipets@gmail.com Issue 501 fixed: correct expected result adjusted.
2019-11-22 irina.arkhipets@gmail.com Issue 499 fixed: correct expected result adjusted.
2019-11-22 sgrekhov@unipro.ru Fixes 500. Expected result corrected
2019-11-12 sgrekhov@unipro.ru Fixes 495. Partial fix. Explicit extension member invocation tests added
2019-11-11 sgrekhov@unipro.ru 495. Partial fix. Null-aware explicit extension member invocation tests added
2019-11-07 sgrekhov@unipro.ru Remove hint in analyzer
2019-11-07 sgrekhov@unipro.ru 495. Partial fix. Explicit extension member invocation tests for composite member invocation added
2019-11-06 sgrekhov@unipro.ru 495. Partial fix. Explicit extension member invocation tests for composite member invocation added
2019-11-05 sgrekhov@unipro.ru 495. Partial fix. Explicit extension member invocation tests for composite member invocation added
2019-10-31 sgrekhov@unipro.ru 495. Partial fix. Explicit extension member invocation tests for binary operations added
2019-10-30 sgrekhov@unipro.ru 495. Partial fix. Explicit extension member invocation tests for binary operations added
2019-10-29 sgrekhov@unipro.ru 495. Partial fix. Explicit extension member invocation tests added
2019-10-10 irina.arkhipets@gmail.com Fixed Issue 494: expected result corrected.
2019-10-09 irina.arkhipets@gmail.com Fixed Issue 493: typo corrected.
2019-10-09 irina.arkhipets@gmail.com Fixed Issue 492: typo corrected.

Failures are due to:
* Triple-shift is not yet implemented.
* #39527

Change-Id: I81578e1e3e18b396f1d20cee7aaa34cd4df54bbf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/125973
Reviewed-by: Jonas Termansen <sortie@google.com>
@johnniwinther johnniwinther self-assigned this Dec 11, 2019
@johnniwinther johnniwinther added this to the D28 Release milestone Dec 11, 2019
@franklinyow
Copy link
Contributor

What is the status on this one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

3 participants