Specify for all literals whether the object overrides `Object.==`.
Also mention it in the `external const factory Symbol` constructor.
This only relevant for constant expressions that may be used as
switch case expressions or constant map keys.
See #32557.
Bug: http://dartbug.com/32557
Change-Id: Ie82799f3f0d39c21c10765338a7dfeb74a582add
Reviewed-on: https://dart-review.googlesource.com/c/81242
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 5b453a0..7e381b9 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -4499,6 +4499,8 @@
Attempting to instantiate \code{Null} causes a run-time error.
It is a compile-time error for a class to extend, mix in or implement \code{Null}.
The \code{Null} class extends the \code{Object} class and declares no methods except those also declared by \code{Object}.
+\commentary{As such, it does not override the \code{==} operator inherited
+from the \code{Object} class.}
\LMHash{}
The static type of \NULL{} is the \code{Null} type.
@@ -4608,6 +4610,8 @@
It is a compile-time error for a class to extend, mix in or implement \code{double}.
It is a compile-time error for any class other than \code{int} and \code{double} to extend, mix in or implement \code{num}.
+\LMHash{}
+The instances of \code{int} and \code{double} all override the \code{==} operator inherited from the \code{Object} class.
\subsection{Booleans}
\LMLabel{booleans}
@@ -4627,6 +4631,10 @@
It is a compile-time error for a class to extend, mix in or implement \code{bool}.
\LMHash{}
+The \code{bool} class does not override the \code{==} operator inherited from
+the \code{Object} class.
+
+\LMHash{}
Invoking the getter \code{runtimeType} on a boolean value returns the \code{Type} object that is the value of the expression \code{bool}.
The static type of a boolean literal is \code{bool}.
@@ -4814,6 +4822,8 @@
\LMHash{}
All string literals evaluate to instances of the built-in class \code{String}.
It is a compile-time error for a class to extend, mix in or implement \code{String}.
+The \code{String} class overrides the \code{==} operator inherited from
+the \code{Object} class.
The static type of a string literal is \code{String}.
@@ -4901,6 +4911,10 @@
and no other symbol literals evaluate to that \code{Symbol} instance
or to a \code{Symbol} instance that is \code{==} to that instance.
+\LMHash{}
+The objects created by symbol literals all override
+the \code{==} operator inherited from the \code{Object} class.
+
\rationale{
One may well ask what is the motivation for introducing literal symbols? In some languages, symbols are canonicalized whereas strings are not.
However literal strings are already canonicalized in Dart.
@@ -4993,6 +5007,10 @@
The result of the evaluation is $a$.
\end{itemize}
+\LMHash{}
+The objects created by list literals do not override
+the \code{==} operator inherited from the \code{Object} class.
+
\commentary{
Note that this document does not specify an order in which the elements are set.
This allows for parallel assignments into the list if an implementation so desires.
@@ -5057,8 +5075,10 @@
It is a compile-time error if the key of an entry in a constant map literal is an instance of
a class that has a concrete operator \syntax{`=='} declaration different from the one in \code{Object},
unless the key is a string or an integer,
-or the key expression is a literal symbol or
-an invocation of a constant constructor of class \code{Symbol}.
+or the key expression evaluates to an instance of the built-in
+class \code{Symbol} which was originally obtained by evaluation of a
+literal symbol or
+a constant invocation of a constructor of the \code{Symbol} class.
% Needs 'free': `const <int, Function(Function<X>(X))>{}` is OK, but
% `X` is not free.
It is a compile-time error if a type argument of a constant map literal
@@ -5107,6 +5127,10 @@
\end{itemize}
\LMHash{}
+The objects created by map literals do not override
+the \code{==} operator inherited from the \code{Object} class.
+
+\LMHash{}
A run-time map literal
\code{\{$k_1:e_1, \ldots, k_n:e_n$\}}
is evaluated as
@@ -6527,6 +6551,9 @@
(\ref{actualTypeOfADeclaration})
corresponding to the signature in the function declaration $f$,
using the current bindings of type variables, if any.
+If $f$ denotes a static method or top-level function,
+the corresponding class does not override the \code{==} operator
+inherited from the \code{Object} class.
%
An invocation of $o$ with a given argument list will bind actuals to formals
in the same way as an invocation of $f$
@@ -9382,8 +9409,10 @@
It is a compile-time error if the class $C$ has an implementation of
the operator \code{==} other than the one inherited from \code{Object},
unless the expression evaluates to a string or an integer,
-or the expression is a literal symbol or
-an invocation of a constant constructor of class \code{Symbol}.
+or the expression evaluates to an instance of the built-in
+class \code{Symbol} which was initially obtained by evaluation of a
+literal symbol or
+a constant invocation of a constructor of the \code{Symbol} class.
\rationale{
The prohibition on user defined equality allows us to implement the switch efficiently for user defined types.
@@ -10920,6 +10949,8 @@
\LMHash{}
When types are reified as instances of the built-in class \code{Type},
+those objects override the \code{==} operator
+inherited from the \code{Object} class, so that
two \code{Type} objects are equal according to operator \syntax{`=='}
if{}f the corresponding types are subtypes of each other.
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index 8580d6f..459aad3 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -70,6 +70,8 @@
* const Symbol("_foo") // Invalid
* ``
*
+ * The created instance overrides [Object.==].
+ *
* The following text is non-normative:
*
* Creating non-const Symbol instances may result in larger output. If