This CL is using an approach that does not rely on program
transformations (based on the idea in CL 50221 from Lasse).
I have taken the approach to make `constant list literal`, `constant
object expression` the higher level concepts, and define the notion of
a `constant context` in terms of the syntax (so it requires an actual
`\CONST{}` or a switch case in the enclosing syntax).
Doing this work, I encountered the section about postfix expressions,
and (like several times before), I noted that there was no
specification of the static analysis at all. So I cleaned up that
section, at the time where I needed to edit it already, because of
the new `constructorInvocation` syntax.
If that is helpful, I could split this CL into a pure "implicit
creation" CL and another "fix up postfix expressions" CL.
Change-Id: I669ce942f698ca2fbb47ea60c58f4f05304ae66d
Reviewed-on: https://dart-review.googlesource.com/c/93432
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Change-Id: I41e8f558fd4c3145637a7d2f09cc261815ab2161
Reviewed-on: https://dart-review.googlesource.com/c/84605
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
This CL just changes whitespace and formatting.
In particular, it replaces \syntax{`...'} by \lit{...} as much as
possible (because it's simpler and shorter, and \lit{...} works in
some situations where \syntax{...} does not).
Change-Id: Icd241a8c9d04280ff57041450aa342eb56d34589
Reviewed-on: https://dart-review.googlesource.com/c/90742
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
This was needed because we had a handful of long sentences, nearly
identical, specifying that operator == must not be overridden, except
if it's in a specific built-in class.
These locations have been adjusted several times because it's tricky,
and now we have this in just one location (so we won't forget to
include bool again, somewhere).
Note that this shows a couple of facts (this was already a consequence
of the wording in the language specification, but now it's explicit):
We can `switch` on constant lists, sets, maps, and function objects,
and similarly for element expressions in constant lists and sets, and
for keys in constant maps.
Bug: https://github.com/dart-lang/language/issues/188.
Change-Id: Ie54bce573ee577654b598926b711d6dc8eab6ff1
Reviewed-on: https://dart-review.googlesource.com/c/90462
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
.. 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>
little problems in the spec that we have noted over time.
Fixed a couple of LaTeX mistakes; adjusted FutureOr section
The 'Type FutureOr' section was adjusted in order to avoid duplicate
subtype rules (the ones that we have had in section 'Type FutureOr'
until now are duplicates of rules in \ref{subtypeRules}).
Also changed the name of \basetype to \futureOrBase, because the former
is too generic to be helpful for readers.
Change-Id: I8d83cf1a0af275a930fbbb94cf59a9d758066583
Reviewed-on: https://dart-review.googlesource.com/c/90061
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Change-Id: I0008f74c75da28fbf38a959e2925b72dd1dfd38f
Reviewed-on: https://dart-review.googlesource.com/c/88563
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Currently, this kind of clash is an error when there is a declaration
at which the conflict is known to be an error, but it was not an error
when it occurs because a class `implements` two other classes where one
provides the getter/setter and the other provides the method.
Note to implementors: The analyzer apparently already flags this
situation as an error, so the change should be non-breaking, and if
implementation changes are needed at all it would most likely only be
in other tools.
Bug: https://github.com/dart-lang/sdk/issues/35561
Change-Id: I7f55b8995829ad64b86ebf33045b235813fc5161
Reviewed-on: https://dart-review.googlesource.com/c/88455
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
It has implementation consequences to refer to classes that are not
declared in dart:core, and it increases the library/spec interaction surface.
This change removes all references to `LinkedHashSet` from the spec.
It changess the rule for when a `{}` is a set to be
context type is a subtype of `FutureOr^\inf(Iterable<Object>)`
and not a subtupe of `FutureOr^\inf(Map<Object,Object>)`.
That should *work* for
* `Iterable<X>`
* `Set<X>`
* `LinkedHashSet<X>`
* `HashSet<X>`
* `FutureOr<Set<X>>`
(with likely exect-type issues as usual).
Change-Id: I3074da27b36093075c8c83e9672bf2fdec135c1c
Reviewed-on: https://dart-review.googlesource.com/c/87972
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Erik Ernst <eernst@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>
Needs some iterations of sanity checks, but has the expected shape
for it all at this point.
Change-Id: Idd96efa95d65ad6bd202b694c9d1f297cf04a8b6
Reviewed-on: https://dart-review.googlesource.com/c/86660
Reviewed-by: Leaf Petersen <leafp@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>
This is already implemented by all platforms and may be in use.
Also clean up redundant requirements for constant literals and
object expressions. There is no need to check whether `x` is constant
in order to allow `const [x]` as a potentially constant expression.
We will get a compile-time error anyway if it isn't, because that is
written explicitly for constant map literals.
Similarly for map literals and constant object expressions.
Change-Id: I425489ff3c0063fa59937978267b13ee68aa039d
Reviewed-on: https://dart-review.googlesource.com/c/81274
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Changed "compile-time warning" to "static warning"; eliminated spurious
space at the beginning of each normative paragraph; added index and
changed all `{\em ..}` containing defining occurrences of words and
phrases such that they are added to the index and marked with a
diamond in the margin (to make it easy to spot definitions).
Change-Id: I688561a24d2b9955f383d6c8db2c913353d41b4b
Reviewed-on: https://dart-review.googlesource.com/c/82501
Reviewed-by: Lasse R.H. Nielsen <lrn@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>
Also mention it in the `external const factory Symbol` constructor.
This only relevant for constant expressions that may be used as
switch case expressions or constant map keys.
See #32557.
Bug: http://dartbug.com/32557
Change-Id: Ie82799f3f0d39c21c10765338a7dfeb74a582add
Reviewed-on: https://dart-review.googlesource.com/c/81242
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Partially resolves issue #34349.
Also note that #34365 and #34319 are affected by this change.
Change-Id: I1d9023464090ff2c07f9dc062353202ddb82ba25
Reviewed-on: https://dart-review.googlesource.com/c/78121
Reviewed-by: Leaf Petersen <leafp@google.com>
This makes some parts of the specification explicit,
and rephrases it so that it is easier to recognize the separate cases.
Change-Id: Ifdbb5c11ec3b3fe80737642f230ee291a18a5841
Reviewed-on: https://dart-review.googlesource.com/c/80824
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Erik Ernst <eernst@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>
Also fix some typos.
Change-Id: Id8ed6d22c9e7c900c4062b2cbc5b68abf93d11ba
Reviewed-on: https://dart-review.googlesource.com/c/77080
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Jenny Messerly <jmesserly@google.com>
Reviewed-by: Erik Ernst <eernst@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>
.. and always use a plain `constant` in normative text. Also fixed a few
LaTeX issues.
Change-Id: I5682f5c5b22120691c620144318f0670c4ba0a24
Reviewed-on: https://dart-review.googlesource.com/76980
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
The existing specification was underspecifying potentially constant expressions,
effectively relying on evaluation to determine whether an expression was
potentially constant.
This change specifies potentially constant recursively using only the syntax
of the expressions.
Adds short-circuting to `?:`, `??`, `||` and `&&` expressions,
so for `String x`, the expression `x != null && x.length > 0`
is compile-time constant.
The original specification requred evaluation of the latter half
even when `x` is null. We can now avoid this because we can require that the
unused expression is a potentially constant expression without having to
check if it, or any part of it, is a compile-time constant expression.
Allows `x == null` and `x != null` as compile-time constant expression
independently of the type of `x`.
Allows `e as T` as a compile-time constant expression. Types are more
important in Dart 2, so you need a way to adjust typing in some cases,
even in compile-time constant expressions.
Change-Id: I02bf0b77013c3b3ced8cd46334db378787cc2d57
Reviewed-on: https://dart-review.googlesource.com/36220
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
We should avoid the situation where `class C extends A with M {}`
requires generation of noSuchMethod forwarders _in the superclass
`A with M`_ when neither `A` nor `M` has an implementation of
`foo`, but `A with M` has a non-trivial noSuchMethod.
If we _do_ generate those nSM forwarders, that will just obscure that
any attempt to invoke `super.foo()` in `C` should be an error.
Note that this is about generating forwarders _in the mixin application
which is the superclass_, it is not about copy-down of forwards from
the class `M` that was used to obtain the mixin in the first place.
Also note that it would be inconvenient to require all methods to be
implemented in `A with M` as used in `abstract C extends A with M {}`,
and it would also be rather funny if we were to say that `A with M` is
abstract when `C` is abstract, and concrete when `C` is concrete.
So I think the only reasonable choice is to make those superclasses
which are mixin applications abstract.
Note that dart:mirrors ought to reflect this, in a separate issue,
if it is not already the case.
Change-Id: If221b2c73b17bd55017d4d5ee4fdb8daf203e195
Reviewed-on: https://dart-review.googlesource.com/76640
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Also update type dynamic and other sections especially affected.
Change-Id: I432992b8190f13b2aea73d524fc9b17d3ef24b41
Reviewed-on: https://dart-review.googlesource.com/75340
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Also corrected some "includes" to "has" when talking about members of
an interface.
Change-Id: Ib8917c2a9f40fce82ab1e41e0e766c87065b168a
Reviewed-on: https://dart-review.googlesource.com/75880
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Also fixed many syntax related glitches.
Change-Id: I926b93a54ad28d05389a44c969fc2288933f8584
Reviewed-on: https://dart-review.googlesource.com/75580
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>