.. and checked that they can occur also in Dart 2; added a comment
about why this is so, on each of them. Also, got rid of the term
"run-time error": the majority of references to errors at run time
were "dynamic error", and now that is the term used everywhere.
Cf. https://github.com/dart-lang/sdk/issues/34521.
Change-Id: I7579c84a8d52199524770fb91c64804173ed533d
Reviewed-on: https://dart-review.googlesource.com/c/90243
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Also marked the feature specification generalized-void.md
as background material
Change-Id: I08c9b54d956208db5aa8e695540b0c1fc941e46b
Reviewed-on: https://dart-review.googlesource.com/c/86421
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Corrected instantiate-to-bound.md to (1) take the variance of the top level
type into account for each step of the algorithm, and (2) explicitly require
that the type yielded by the algorithm must be checked for well-boundedness;
finally (3) an example showing that we can indeed get a result which is not
well-bounded was added.
Also adjusted the terminology to be consistent with dartLangSpec.tex
(where we say 'generic type alias' rather than 'parameterized type
alias').
Change-Id: I4b4e4ee7988439e39b05514f172d69233b1695d7
Reviewed-on: https://dart-review.googlesource.com/c/80140
Reviewed-by: Leaf Petersen <leafp@google.com>
Also updated spec on the static and dynamic types of functions literals
and static functions along with the function objects obtained from
closurizations of them.
Introduced a separate notion of what it means to be a correct override
relation (where the old text used subtyping, which won't suffice, for
several reasons).
Introduced the notion of interfaces as a separate kind of entity that
contains method signatures (again, a new kind of entity), thus
clarifying exactly which pieces of information is available during
static analysis of member accesses, e.g., instance method invocations.
Introduced 'combined' interfaces; they are needed for `mixin`
declarations, and we will specify them soon (so it should be OK to
have them now, even though they are unused).
Change-Id: I6347df49b1aa7a81d74e25904ee75c19e8ac6930
Reviewed-on: https://dart-review.googlesource.com/c/81263
Reviewed-by: Leaf Petersen <leafp@google.com>
The analyzer enforces the rule that when a generic type alias F has
formal type parameters X1..Xm with bounds B1..Bm, if we assume that
X1..Xm are types satisfying the corresponding bounds then it must be
the case that every type which occurs in the body of F must be
regular-bounded.
In other words, the bounds on the left hand side of `=` must imply
the bounds applicable to every type on the right hand side.
---------- NEW TEXT ----------
I just discovered that it is _not_ possible to skip the check on
every super-bounded parameterized type based on a generic type
alias: It is certainly possible to have a type which is correctly
super-bounded according to the type parameter bounds on the left
hand side of `=` in the type alias declaration, and still have a
right hand side where some types are not well-bounded. Consider the
following declarations:
class B<Y1 extends Y2, Y2, Y3 extends num> {}
typedef F<X extends num> = B<num, Object, X> Function();
According to the declarations to the left of `=`, `F<Object>`
is a correct super-bounded type, because it is not
regular-bounded (`Object <\: num`), and `F<Null>` is regular-bounded
(`Null <: num`).
Also, when the declared bound of `X` is satisfied, we are
guaranteed that each type on the right hand side is regular-bounded
(if parameterized, it receives type arguments that satisfy all
the specified bounds).
But consider the result of applying `F` to `Object`:
B<num, Object, Object> Function();
That's not a type where all subterms which are types are
well-bounded:
B<num, Object, Object> is not regular-bounded because
`Object <\: num` (third type argument).
B<num, Object, Object> is not super-bounded because
B<num, Null, Null> is not regular-bounded because
`num <\: Null` (violating `Y1 extends Y2`).
So there is no way we can prove that this check can be skipped,
because we have a pretty simple counter-example!
I'm currently adjusting the text to re-introduce the check.
---------- OLD TEXT, NOT VALID ----------
This must be specified, because it justifies the _removal_ of a
requirement that we had in the feature specification
super-bounded-types.md: It was required for every application of a
generic type alias F to a list of actual type arguments <T1..Tk>
such that the resulting parameterized type F<T1..Tk> was
super-bounded that both the parameterized type F<T1..Tk> and every
type in the resulting type [T1/X1..Tk/Xk]U (where U is the body of
F and X1..Xk are its formal type parameters) be well-bounded.
But when the bounds of F imply satisfaction of the bounds of all
types that occur in the body of F, it's trivially true that all
types in the resulting type are regular-bounded for the result
of substituting Null for covariant top types and Object for
contravariant Null for every super-bounded F<T1..Tk>. I'm looking
into a proof sketch for the result that this implies that any
well-bounded generic type alias application yields a type that
contains only well-bounded types.
This would be a very welcome simplification (because it was an
inconvenient complication that we had to check both the left hand
side and the right hand side of a type alias whenever we
encountered a super-bounded type expressed via a type alias), and
I believe that it will also make the tools run faster (because they
can now skip all those checks of every type that occurs in the body
for every super-bounded usage of a type alias.
Change-Id: Icd70649ebaed41b193aeb0cb6f08d06aed0ee5bd
Reviewed-on: https://dart-review.googlesource.com/c/79743
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Cf. SDK issue 34722, where the need for this clarification arose.
Change-Id: I3b1692931506410e77c59004b1ed1981a17a6f3d
Reviewed-on: https://dart-review.googlesource.com/c/78982
Reviewed-by: Leaf Petersen <leafp@google.com>
The existing version covers generic classes only, but we should
use exactly the same rules for parameterized type aliases, which was
actually already specified in all the nested cases (e.g., `A` would mean
`A<F<dynamic>>` with the declarations `typedef F<X> = X Function();` and
`class A<X extends F<X>> {}`, but there were no rules for a plain `F`).
A rendered version corresponding to patchset 3 is available here:
https://gist.github.com/eernstg/6deffcde2cbe79f8ba499b3aac950900
Change-Id: Ic265ccc736c65361919e860b1ab7ecb947c2c066
Reviewed-on: https://dart-review.googlesource.com/c/76660
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
The valid return tests were misnamed and hence not run. Also remove
duplicate tests from one file, and add status to the informal proposal.
Change-Id: I20179e81a0281302056f601ee3b7a51e2aec180e
Reviewed-on: https://dart-review.googlesource.com/73562
Commit-Queue: Leaf Petersen <leafp@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
In changing the proposed spec to address comments in a way that was intended to be
non-breaking, I accidentally introduced some new (unintended) restrictions. This
fixes the spec, rolls back the change in analyzer, and adjusts the language tests
appropriately.
Change-Id: I487b0eaacbfa1447d4ee909c0a56e435c2088990
Reviewed-on: https://dart-review.googlesource.com/70462
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
We need to clarify the following case:
`dynamic foo() => print('');`,
`dynamic bar() { return print(''); }`
that is, using `return e` where `e` has type `void`, when the return
type of the enclosing function is `dynamic` (inferred or explicit).
We do not currently have any elements in the generalized-void.md
whitelist for that, so it's an error. However, invalid_returns.md
from https://dart-review.googlesource.com/c/sdk/+/60401 implies
(patchset 6: line 19-20 and 34-35) that it is allowed.
It is my impression that we agree on invalid_returns.md, and also
that it describes the current behavior (maybe not 100%?).
This indicates to me that we should, probably, add an element to
the above-mentioned whitelist to allow it.
This CL makes that change to generalized-void.md.
Change-Id: I0326081960deda907b3b4ff34bd2d60f7c9dc35b
Reviewed-on: https://dart-review.googlesource.com/64341
Reviewed-by: Erik Ernst <eernst@google.com>
The issue was raised recently that there must be generated forwarders
for some method signatures that we had not previously mentioned in
nosuchmethod-forwarders.md: Private methods with an inaccessible name,
that is, private methods declared in a different library than the
current target of nSM forwarder generation.
Given that such forwarders are semantically significant (a tear-off
performed in the library where the abstract private method declaration
is located would tear off a generated forwarder, rather than causing
an invocation of `noSuchMethod`), we need to specify this.
This CL adds such a specification to nosuchmethod-forwarders.md.
This CL addresses SDK issue #33725, and SDK issue #33727 is related
being concerned with the implementation in the common front
end.
Change-Id: Iedbcdd8b4c8df95c6038022f72b3211ec1b76649
Reviewed-on: https://dart-review.googlesource.com/64380
Reviewed-by: Erik Ernst <eernst@google.com>
This mostly documents and regularizes existing (post bug fix) semantics,
with a small additional restriction on returning `void` from an async
function.
Change-Id: Ic1a302aeb666fa73ca2b7e23072394490bb4fe76
Reviewed-on: https://dart-review.googlesource.com/60401
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
This CL adds a new feature specification for 'generic function
instantiation' (aka partial specialization, type-curried invocation,
etc.), which amounts to implicitly obtaining a non-generic function
from a denotation of a generic function when the typing requires the
latter.
This feature spec relies on type inference, but as a black box (so
it can hardly be incompatible with any current or future version of
type inference in Dart).
Note that it is a restricted version of generic function
instantiation which is specified here, it only supports global and
static functions and instance methods; function literals and first
class function values are not supported.
I just learned from Vijay (Mar 23, 3pm CET) that first class functions
_do_ support generic function instantiation in some existing
implementations. So maybe there is no problem supporting them, and
we should just eliminate that restriction?
Here is a rendered version of the document, refreshed to match patch
set 19: https://gist.github.com/eernstg/bf816d3495e9b87ab6eb958ba707d016
Change-Id: Ie1fd601d3e359bfb5f4616f8ec68a110f42e01b7
Reviewed-on: https://dart-review.googlesource.com/47043
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
This CL adds an example to super-bounded-types.md in order to motivate
the definition of what it means for a parameterized type based on a
type alias to be super-bounded. The definition says that we must check
the actual type arguments relative to the formal type parameter
list of the given `typedef` as well as the right hand side, replacing
the formals by the given actual type arguments. The example shows that
the right hand side can be ill-bounded even though the check that we
apply based on the formal type parameter bounds (that is, the check
that we apply to class types) succeeds.
A rendered version of super-bounded-types.md corresponding to patchset
6 is available here:
https://gist.github.com/eernstg/fc12eeb23064a2578a936b443461dde4.
Change-Id: I33dc6ced592f53160bc6f933558bfface46cd329
Reviewed-on: https://dart-review.googlesource.com/56668
Commit-Queue: Erik Ernst <eernst@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Sergey pointed out a couple of name clashes, and I renamed some indices
in order to avoid them. At the same time, I fixed a couple of typos
and adjusted the whitespace to be more similar to other *.md files.
Finally, I adjusted the wording involving 'algorithmic' and 'syntax
directed' in order to make it explicit that they stand for the same
thing.
Change-Id: Ic03b907f4bdc722d9ba218d38077addf9cc4a777
Reviewed-on: https://dart-review.googlesource.com/50981
Reviewed-by: Leaf Petersen <leafp@google.com>
In response to the discussions in SDK issue 32414 about the typing of
members of `Object` when the receiver type is `dynamic`.
A rendered version of this document is available at
https://gist.github.com/eernstg/fc0094b0230ea18b9507092e50dab537
(uploaded as of patchset 6).
Change-Id: I3a74ecd5e7c9c9c05fadda5b1fa0d644561796e9
Reviewed-on: https://dart-review.googlesource.com/46247
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Jenny Messerly <jmesserly@google.com>
As an example of a void-to-void data flow, consider `void x = foo();`,
where `foo` has return type `void`. In general, a void-to-void data
flow is a computation which is trivial (we may select one of two
branches in a conditional expression and otherwise only pass the value
on without any computation) where the expression being evaluated has
type void, and the target that receives the value is also of type
void.
This CL makes adjustments to generalized-void.md such that void-to-void
data flows are allowed.
Change-Id: Ia1722cd399c77c57cc5c61e9c10b7a84a18fe107
Reviewed-on: https://dart-review.googlesource.com/38060
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
It turns out that the special case for FutureOr<void> that I added in
https://dart-review.googlesource.com/c/sdk/+/35920 was misunderstood,
nobody really wanted it.
This CL removes all references to `FutureOr` in generalized-void.md,
which removes that special case and also the concept of types that are
"void equivalent" (because such types are not used any more).
The message here is that we are now more consistent in our protection
of developers against accidentally discarding a value which is
meaningful (just like `void foo() { return 42; }`), because they've
forgotten that the return type is `void`.
Change-Id: Ia4e6e00b2d33ff434923de7eb78d000cd7cc1c3e
Reviewed-on: https://dart-review.googlesource.com/41822
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
A similar rule applies to asynchronous for-in loops.
Change-Id: I88ba234c27a38167eaac0350d269e88894a0fe9e
Reviewed-on: https://dart-review.googlesource.com/35920
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
The language team several times agreed to make it an error when a
non-void expression `e` is used in `return e;` in the body of a
function whose return type is `void`.
When `void` is changed from a near-bottom type to a top type, the
wording in the language specification (dartLangSpec.tex) does _not_
ensure that this is an error, because all types are assignable to
`void`, so we need a specific rule saying that it is an error.
This CL adds such a rule to the feature spec for generalized void.
It also adds a rule that makes it an error to have return type `void`
in a function marked `async*` or `sync*`, based on the reasoning
that they "are returning a Future/Stream/Iterable semantically",
and it would now be an error if they did that explicitly.
Change-Id: I22fed9e9fc6097bb50100a151b964045e41ef173
Reviewed-on: https://dart-review.googlesource.com/35680
Reviewed-by: Leaf Petersen <leafp@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
Description which is relevant as of January 2018:
The more aggressive approach where `const` is inserted whenever
possible (for instance creation expressions) and whenever required
(for composite literals), and `new` is inserted otherwise, is now
the agreed policy. This means that the remaining discussion is on
the specification of this policy, not the policy itself. This has
been true approximately since Dec 1st, 2017.
Here is a brief overview of the feature which is specified in the
document added by this CL:
The introduction of 'implicit creation' adjusts the grammar such
that instance creation expressions (such as `new C()`) can always
omit the keyword (`new` or `const`). The semantics is that these
expressions will still invoke the same constructor (which may
produce a fresh instance in case of a generative constructor, and
some object that may or may not be new in case of a factory),
as if `new` or `const` had been added implicitly. The choice of
whether to add `new` or `const` is made according to the policy
described above.
----------------------------------------------------------------------
Original description, FYI:
Copy of Rietveld 3012703002: magic optional const
Adjusted informal spec optional-new to insert `const` whenever possible
The current version of optional-new.md specifies that `const` should be
inserted into certain syntactic phrases (when specific identifiers
satisfy some constraints), but only when these phrases occur in a const
context.
This CL changes that approach and specifies that `const` should also be
inserted outside const contexts, if the resulting expression is a
correct constant expression.
We haven't yet decided on whether we want the current (predictable)
model or we want the more "magic" one specified in this CL; this CL
is intended to be landed if we choose the latter, and discarded if we
choose the former.
Change-Id: I602e7eaf3d4c7904277af45c6f62089c77bd5117
Reviewed-on: https://dart-review.googlesource.com/3160
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
The covariant parameter related feature specs were written to specify
that overriding admits a type annotation `T` on a formal parameter as
long as `T <: S` or `S <: T` for every type annotation `S` on a
corresponding formal parameter in an overridden declaration (directly
or indirectly).
This CL changes the rules such that a covariant-from-class parameter
must satisfy the standard constraints (contravariance) instead, which
is needed in order to ensure that an important optimization (on self-
sends) is valid.
This makes the spec follow the actual implementation, i.e., the change
will not break any existing software.
Change-Id: Ic871cc16c09220a385d68d9ec32c7a06683db87b
Reviewed-on: https://dart-review.googlesource.com/37664
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
The Dart 1 specification of 'generic method syntax' had no status
indicator, it is now marked as 'background material' because generic
methods (in full) have been integrated into the language specification.
Several other changes of a similar nature.
Implication: It should now be possible for readers of these documents
to trust their status indication. As we go, we will need to update them
again, especially when something is integrated into the language
specification.
Do we want to migrate background material to another directory? Do we
want to rename the directory `informal` to `feature` or somesuch?
Change-Id: Ia3851bdbe7b5a46d71848c376906f95feb4db349
Reviewed-on: https://dart-review.googlesource.com/34663
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>