Skip to content

[Extension types] No error in analyzer if result of == operator is assigned to not bool #54080

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
Tracked by #49732
sgrekhov opened this issue Nov 17, 2023 · 3 comments
Closed
Tracked by #49732
Assignees
Labels
feature-extension-types Implementation of the extension type feature legacy-area-analyzer Use area-devexp instead. P1 A high priority bug; for example, a single project is unusable or has many test failures type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@sgrekhov
Copy link
Contributor

The following test works in CFE but fails in analyzer

// SharedOptions=--enable-experiment=inline-class

class C {
  BoolET operator ==(Object? other) {
    return BoolET(other == this);
  }
}

extension type BoolET(bool b) implements bool {}

main() {
  BoolET b = C() == C();  // No expected error in analyzer
//               ^
// [analyzer] unspecified
// [cfe] unspecified
}

According to the Dart spec "The static type of an equality expression is bool", so there should be an error here

@lrhn
Copy link
Member

lrhn commented Nov 17, 2023

The static type of == is bool, not the type of operator==, because the == operator may return true or false without calling operator== when comparing with null.
So it's a soundness requirement, not just laziness.

There didn't use to be that many subtypes of bool, but the following were also valid before extension types:

class C<B extends bool> {
  final B truth, falsity;
  C(this.truth, this.falsity);
  B operator ==(Object other) => other is C && truth == other.truth && falsity == other.falsity ? truth : falsity;
  void chk(C<B>? other) {
    var eq = this == other;
    assert(eq);
    eq = false; // Not allowed if type of `eq` is `B`.
  }
}
class D {
  Never operator ==(Object other) => throw "Dunno, maybe?";
}
void main() {
  var c = C<bool>(true, false);
  c.chk(c);
  D? notD = DateTime.now().millisecondsSinceEpoch > 0 ? null : D();
  var eq = D() == notD;
  eq = false; // Not allowed if `eq` has type `Never`.
}

And indeed, the analyzer gives the errors:

error
line 8 • A value of type 'bool' can't be assigned to a variable of type 'B'.[ (view docs)](https://dart.dev/diagnostics/invalid_assignment)
Try changing the type of the variable, or casting the right-hand type to 'B'.
error
line 19 • A value of type 'bool' can't be assigned to a variable of type 'Never'.[ (view docs)](https://dart.dev/diagnostics/invalid_assignment)
Try changing the type of the variable, or casting the right-hand type to 'Never'.

This is not constrained to extension types, it's a general issue with the analyzer, one which can possibly give incorrect type inference (if a Never expression considered unable to continue).

class FoolMe { Never operator==(Object? o) => throw "Ever"; }
void main() {
  Object? o = "not an integer";
  if (o is! int) { FoolMe() == 0; }
  print(o.toRadixString(16));
}

has no error in the analyzer.

(All tests done in DartPad, master branch.)

@lrhn lrhn added type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed feature-extension-types Implementation of the extension type feature labels Nov 17, 2023
@eernstg
Copy link
Member

eernstg commented Nov 17, 2023

Great examples! I think the latter should be reported explicitly as a soundness issue, so I created #54083.

@srawlins srawlins added P1 A high priority bug; for example, a single project is unusable or has many test failures feature-extension-types Implementation of the extension type feature labels Nov 20, 2023
@scheglov scheglov self-assigned this Nov 20, 2023
@scheglov
Copy link
Contributor

copybara-service bot pushed a commit that referenced this issue Nov 20, 2023
Bug: #54080
Change-Id: I5deff67f480b24dc719d438bc7df5a7697772bee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/337281
Reviewed-by: Samuel Rawlins <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-extension-types Implementation of the extension type feature legacy-area-analyzer Use area-devexp instead. P1 A high priority bug; for example, a single project is unusable or has many test failures type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

5 participants