Open KavinduZoysa opened 4 years ago
It's an interesting example.
The type should clearly be anydata|string which is the same as anydata.
But this example makes me think that we shouldn't allow E?.x
when the static type of E is a union, unless x is an individual field in all branches of the union.
Where the spec now says:
(if the type descriptor is a union, then this requirement must be satisfied by at least one member of the union)
I am thinking it ought instead to say:
(if the type descriptor is a union, then this requirement must be satisfied by all members of the union)
@hasithaa @sameerajayasoma Any thoughts?
Doesn't that kind of defeat the purpose of union for optional fields?
Now that we have never
, what if the requirement is something along the lines of
(if the type descriptor is a union, then this requirement must be satisfied by at least one member of the union, and the rest of the members can never have a
field-name
field)
So, optional field access will still work for
type Foo record {
int i;
};
type Bar record {|
string s;
|};
public function main() {
Foo|Bar fb = {i: 23};
int? i = fb?.i;
}
and
type Foo record {
int i;
};
type Bar record {
string s;
never i?;
};
public function main() {
Foo|Bar fb = {i: 23};
int? i = fb?.i;
}
But in other scenarios, such as the following, you'll have to use member-access?
type Foo record {
int i;
};
type Bar record {
string s;
};
public function main() {
Foo|Bar fb = {i: 23};
anydata i = fb["i"];
}
type Foo record {
int i;
};
type Bar record {|
string s;
int...;
|};
public function main() {
Foo|Bar fb = {i: 23};
int? i = fb["i"]; // Will be `int?`.
}
There are four possibilities for each branch of the union for an expression E.s
record { string s; }
record { string s?; }
record {| int x; |}
map<string>
or record { int x; }
In the case above, we have one branch is case 1 and one branch is case 4: that seems to me really weird, not useful and most likely to be an error.
Above, I suggested that they requirement should be that all branches are case 1 or case 2. But I think that's too restrictive, since it would disallow a combination of case 3 with case 1 or 2.
So a better restriction (this is for the non-lax case):
With this restriction, if E?.s
is allowed, then there are two runtime possibilities:
s
, in which case the the result with be ()
s
and it corresponds to an individually declared fieldNote that we don't allow E.s
when E has static type of case 4.
Description:
Currently the type of expression fb.s is determined as string. Shouldn't that be anydata?