Skip to content

Implement more flexible constant expression comparison #33408

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
2 tasks done
eernstg opened this issue Jun 11, 2018 · 0 comments
Closed
2 tasks done

Implement more flexible constant expression comparison #33408

eernstg opened this issue Jun 11, 2018 · 0 comments
Labels
area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...).

Comments

@eernstg
Copy link
Member

eernstg commented Jun 11, 2018

As of commit f11f2ed, the language specification has been modified to slightly relax the constraints on the usage of operator == in constant expressions. The updated spec language occurs in one of the items about what it takes to be a constant expression:

\item An expression of one of the forms  \code{$e_1$ == $e_2$} or  \code{$e_1$ != $e_2$}
where $e_1$ and $e_2$ are constant expressions, and either both evaluate to a numeric,
string or boolean value, or at least one of $e_1$ or $e_2$ evaluates to \NULL{}.

The previous wording allowed only numeric, string, or boolean values and the null object, but the new wording allows arbitrary objects on one side, as long as the other side evaluates to the null object (which could be because it is the expression null, or because it is some other expression, possibly including formal parameters from the enclosing constructor declaration, that evaluates to the null object for each constant object expression that denotes said constructor).

This means that it is now possible to use constructs like the following also for constant expressions like const C(e1, e2) where e1 and/or e2 evaluate to instances which are not numeric, not strings, and not booleans:

class C {
  final Object opt1;
  final Object opt2;

  // Ensure that at most one of opt1/2 is non-null.
  const C({this.opt1, this.opt2}) : assert(opt1 == null || opt2 == null);

  // Indirectly ensure that exactly one of opt1/2 is null. For instance, it
  // is a compile-time error to use `const C.tricky(...)` with two different lists:
  // the arguments are not equal (so the assert "looks OK"), but they are
  // both non-null, and that causes the use of `!=` to be an error.
  const C.tricky({List this.opt1, List this.opt2}): assert(opt1 != opt2);
}

main() {
  var c;

  c = const C(); //# 01: ok
  c = const C(opt1: 4); //# 02: ok
  c = const C(opt2: 2); //# 03: ok

  // Make the `assert` fail.
  c = const C(opt1: 4, opt2: 2); //# 04: compile-time error

  c = const C.tricky(opt1: [], opt2: null); //# 05: ok
  c = const C.tricky(opt1: null, opt2: []); //# 06: ok

  // Make the `assert` fail.
  c = const C.tricky(); //# 07: compile-time error

  // Make the evaluation attempt to use `!=` on two non-null objects, hence fail.
  c = const C.tricky(opt1: [1], opt2: [2]); //# 08: compile-time error

  print(c); // Avoid 'unused' hint.
}

Note that some discussions in the same topic area occurred in #26980 and #30288. The example is a variant of an example given in this comment on #30288.


Subtasks

@leafpetersen leafpetersen added the area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). label Jun 11, 2018
@lrhn lrhn added the area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). label Jun 22, 2018
@munificent munificent removed the area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). label Jul 11, 2018
dart-bot pushed a commit that referenced this issue Aug 10, 2018
This is the fix for #33408 for dart2js

Change-Id: Ifddeacb68884da308d279ce6d5cbbb6adc5385ca
Reviewed-on: https://dart-review.googlesource.com/69020
Commit-Queue: Harry Terkelsen <[email protected]>
Reviewed-by: Sigmund Cherem <[email protected]>
@eernstg eernstg closed this as completed Aug 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...).
Projects
None yet
Development

No branches or pull requests

4 participants