@@ -283,6 +283,77 @@ fields are) and collection literals.
283
283
284
284
** TODO: Specify this more precisely.**
285
285
286
+ ### Constants
287
+
288
+ _ Record expressions can be constant and potentially constant expressions._
289
+
290
+ A record expression is a compile-time constant expression
291
+ if and only if all its record field expressions are compile-time constant expressions.
292
+
293
+ _ This is true whether the expression occurs in a constant context or not,
294
+ which means that a record expression can be used directly as a parameter default value
295
+ if its record field expressions are constant expressions.
296
+ Example: ` f({(int, int) x = (1, 2)}) => ... ` ._
297
+
298
+ A record expression is a potentially constant expression
299
+ if and only iff all its record field expressions are potentially constant or constant expressions.
300
+
301
+ _ This means that a record expression can be used in the initializer list
302
+ of a constant non-redirecting generative constructor,
303
+ and can depend on constructor parameters._
304
+
305
+ _ Constant * object* instantiations create deeply immutable and canonicalied objects.
306
+ Records are always unmodifiable, and if their field values are deeply immutable,
307
+ like constants values, the records are also deeply immutable.
308
+ It's meaningless to consider whether record constants are canonicalized,
309
+ since records do not have a persistent identity._
310
+
311
+ _ Because of that, there is no need for a ` const (1, 2) ` syntax to force a record
312
+ to be a constant, like there is for object creation expressions.
313
+ A record expression with field values that are constant-created values,
314
+ will be indistinguishable from a similar expression created in a constant
315
+ context, since identity cannot be used as a distinguishing trait._
316
+
317
+ _ (We could choose to promise that a compile-time constant ` identical(c1, c2) ` ,
318
+ where the expression occurs in a constant context and ` c1 ` and ` c2 ` are records,
319
+ will evaluate to ` true ` iff a runtime evaluation of ` identical `
320
+ * can* return ` true ` for the same values.
321
+ That is, records would be canonicalized during compile-time constant evealuation,
322
+ but may lose their identity at runtime. We will not make such a promise.)_
323
+
324
+ For canonoicalization purposes, we update the definition of when to canonicalize
325
+ the result of a constant object creation expression to not be dependent on
326
+ the ` identical ` function, since it does not behave predictably (or usefully)
327
+ for records.
328
+
329
+ We define two Dart values, * a* and * b* , to be _ structurally equivalent_ as follows:
330
+ * If * a* and * b* are both records, and they have the same shape,
331
+ and for each field * f* of that shape, the records' values of that field,
332
+ * a* <sub >* f* </sub > and * b* <sub >* f* </sub > are structurally equivalent,
333
+ then * a* and * b* are structurally equivalent.
334
+ * If * a* and * b* are non-record object references,
335
+ and they refer to the same object, then * a* and * b* are structurally equivalent.
336
+ _ So structural equivalence agrees with ` identical ` for non-records._
337
+ * Otherwise * a* and * b* are not structurally equivalent.
338
+
339
+ With that definition, the rules for object and collection canonicalization is changed
340
+ from requiring that instance variable, list/set element and map key/value values are
341
+ ` identical ` between the instances, to them being _ structurally equivalent_ .
342
+
343
+ _ This change allows a class like_
344
+ ``` dart
345
+ class C {
346
+ final (int, int) pair;
347
+ const C(int x, int y) : pair = (x, y);
348
+ }
349
+ ```
350
+ _ to be properly canonicalized for objects with the same effective state,
351
+ independentlty of whether ` identical ` returns ` true ` or ` false ` on the ` pair ` value._
352
+
353
+ _ Notice that if the ` identical ` returns ` true ` on two records, they must be structurally equivalent,
354
+ but unlike for non-records, the ` identical ` function can also return ` false `
355
+ for structurally equivalent records._
356
+
286
357
## Runtime semantics
287
358
288
359
### Records
0 commit comments