Please see Examples section of https://github.com/dart-lang/language/blob/master/accepted/future-releases/set-literals/feature-specification.md
...
const v13 = {1}; // const Set<int>
...
const v17 = {1, 2, 3, 2, 1}; // Set<int>
...
Types of v13 and v17 must be the same. Both constants or both not. What type is shown in the comment? Type of the variable on the left side of the '=' or type of the set literal on the right side of '='?
In the first case (type of the variable) it is const, because variable is declared as a constant.
In the second case (type of the set literal) seems it is not a constant. See specification
If s is a set literal, then it has the form const? ('<' type '>')? '{' ... '}'
...
If s starts with const, then it is a compile-time error if any element expression is not a compile-time constant expression, or if T is not a compile-time constant type. It is a compile-time error if any of the values of the constant element expressions override Object.operator== unless they are instances of int or String, objects implementing Symbol originally created by a symbol literal or a constant invocation of the Symbol constructor, or objects implementing Type originally created by a constant type literal expression.
In the examples above there is no const before '{' so it is not a constant. Right? One more related issue
// Compile-time error, overrides `==`.
// const v15 = {Duration(seconds: 1)};
But according to the cite above, it is a compile time error only when s starts with const. So, my understandig, is that {Duration(seconds: 1)} is not a constant and compile-time error here will be not because of '==' overriding.
Please clarify spec and examples in the 'const' part. Also, please, add to the examples something like
var v = const {1, 2, 3.14} // const Set<num>
Both sets would be constant. The literal occurs in a constant context, so it must be constant, just as for lists.
The type in the comment is, well, probably not consistent. I guess it should be the runtime type. I'll have a look at it. (Update: Now done, document updated)
Whether something is a set literal does not depend on the constant-ness. In all these examples, it is a set literal. A set literal is constant if it is prefixed by const or it occurs in a constant context, just as List and Map literals.
There is still
const v17 = {1, 2, 3, 2, 1}; // Set<int>.
There should be
const v17 = {1, 2, 3, 2, 1}; // const Set<int>
Good catch. Fixed that and v16.
var v2 = <int, int>{}; // LinkedMap<int, int>
Shouldn't it be a LinkedHashMap<int, int>?
var l16 = x.toList(); // -> <int>[1, 2, 3]
Please, define x first
For v14, v15,l18, v23, v24, v26, s5, s6add ; at the end of the statement
var v19 = {C(1, "a"), C(2, "a"), C("1", b")};
Change to
var v19 = {C(1, "a"), C(2, "a"), C(1, "b")};
Fixed. It's amazing how hard it is to get details right when you have no compiler to help you :)
hard [..] when you have no compiler
Surely that would come as a complete surprise to you, @sgrekhov. ;-)
@lrhn , @eernstg
var x = {1, 1.0};
Which type will have x here? LinkedHashSet<int> or LinkedHashSet<num>? Spec says that it must be the same as
LinkedHashSet o4 = new LinkedHashSet();
o4.add(1);
o4.add(1.0);
print(o4.runtimeType); // _CompactLinkedHashSet<dynamic>
But this prints _CompactLinkedHashSet<dynamic>
The type is inferred the same way as for list literals, so it is a Set<num>.
Since there is no context type, the type is inferred from the static type of the element expressions. Those are int and double, and we pick an upper bound of that, which is num.
The runtime semantics do not introduce the type, you have to treat the rewrite as starting with var o4 = LinkedHashSet<num>().
Please, also change
var v19 = {C(1, "a"), C(2, "a"), C(1, b")}; // LinkedHashSet< C >
to
var v19 = {C(1, "a"), C(2, "a"), C(1, "b")}; // LinkedHashSet< C >
@lrhn @sgrekhov can we close this now?
I'm going to guess this is safe to close.
Most helpful comment
Fixed. It's amazing how hard it is to get details right when you have no compiler to help you :)