sdk
sdk copied to clipboard
Record with `double` value cannot be used in a constant `==` operator
The code below produces an error in a both CFE and the analyzer
const c1 = (1,) == (1,); // Ok, c1 is `true`
const c2 = (3.14,) == (3.14,); // Error. In constant expressions, operands of this operator must be of type 'bool', 'num', 'String' or 'null'.
Why? (int,) is not bool, num, String or null but is accepted, but (double,) not
Tested on Dart SDK version: 3.4.0-edge.3f91beb64f8af4705e8e2e6aec1bd78f947b8a31 (main) (Mon Jan 15 23:41:29 2024 +0000) on "linux_x64"
I believe the error matches the specification, but the analyzer error message is somewhat misleading.
e1 == e2 is constant if the value of e1 is a double object, or an object that has primitive equality (or e2 is null). The reference to "'bool', 'num', 'String' or 'null'" is obsolete in any case, so the analyzer should emit a different message (the CFE message seems to be a good starting point).
However, e1 isn't a double object and it isn't an object that has primitive equality (records only have primitive equality when all components have it, and double doesn't). Hence, (3.14,) == (3.14,) is not a constant expression, so it's OK to report an error, it's just the explanation which is somewhat outdated with the analyzer.
https://github.com/dart-lang/language/issues/3563 might give rise to an update in this area.
The analyzer error message was written before there were records and we failed to update it accordingly when records were added.
The reference to "'bool', 'num', 'String' or 'null'" is obsolete ...
I agree, the message needs to be updated. I'm not sure I know what the list currently ought to be, so I don't have a concrete proposal to offer at this time.
... records only have primitive equality when all components have it ...
It sounds like the analyzer should have a specialized message for the case where both operands are records that explains the need for all components to be comparable. It would be best if it could also indicate (whether in the problem message or in context messages) which fields are causing the problem.