@@ -281,9 +281,9 @@ become strict subtype checks instead.
281
281
282
282
### Const spreads
283
283
284
- Spread elements are not allowed in const lists or maps . Because the spread must
285
- be imperatively unpacked, this could require arbitrary code to be executed at
286
- compile time:
284
+ We must be careful with spread elements in const collections . Because the spread
285
+ is imperatively unpacked, even a "const" object could cause arbitrary
286
+ computation at compile time:
287
287
288
288
``` dart
289
289
class InfiniteSequence implements Iterable<int> {
@@ -300,6 +300,43 @@ class InfiniteSequence implements Iterable<int> {
300
300
const forever = [...InfiniteSequence()];
301
301
```
302
302
303
+ However, if the spread expression is a valid const expression and the resulting
304
+ value is exactly the built-in List or Map classes, then it's safe because we
305
+ know exactly how constants of those classes behave. Thus, we state:
306
+
307
+ * In a constant list, a spread element expands at compile time to the series
308
+ of elements contained in the spread object list.
309
+
310
+ * In a constant map, a spread element expands to the series of entries
311
+ contained in the spread object map.
312
+
313
+ * It is a compile-time error to use a spread element in a constant list unless
314
+ the spread object was created by a constant list literal expression.
315
+
316
+ * It is a compile-time error to use a spread element in a constant map unless
317
+ the spread object was created by from a constant map literal expression.
318
+
319
+ This enables in-place literals (which aren't very useful):
320
+
321
+ ``` dart
322
+ const list = [...["why"]];
323
+ ```
324
+
325
+ It also enables const expressions that refer to constant lists and maps defined
326
+ elsewhere, which is useful:
327
+
328
+ ``` dart
329
+ const list = [2, 3];
330
+ const another = [1, ...list, 4]; // [1, 2, 3, 4].
331
+ ```
332
+
333
+ The existing rules against self-reference prohibit a list or map from spreading
334
+ into itself:
335
+
336
+ ``` dart
337
+ const list = [...list]; // Error.
338
+ ```
339
+
303
340
### Type inference
304
341
305
342
Inference propagates upwards and downwards like you would expect:
0 commit comments