Skip to content

Commit d5f246b

Browse files
authored
Change type requirements for {} being a set literal. (#129)
* Change rules for when a set-or-map-literal is a set literal. The existing rule had some issue. My immediate fix would have different issues. The `FutureOr` case is particularly annoying because `FutureOr<LinkedHashSet<X>>` as a context type should create a `Set<X>`, and `FutureOr<V>` is a super-type of `V` and we don't want to get into zig-zag problems (`Iterable<int>` is incomarable to `List<num>`, and `Iterable<int>` is incomparable to `FutureOr<List<int>>`). This change requires answering a negative universal property, but I believe the types in question must be available in the context type, so it should be simple (get the `T` type as the type parameter of `Iterable` if the context type implements iterable, get the `K` and `V` as the type parmeters of `Map` if the context type implements `Map`, and you only need to check those). * Simplify. Do not attempt to match type variables because they won't work.
1 parent ba1571f commit d5f246b

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

accepted/future-releases/set-literals/feature-specification.md

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Set Literals Design Document
22
Author: lrn@google.com
3+
Version: 1.1
34

45
Solution for [Set Literals Problem](http://github.com/dart-lang/language/issues/36).
56
Based on feature proposal [Issue 37](http://github.com/dart-lang/language/issues/37)
@@ -84,12 +85,14 @@ if *s* has a `typeArguments` with two type arguments, *s* is a *map literal*.
8485
(*Three or more type arguments is a compile time error, so the remaining possible case is having no type arguments*).
8586

8687
If *s* is an `emptySetOrMapLiteral` with no `typeArguments` and static context type *C*, then
87-
if `Set<Null>` is assignable to *C* and `Map<Null, Null>` is not assignable to *C*, then *s* is a *set literal*,
88-
otherwise *s* is a *map literal*.
88+
if `LinkedHashSet<Null>` is assignable to *C* and `LinkedHashMap<Null, Null>` is not assignable to *C*,
89+
then *s* is a *set literal*, otherwise *s* is a *map literal*.
8990

90-
(*So if *C* is, for example, `Iterable<int>` or `Set<Object>` or `FutureOr<Iterable<int>>` or a type variable with any of
91-
those as bound, then *s* is a set literal. If *C* is `Object` or `dynamic` or `Null` or `String`, then *s* is a map literal,
92-
*and* potentially a compile-time error due to static typing*).
91+
(*So if *C* is, for example, `Iterable<int>`, `Set<Object>`, `LinkedHashSet<int>` or `FutureOr<Iterable<int>>`,
92+
then *s* is a set literal. If *C* is `Object` or `dynamic` or `Null` or `String`, then *s* is a map literal,
93+
*and* potentially a compile-time error due to static typing*. If *C* is some subclass of `Set<X>` other than `LinkedHashSet`, then the literal is a map literal, but it is also a guaranteed type error even if the literal
94+
is a set. If *C* is a subtype of `LinkedHashSet<X>` *and* a subtype of `LinkedHashMap<Y, Z>`, then *s* is again
95+
a map literal, and a guaranteed run-time type error).
9396

9497
### Map literals
9598

@@ -357,3 +360,7 @@ var s6 = {...{1: 1}, ...?d}; // Map<dynamic, dynamic>
357360
// var s7 = {...?d}; // Compile-time error, ambiguous
358361
// var s8 = {...{1}, ...{1: 1}}; // Compile-time error, incompatible
359362
```
363+
364+
##Revisions
365+
1.0: Initial version plus type fixes.
366+
1.1: Changed type rules for selecting set literals over map literals.

0 commit comments

Comments
 (0)