\documentclass[makeidx]{article}
\usepackage{xspace}
\usepackage{epsfig}
\usepackage{xcolor}
\usepackage{syntax}
\usepackage[fleqn]{amsmath}
\usepackage{amssymb}
\usepackage{semantic}
\usepackage{dart}
\usepackage[hidelinks]{hyperref}
\usepackage{lmodern}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\makeindex
\title{Dart Programming Language Specification\\
{6th edition draft}\\
{\large Version 2.13-dev}}
\author{}

% For information about Location Markers (and in particular the
% commands \LMHash and \LMLabel), see the long comment at the
% end of this file.

% CHANGES
% =======
%
% Significant changes to the specification. Note that the versions specified
% below indicate the current tool chain version when those changes were made.
% In practice, new features have always been integrated into the language
% specification (this document) a while after the change was accepted into
% the language and implemented. As of September 2022, the upcoming version of
% the language which is being specified is indicated by a version number in
% parentheses after the tool chain version.
%
% Note that the version numbers used below (up to 2.15) were associated with
% the currently released language and tools at the time of the spec change,
% they were not aligned with the actual version of the language which is being
% specified in that version of this document. This is highly misleading, so we
% changed the subtitles to be a month rather than a version number. Similarly,
% the 'Version' specified on the front page has been changed to indicate the
% version of the language which will actually be specified by the next stable
% release of this document.
%
% Oct 2025
% - Simplify the member declaration grammar by using a single `memberDeclaration`
%   to derive all kinds of member declarations (for a class, a mixin, etc),
%   rather than having a dedicated `classMemberDeclaration`.
%
% Sep 2025
% - Remove the rules about DartDoc comments. This topic is now handled by each
%   of the tools that process those comments in any way.
%
% Jul 2025
% - Clarify that operator `[]` and `[]=` are included in the `void` allowlist
%   rule about formal parameters of type `void`, and so are setters.
%
% May 2025
% - Add `s?.length` as a constant expression in the case where `s` satisfies
%   some requirements.
%
% Apr 2025
% - Change the rules about constants to be more consistent: Every constant
%   expression is also a potentially constant expression. Also, eliminate
%   redundancies in the rules about constant collection literals and constant
%   object expressions (they are now defined just once, outside 'Constants').
%
% Sep 2024
% - Clarify the extension applicability rule to explicitly state that it
%   is concerned with an instance member with the same basename, not a
%   static member.
%
% Jun 2024
% - Add missing references to section 'Type dynamic' at the points where the
%   static analysis of Object member invocations is specified.
%
% Feb 2024
% - Correct the rule about deriving a future type from a type (which is used
%   by `flatten`).
%
% Dec 2023
% - Allow `~/` on operands of type `double` in constant expressions, aligning
%   the specification with already implemented behavior.
% - Broaden the grammar rule about `initializerExpression` to match the
%   implemented behavior. Specify that an initializer expression can not be
%   a function literal.
% - Specify in which situations it is an error to declare an initializing
%   formal parameter.
%
% Nov 2023
% - Specify that the dynamic error for calling a function in a deferred and
%   not yet loaded library will occur before actual argument evaluation, not
%   after.
%
% Oct 2023
% - Introduce the rule that an `extension` declaration cannot have the name
%   `type`. This is needed in order to disambiguate an `extension type`
%   named `on`.
%
% Aug 2023
% - Correct text about built-in identifier error and turn it into commentary
%   (the normative text is in grammar rules using `typeIdentifier`), and
%   correct the grammar for import prefixes to use `typeIdentifier`.
%
% Jul 2023
% - Land the null-safety updates for sections about variables.
% - Change terminology: A 'static variable' is now a variable whose declaration
%   includes `static` (which used to be called a 'class variable'); the old
%   meaning of 'static variable' is now never used (we spell out every time
%   that it is a 'library variable or a static variable', where the latter is
%   the new meaning of that phrase). This avoids the confusion that came up
%   just about every single time the phrase 'static variable' came up in a
%   discussion.
% - Change terminology: The notion of 'mutable' and 'immutable' variables has
%   been eliminated (it is spelled out each time which modifiers must be
%   present or not present). The concept is confusing now where a variable can
%   be late and final, and assignments to it are allowed by the static analysis.
% - Change the definition of the 'element type of a generator function', due to
%   soundness issue with the current definition.
%
% Mar 2023
% - Clarify how line breaks are handled in a multi-line string literal. Rename
%   the lexical token NEWLINE to LINE\_BREAK (clarifying that it is not `\n`).
% - Clean up grammar rules (avoid `T?` as a superclass/etc., which is an
%   error anyway; change extension names to `typeIdentifier`, avoiding
%   built-in identifiers).
%
% Feb 2023
% - Change the specification of constant expressions of the form `e1 == e2`
%   to use primitive equality.
%
% Dec 2022
% - Change the definition of the type function 'flatten' to resolve soundness
%   issue, cf. SDK issue #49396.
% - Introducing null-safety related changes to the sections about variables
%   and local variables.
% - Change 'primitive operator ==' to 'primitive equality', and include
%   constraints on `hashCode` corresponding to the ones we have on `==`.
%
% 2.15
% - Allow generic instantiation of expressions with a generic function type
%   (until now, it was an error unless the expression denoted a declaration).
% - Allow generic instantiation of the `call` method of a function object.
% - Clarify that `TypeLiteral.extensionMethod()` is an error, in line with the
%   error for `int.toString()`.
% - Add support for function closurization for callable objects, in the sense
%   that `o` is desugared as `o.call` when the context type is a function type.
% - Clarify the treatment of `covariant` parameters in the interface of a class
%   that inherits an implementation where those parameters are not covariant.
% - Adjust and clarify simple string interpolation (to allow `'$this'`, which
%   is already implemented and useful).
% - Add several lexical rules about identifiers, clarifying different kinds.
% - Clarify the conflicts between extension members and `Object` instance
%   members.
% - Correct <partDeclaration> to include metadata.
% - Clarify the section about assignable expressions.
%
% 2.14
% - Add constraint on type of parameter which is covariant-by-declaration in
%   the case where the method is inherited (that case was omitted by mistake).
% - Clarify symbol equality and identity.
%
% 2.12 - 2.13 (there was no 2.11)
% - Revert the CL where certain null safety features were removed (to enable
%   publishing a stable version of the specification).
% - Add rule that a top-level pair of declarations with the same basename
%   is a compile-time error except when it is a getter/setter pair.
% - Change grammar to enable non-function type aliases. Correct rule for
%   invoking `F.staticMethod()` where `F` is a type alias.
% - Add missing error for cyclic redirecting generative constructor.
%
% 2.8 - 2.10
% - Change several warnings to compile-time errors, matching the actual
%   behavior of tools.
% - Eliminate error for library name conflicts in imports and exports.
% - Clarify the specification of initializing formals. Fix error: Add
%   missing `?` at the end for function typed initializing formal.
% - Adjust specification of JS number semantics.
% - Revise and clarify the sections Imports and Exports.
% - Bug fix: Change <qualifiedName> to omit the single identifier, then add it
%   back when <qualifiedName> is used, as <typeIdentifier> resp. <identifier>.
% - Clarify that a function-type bounded receiver has a `.call` method.
% - Merge the `static' and `instance' scope of a class, yielding a single
%   `class' scope.
% - Add specification of `>>` in JavaScript compiled code, in appendix.
% - Integrate the specification of extension methods into this document.
% - Specify identifier references denoting extension members.
% - Remove a few null safety features, to enable publishing a stable
%   version of the specification which is purely about Dart 2.10.
% - Reorganize specification of type aliases to be in section `Type Aliases'
%   (this used to be both there, and in 'Generics').
% - Clarify the cyclicity error for type aliases ("F is not allowed to depend
%   on itself).
% - Add the error for a type alias $F$ used in an instance creation etc., when
%   $F$ expands to a type variable.
% - Correct lexical lookup rules to include implicit extension method
%   invocation.
%
% 2.7
% - Rename non-terminals `<...Definition>` to `<...Declaration>` (e.g., it is
%   'class declaration' everywhere, so `<classDefinition>` is inconsistent).
% - Clarify that <libraryDeclaration> and <partDeclaration> are the
%   start symbols of the grammar.
% - Clarify the notion of being `noSuchMethod forwarded': `m` is indeed
%   noSuchMethod forwarded if an implementation of `m` is inherited, but
%   it does not have the required signature.
% - Clarify static checks on `yield` and `yield*` to explicitly ensure that
%   assignability is enforced per element.
% - Update whitelist for expressions of type void to include `await e`,
%   consistent with decision in SDK issue #33415.
% - Re-adjust `yield*` rules: Per-element type checks are not supported,
%   the given Iterable/Stream must have a safe element type.
% - Clarify that an expression of type `X extends T` can be invoked when
%   `T` is a function type, plus other similar cases.
% - Specify actual type arguments passed to a generic function which is invoked
%   with no type arguments (so it must be a dynamic invocation).
%
% 2.6
% - Specify static analysis of a "callable object" invocation (where
%   the callee is an instance of a class that has a `call` method).
% - Specify that <libraryImport> string literals cannot use string
%   interpolation; specify that it is a dynamic error for `loadLibrary`
%   to load a different library than the one which was used for
%   compile-time checks.
% - Specify that a constant expression `e.length` can only invoke an instance
%   getter (in particular, it cannot execute/tear-off an extension member);
%   similar changes were made for several operators.
% - Specify the type arguments of the fields of an `Invocation` received by
%   `noSuchMethod`, when invoked in response to a failed instance member
%   invocation.
%
% 2.4
% - Clarify the section `Exports'.
% - Update grammar rules for <declaration>, to support `static late final`
%   variables with no initializer; for several top-level declarations,
%   to correct the existence and placement of <metadata>; for
%   <assignableSelectorPart>, to simplify the grammar (preserving the
%   derivable terms); for <topLevelDeclaration>, to allow top-level final
%   and const variables with no type, and to allow `late final` top-level
%   variables, to allow `late` on a top-level variable declaration; and
%   adding <namedParameterType> to allow `required` parameters.
% - Make lexical identifier lookups use the rules for 'Identifier Reference'
%   consistently; that is, always look up `id` as well as `id=`, and commit
%   to the kind of declaration found by that lookup.
% - Specify the signature of the `call` method of a function object.
% - Add the rule that it is an error for a type variable of a class to occur
%   in a non-covariant position in a superinterface.
% - Correct several grammar rules, including: added <functionExpressionBody> (to
%   avoid semicolon in <functionBody>), adjusted <importSpecification>.
% - Revise section on cascades. Now uses compositional grammar, and
%   specifies static type, compile-time errors, and includes `?..`.
% - Correct the grammar and lexical rules for string literals.
% - Change specification of `await` to be type-safe, avoiding cases like:
%       FutureOr<Future<S>> ffs = Future<S>.value(s);
%       Future<S> fs = await ffs;
%
% 2.3
% - Add requirement that the iterator of a for-in statement must have
%   type `Iterator`.
% - Clarify which constructors are covered by the section 'Constant
%   Constructors' and removed confusing redundancy in definiton of
%   potentially constant expressions.
% - Integrate the feature specification of collection literal elements
%   (aka UI-as-code).
%
% 2.2
% - Specify whether the values of literal expressions override Object.==.
% - Allow Type objects as case expressions and const map keys.
% - Introduce set literals.
% - Specify that a getter/setter and a method with the same basename is
%   an error, also in the case where a class obtains both from its
%   superinterfaces.
% - Specify the Dart 2.0 rule that you cannot implement, extend or mix-in
%   Function.
% - Generalize specification of type aliases such that they can denote any
%   type, not just function types.
% - Clarify that 'Constant Constructors' is concerned with non-redirecting
%   generative constructors only.
%
% 2.1
% - Remove 64-bit constraint on integer literals compiled to JavaScript numbers.
% - Allow integer literals in a double context to evaluate to a double value.
% - Specify dynamic error for a failing downcast in redirecting factory
%   constructor invocation.
% - Specify that type arguments passed in a redirecting factory constructor
%   declaration must be taken into account during static checks.
% - Disallow any expression statement starting with `{`, not just
%   those that are map literals.
% - Define a notion of lookup that is needed for superinvocations, adjust
%   specification of superinvocations accordingly.
% - Specify that it is a dynamic error to initialize a non-static variable
%   with an object that does not have the declared type (e.g., a failed cast).
% - Specify for constructor initializers that target variable must exist and
%   the initializing expression must have a type which is assignable to its
%   type.
% - Specify for superinitializers that the target constructor must exist and
%   the argument part must have a matching shape and pass type and value
%   arguments satisfying the relevant constraints.
% - Reword rules about abstract methods and inheritance to use 'class
%   interface'.
% - Specify that it is an error for a concrete class with no non-trivial
%   \code{noSuchMethod} to not have a concrete declaration for some member
%   in its interface, or to have one which is not a correct override.
% - Use \ref{bindingActualsToFormals} in 3 locations, eliminating 2 extra
%   copies of nearly the same text.
% - Add figure in \ref{bindingActualsToFormals} for improved readability.
% - Introduce a notion of lookup which is needed for superinvocations.
% - Use new lookup concept to simplify specification of getter, setter, method
%   lookup.
% - Introduce several `Case<SomeTopic>` markers in order to improve
%   readability.
% - Reorganize several sections to specify static analysis first and then
%   dynamic semantics; clarify many details along the way. The sections are:
%   \ref{variables}, \ref{new}, \ref{const}, \ref{bindingActualsToFormals},
%   \ref{unqualifiedInvocation}, \ref{functionExpressionInvocation},
%   \ref{superInvocations}, \ref{assignment}, \ref{compoundAssignment},
%   \ref{localVariableDeclaration}, and \ref{return}.
% - Corrected error involving multiple uses of the same part in the same
%   program such that it takes exports into account.
% - Eliminate all references to checked and production mode, Dart 2 does
%   not have modes.
% - Integrate feature specification on noSuchMethod forwarders.
% - Specify that bound satisfaction in generic type alias type parameters
%   must imply bound satisfaction everywhere in the body.
% - Specify that super-bounded generic type alias applications must trigger
%   a well-boundedness check on all types occurring in the denoted type.
% - Corrected corner case of rules for generation of noSuchMethod forwarders.
% - Integrate feature specification on parameters that are
%   covariant-by-declaration.
% - Integrate feature specification on parameters that are
%   covariant-by-class.
% - Correct section 'Type of a function', allowing for adjustments needed
%   for rules related to covariant parameters.
% - Specified the dynamic type of function objects in several contexts, such
%   that the special treatment of covariant parameters can be mentioned.
% - Specified what it means for an override relation to be correct, thus
%   adding the parts that are not captured by a function type subtype check.
% - Introduced the notion of member signatures, specified that they are the
%   kind of entity that a class interface contains.
% - Corrected super-boundedness check to take variance into account at the
%   top level.
%
% 2.0
% - Don't allow functions as assert test values.
% - Start running "async" functions synchronously.
% - It is a static warning and dynamic error to assign to a final local.
% - Specify what "is equivalent to" means.
% - Remove @proxy.
% - Don't specify the exact object used for empty positionalArguments and
%   namedArguments on Invocation.
% - Remove the, now unnecessary, handling of invalid overrides of noSuchMethod.
% - Add >>> as overridable operator.
% - If initializing formal has type annotation, require subtype of field type.
% - Constant `==` operations now also allowed if just one operand is null.
% - Make flatten not be recursive.
% - Disallow implementing two instantiations of the same generic interface.
% - Update "FutureOr" specification for Dart 2.0.
% - Require that a top-level "main" declaration is a valid script-entry
%   function declaration.
% - State that the return type of a setter or []= is void when not specified.
% - Clarify that "noSuchMethod" must be implemented, not just redeclared
%   abstractly, to eliminate certain diagnostic messages.
% - Add generic functions and methods to the language.
% - Don't cause warning if a non-system library import shadows a system library.
% - Update mixin application forwarding constructors to correctly handle
%   optional parameters and const constructors.
% - Specify `call` for Dart 2 (no function type given to enclosing class).
% - Clarify that an identifier reference denoting a top-level, static, or
%   local function evaluates to the closurization of that declaration.
% - Make `mixin` and `interface` built-in identifiers.
% - Make `async` *not* a reserved word inside async functions.
% - Add 'Class Member Conflicts', simplifying and adjusting rules about
%   member declaration conflicts beyond "`n` declared twice in one scope".
% - Specify that integer literals are limited to signed 64-bit values,
%   and that the `int` class is intended as signed 64-bit integer, but
%   that platforms may differ.
% - Specify variance and super-bounded types.
% - Introduce `subterm' and `immediate subterm'.
% - Introduce `top type'.
% - Specify configurable imports.
% - Specify the dynamic type of the Iterable/Future/Stream returned from
%   invocations of functions marked sync*/async/async*.
% - Add appendix listing the major differences between 64-bit integers
%   and JavaScript integers.
% - Remove appendix on naming conventions.
% - Make it explicit that "dynamic" is exported from dart:core.
% - Remove "boolean conversion". It's just an error to not be a bool.
% - Adjust cyclic subtype prevention rule for type variables.
% - Clarify that it is an error to use FutureOr<T> as a superinterface etc.
% - Eliminate the notion of static warnings, all program faults are now errors.
% - It is no longer an error for a getter to have return type `void`.
% - Specify that each redirection of a constructor is checked, statically and
%   dynamically.
% - Specify that it is an error for a superinitializer to occur anywhere else
%   than at the end of an initializer list.
% - Update the potentially/compile-time constant expression definitions
%   so that "potentially constant" depends only on the grammar, not the types
%   of sub-expressions.
% - Make `==` recognize `null` and make `&&` and `||` short-circuit in constant
%   expressions.
% - Add `as` and `is` expressions as constant expressions
% - Make `^`, `|` and `&` operations on `bool` constant operations.
% - Integrate subtyping.md. This introduces the Dart 2 rules for subtyping,
%   which in particular means that the notion of being a more specific type
%   is eliminated, and function types are made contravariant in their
%   parameter types.
% - Integrate instantiation to bound. This introduces the notions of raw
%   types, the raw-depends relation, and simple bounds; and it specifies
%   the algorithm which is used to expand a raw type (e.g., `C`) to a
%   parameterized type (e.g., `C<int>`).
% - Integrate invalid_returns.md. This replaces the rules about when it is
%   an error to have `return;` or `return e;` in a function.
% - Integrate generalized-void.md. Introduces syntactic support for using
%   `void` in many new locations, including variable type annotations and
%   actual type arguments; also adds errors for using values of type `void`.
% - Integrate implicit_creation.md, specifying how some constant expressions
%   can be written without `const`, and all occurrences of `new` can be
%   omitted.
%
% 1.15
% - Change how language specification describes control flow.
% - Object initialization now specifies initialization order correctly.
% - Specifies that leaving an await-for loop must wait for the subscription
%   to be canceled.
% - An await-for loop only pauses the subscription if it does something async.
% - Assert statements allows a "message" operand and a trailing comma.
% - The Null type is now considered a subtype of all types in most cases.
% - Specify what NEWLINE means in multiline strings.
% - Specified the FutureOf type.
% - Asserts can occur in initializer lists.
%
% 1.14
% - The call "C()" where "C" is a class name, is a now compile-time error.
% - Changed description of rewrites that depended on a function literal.
%   In many cases, the rewrite wasn't safe for asynchronous code.
% - Removed generalized tear-offs.
% - Allow "rethrow" to also end a switch case. Allow braces around switch cases.
% - Allow using `=` as default-value separator for named parameters.
% - Make it a compile-time error if a library includes the same part twice.
% - Now more specific about the return types of sync*/async/async* functions
%   in relation to return statements.
% - Allow Unicode surrogate values in String literals.
% - Make an initializing formal's value accessible in the initializer list.
% - Allow any expression in assert statements (was only conditionalExpression).
% - Allow trailing commas in argument and parameter lists.
%
% 1.11 - ECMA 408 - 4th Edition
% - Specify that potentially constant expressions must be valid expressions
%   if the parameters are non-constant.
% - Make "??" a compile-time constant operator.
% - Having multiple unnamed libraries no longer causes warnings.
% - Specify null-aware operators for static methods.
%
% 1.10
% - Allow mixins to have super-classes and super-calls.
% - Specify static type checking for the implicit for-in iterator variable.
% - Specify static types for a number of expressions where it was missing.
% - Make calls on the exact type "Function" not cause warnings.
% - Specify null-aware behavior of "e?.v++" and similar expressions.
% - Specify that `package:` URIs are treated in an implementation dependent way.
% - Require warning if for-in is used on object with no "iterator" member.
%
% 1.9 - ECMA-408 - 3rd Edition
%

\begin{document}
\maketitle
\tableofcontents

\newpage

\pagestyle{myheadings}
\markright{Dart Programming Language Specification}


% begin Ecma boilerplate
\section{Scope}
\LMLabel{ecmaScope}

\LMHash{}%
This Ecma standard specifies the syntax and semantics of
the Dart programming language.
It does not specify the APIs of the Dart libraries
except where those library elements are essential to
the correct functioning of the language itself
(e.g., the existence of class \code{Object} with methods
such as \code{noSuchMethod}, \code{runtimeType}).


\section{Conformance}
\LMLabel{ecmaConformance}

\LMHash{}%
A conforming implementation of the Dart programming language
must provide and support all the APIs
(libraries, types, functions, getters, setters,
whether top-level, static, instance or local)
mandated in this specification.

\LMHash{}%
A conforming implementation is permitted to provide additional APIs,
but not additional syntax,
except for experimental features.


\section{Normative References}
\LMLabel{ecmaNormativeReferences}

\LMHash{}%
The following referenced documents are indispensable for
the application of this document.
For dated references, only the edition cited applies.
For undated references, the latest edition of the referenced document
(including any amendments) applies.

\begin{enumerate}
\item
  The Unicode Standard, Version 5.0, as amended by Unicode 5.1.0, or successor.
\item
  Dart API Reference, https://api.dartlang.org/
\end{enumerate}


\section{Terms and Definitions}
\LMLabel{ecmaTermsAndDefinitions}

\LMHash{}%
Terms and definitions used in this specification are given in
the body of the specification proper.
% End Ecma Boilerplate


\section{Notation}
\LMLabel{notation}

\LMHash{}%
We distinguish between normative and non-normative text.
Normative text defines the rules of Dart.
It is given in this font.
At this time, non-normative text includes:

\begin{itemize}
\item[Rationale]
  Discussion of the motivation for language design decisions appears in italics.
\rationale{%
  Distinguishing normative from non-normative helps clarify
  what part of the text is binding and what part is merely expository.%
}
\item[Commentary]
  Comments such as
  ``\commentary{%
    The careful reader will have noticed
    that the name Dart has four characters%
  }''
  serve to illustrate or clarify the specification,
  but are redundant with the normative text.
\commentary{%
  The difference between commentary and rationale can be subtle.%
}
\rationale{%
  Commentary is more general than rationale,
  and may include illustrative examples or clarifications.%
}
\end{itemize}

\LMHash{}%
Reserved words and built-in identifiers
(\ref{identifierReference})
appear in {\bf bold}.

\commentary{%
  Examples would be \SWITCH{} or \CLASS.%
}

\LMHash{}%
Grammar productions are given in a common variant of EBNF.
The left hand side of a production ends with `\lit{::=}'.
On the right hand side, alternation is represented by vertical bars,
and sequencing by spacing.
As in PEGs, alternation gives priority to the left.
Optional elements of a production are suffixed by a question mark
like so: \code{anElephant?}.
Appending a star to an element of a production means
it may be repeated zero or more times.
Appending a plus sign to a production means it occurs one or more times.
Parentheses are used for grouping.
Negation is represented by prefixing an element of a production with a tilde.
Negation is similar to the not combinator of PEGs,
but it consumes input if it matches.
In the context of a lexical production it consumes
a single character if there is one;
otherwise, a single token if there is one.

\commentary{%
  An example would be:%
}

\begin{grammar}\color{commentaryColor}
<aProduction> ::= <anAlternative>
  \alt <anotherAlternative>
  \alt <oneThing> <after> <another>
  \alt <zeroOrMoreThings>*
  \alt <oneOrMoreThings>+
  \alt <anOptionalThing>?
  \alt (<some> <grouped> <things>)
  \alt \gtilde<notAThing>
  \alt `aTerminal'
  \alt <A\_LEXICAL\_THING>
\end{grammar}

\LMHash{}%
Both syntactic and lexical productions are represented this way.
Lexical productions are distinguished by their names.
The names of lexical productions consist exclusively of
upper case characters and underscores.
As always, within grammatical productions,
whitespace and comments between elements of the production
are implicitly ignored unless stated otherwise.
Punctuation tokens appear in quotes.

\LMHash{}%
Productions are embedded, as much as possible,
in the discussion of the constructs they represent.

\LMHash{}%
A \Index{term} is a syntactic construct.
It may be considered to be a piece of text which is derivable in the grammar,
and it may be considered to be a tree created by such a derivation.
An \Index{immediate subterm} of a given term $t$ is a syntactic construct
which corresponds to an immediate subtree of $t$
considered as a derivation tree.
A \Index{subterm} of a given term $t$ is $t$,
or an immediate subterm of $t$,
or a subterm of an immediate subterm of $t$.

\LMHash{}%
A list \DefineSymbol{x_1, \ldots, x_n} denotes any list of
$n$ elements of the form $x_i, 1 \le i \le n$.
Note that $n$ may be zero, in which case the list is empty.
We use such lists extensively throughout this specification.

\BlindDefineSymbol{j, y_j, x_j}%
\LMHash{}%
For $j \in 1 .. n$,
let $y_j$ be an atomic syntactic entity (like an identifier),
$x_j$ a composite syntactic entity (like an expression or a type),
and \DefineSymbol{E} again a composite syntactic entity.
The notation
\IndexCustom{$[x_1/y_1, \ldots, x_n/y_n]E$}{[x1/y1, ..., xn/yn]E@$[x/y\ldots]E$}
then denotes a copy of $E$
in which each occurrence of $y_i, 1 \le i \le n$ has been replaced by $x_i$.

\LMHash{}%
This operation is also known as \Index{substitution},
and it is the variant that avoids capture.
That is, when $E$ contains a construct that introduces $y_i$ into
a nested scope for some $i \in 1 .. n$,
the substitution will not replace $y_i$ in that scope.
Conversely, if such a replacement would put an identifier \id{}
(a subterm of $x_i$) into a scope where \id{} is declared,
the relevant declarations in $E$ are systematically renamed to fresh names.

\commentary{%
  In short, capture freedom ensures that the ``meaning'' of each identifier
  is preserved during substitution.%
}

\LMHash{}%
We sometimes abuse list or map literal syntax, writing \code{[\List{o}{1}{n}]}
(respectively \code{\{$k_1$:\ $o_1$, \ldots, $k_n$:\ $o_n$\}})
where the $o_i$ and $k_i$ may be objects rather than expressions.
The intent is to denote a list (respectively map) object
whose elements are the $o_i$
(respectively, whose keys are the $k_i$ and values are the $o_i$).

\LMHash{}%
\BlindDefineSymbol{x, op, y}%
The specifications of operators often involve statements such as
\code{$x$ \metavar{op} $y$} is equivalent to the method invocation
\IndexCustom{\rm\code{$x$.\metavar{op}($y$)}}{%
  x.op(y)@\code{$x$.\metavar{op}($y$)}}.
Such specifications should be understood as a shorthand for:

\begin{itemize}
\item
  $x$ $op$ $y$ is equivalent to the method invocation
  \code{$x$.\metavar{op'}($y$)},
  assuming the class of $x$ actually declared a non-operator method named $op'$
  defining the same function as the operator $op$.
\end{itemize}

\rationale{%
  This circumlocution is required because
  {\rm\code{$x$.\metavar{op}($y$)}}, where op is an operator,
  is not legal syntax.
  However, it is painfully verbose, and we prefer to state this rule once here,
  and use a concise and clear notation across the specification.%
}

\LMHash{}%
When the specification refers to the order given in the program,
it means the order of the program source code text,
scanning left-to-right and top-to-bottom.

\LMHash{}%
When the specification refers to a
\IndexCustom{fresh variable}{variable!fresh},
it means a local variable with a name that doesn't occur anywhere
in the current program.
When the specification introduces a fresh variable bound to an object,
the fresh variable is implicitly bound in a surrounding scope.

\LMHash{}%
References to otherwise unspecified names of program entities
(such as classes or functions)
are interpreted as the names of members of the Dart core library.

\commentary{%
  Examples would be the classes \code{Object} and \code{Type}
  representing, respectively, the root of the class hierarchy and
  the reification of run-time types.
  %
  It would be possible to declare, e.g.,
  a local variable named \code{Object},
  so it is generally incorrect to assume that
  the name \code{Object} will actually resolve to said core class.
  However, we will generally omit mentioning this, for brevity.%
}

%% TODO(eernst): We need to get rid of the concept of `is equivalent to`,
%% cf. language issue https://github.com/dart-lang/language/issues/227.
%% In this CL the phrase `treated as` has been introduced in a few places,
%% and the above-mentioned issue 227 will give rise to a complete revision
%% of this aspect of this document. In particular, the next paragraph will
%% be deleted.

\LMHash{}%
When the specification says that one piece of syntax \Index{is equivalent to}
another piece of syntax, it means that it is equivalent in all ways,
and the former syntax should generate the same compile-time errors
and have the same run-time behavior as the latter, if any.
\commentary{%
  Error messages, if any, should always refer to the original syntax.%
}
If execution or evaluation of a construct is said to be
equivalent to execution or evaluation of another construct,
then only the run-time behavior is equivalent,
and compile-time errors apply only for the original syntax.

\LMHash{}%
\BlindDefineSymbol{s, s'}%
When the specification says that one piece of syntax $s$ is
\Index{treated as}
another piece of syntax $s'$,
it means that the static analysis of $s$ is the static analysis of $s'$
\commentary{(in particular, exactly the same compile-time errors occur)}.
Moreover, if $s$ has no compile-time errors then
the behavior of $s$ at run time is exactly the behavior of $s'$.

\rationale{%
  Error \emph{messages}, if any,
  should always refer to the original syntax $s$.%
}

\commentary{%
  In short, whenever $s$ is treated as $s'$,
  the reader should immediately switch to the section about $s'$
  in order to get any further information about
  the static analysis and dynamic semantics of $s$.%
}

\rationale{%
  The notion of being `treated as' is similar to the notion of syntactic sugar:
  ``$s$ is treated as $s'$''
  could as well have been worded
  ``$s$ is desugared into $s'$''.
  Of course, it should then actually be called ``semantic sugar'',
  because the applicability of the transformation and the construction of $s'$
  may rely on information from static analysis.

  The point is that we only specify the static analysis and dynamic semantics
  of a core language which is a subset of Dart
  (just slightly smaller than Dart),
  and desugaring transforms any given Dart program to
  a program in that core language.
  This helps keeping the language specification consistent and comprehensible,
  because it shows directly
  that some language features are introducing essential semantics,
  and others are better described as mere abbreviations of existing constructs.%
}

\LMHash{}%
The specification uses one syntactic construct, the
\IndexCustom{\LET{} expression}{let expression@\LET{} expression},
which is not derivable in the grammar
\commentary{(that is, no Dart source code contains such an expression)}.
This expression is helpful in specifying certain syntactic forms
that are treated as other syntactic forms,
because it allows for introducing and initializing one or more fresh variables,
and using them in an expression.

\commentary{%
  That is, a \LET{} expression is only introduced as a tool
  to define the evaluation semantics of an expression
  in terms of other expressions containing \LET{} expressions.%
}

\LMHash{}%
The syntax of a \LET{} expression is as follows:

\begin{grammar}
<letExpression> ::= \LET{} <staticFinalDeclarationList> \IN{} <expression>
\end{grammar}

\LMHash{}%
\BlindDefineSymbol{e_{\metavar{let}}, e_j, v_j, k}%
Let $e_{\metavar{let}}$ be a \LET{} expression of the form
\LetMany{$v_1$}{$e_1$}{$v_k$}{$e_k$}{$e$}.
It is tacitly assumed that $v_j$ is a fresh variable, $j \in 1 .. k$,
unless something is stated to the contrary.

\LMHash{}%
$e_{\metavar{let}}$ contains $k$ nested scopes, \DefineSymbol{\List{S}{1}{k}}.
The enclosing scope for $S_1$ is the current scope for $e_{\metavar{let}}$,
and the enclosing scope for $S_j$ is $S_{j-1}$, $j \in 2 .. k$.
The current scope of $e_1$ is the current scope of $e_{\metavar{let}}$,
the current scope of $e_j$ is $S_{j-1}$, $j \in 2 .. k$,
and the current scope of $e$ is $S_k$.
For $j \in 1 .. k$, $v_j$ introduces a final, local variable into $S_j$,
with the static type of $e_j$ as its declared type.

\commentary{%
  Type inference of $e_j$ and the context type used for inference of $e_j$
  are not relevant.
  It is generally assumed that type inference has occurred already
  (\ref{overview}).%
}

\LMHash{}%
Evaluation of $e_{\metavar{let}}$ proceeds by
evaluating $e_j$ to an object $o_j$ and binding $v_j$ to $o_j$,
where $j \in 1 .. k$, in that order.
Finally, $e$ is evaluated to an object $o$ and then
$e_{\metavar{let}}$ evaluates to $o$.

\LMHash{}%
The right margin of each page in this document is used to indicate
referenced entities.

\LMHash{}%
The document contains an index at the end.
Each entry in the index refers to a page number, $p$.
On page $p$ there is a `$\diamond$' in the margin
at the definition of the given indexed phrase,
and the phrase itself is shown using \emph{this typeface}.
We have hereby introduced the
\Index{index marker $\diamond$}
itself.

\LMHash{}%
The right margin also contains symbols.
Whenever a symbol
\BlindDefineSymbol{\textcolor{commentaryColor}{C}}%
\BlindDefineSymbol{\textcolor{commentaryColor}{x_j}}%
\commentary{(say, $C$ or $x_j$)}
is introduced and used in more than a few lines of text,
it is shown in the margin.

\commentary{%
  The point is that it is easy to find the definition of a symbol
  by scanning back in the text until that symbol occurs in the margin.
  To avoid useless verbosity, some symbols are not mentioned in the margin.
  For instance, we may introduce \List{e}{1}{k},
  but only show $e_j$ and $k$ in the margin.

  Note that it may be necessary to look at a few lines of text
  above the `$\diamond$' or symbol,
  because the margin markers can be pushed down one line
  when there is more than one marker for a single line.%
}


\section{Overview}
\LMLabel{overview}

\LMHash{}%
Dart is a class-based, single-inheritance, pure
object-oriented programming language.
Dart is optionally typed (\ref{types}) and supports reified generics.
The run-time type of every object is represented as
an instance of class \code{Type} which can be obtained
by calling the getter \code{runtimeType} declared in class \code{Object},
the root of the Dart class hierarchy.

\LMHash{}%
Dart programs may be statically checked.
Programs with compile-time errors do not have a specified dynamic semantics.
This specification makes no attempt to answer additional questions
about a library or program at the point
where it is known to have a compile-time error.

\commentary{%
  However, tools may choose to support execution of some programs with errors.
  For instance, a compiler may compile certain constructs with errors such that
  a dynamic error will be raised if an attempt is made to
  execute such a construct,
  or an IDE integrated runtime may support opening
  an editor window when such a construct is executed,
  allowing developers to correct the error.
  It is expected that such features would amount to a natural extension of the
  dynamic semantics of Dart as specified here, but, as mentioned,
  this specification makes no attempt to specify exactly what that means.%
}

\LMHash{}%
As specified in this document,
dynamic checks are guaranteed to be performed in certain situations,
and certain violations of the type system throw exceptions at run time.

\commentary{%
  An implementation is free to omit such checks whenever they are
  guaranteed to succeed, e.g., based on results from the static analysis.%
}

\commentary{%
  The coexistence between optional typing and reification
  is based on the following:

\begin{enumerate}
\item
  Reified type information reflects the types of objects at run time
  and may always be queried by dynamic typechecking constructs
  (the analogs of instanceOf, casts, typecase etc.\ in other languages).
  Reified type information includes
  access to instances of class \code{Type} representing types,
  the run-time type (aka class) of an object,
  and the actual values of type parameters
  to constructors and generic function invocations.
\item
  Type annotations declare the types of
  variables and functions (including methods and constructors).
\item
  %% TODO(eernst): Change when integrating instantiate-to-bounds.md.
  Type annotations may be omitted, in which case they are generally
  filled in with the type \DYNAMIC{}
  (\ref{typeDynamic}).
\end{enumerate}%
}

%% TODO(eernst): Update when we add inference.
\commentary{%
  Dart as implemented includes extensive support for inference of omitted types.
  This specification makes the assumption that inference has taken place,
  and hence inferred types are considered to be present in the program already.
  However, in some cases no information is available
  to infer an omitted type annotation,
  and hence this specification still needs to specify how to deal with that.
  A future version of this specification will also specify type inference.%
}

\LMHash{}%
Dart programs are organized in a modular fashion into
units called \NoIndex{libraries} (\ref{librariesAndScripts}).
Libraries are units of encapsulation and may be mutually recursive.

\commentary{%
  However they are not first class.
  To get multiple copies of a library running simultaneously,
  one needs to spawn an isolate.%
}

\LMHash{}%
A dart program execution may occur with assertions enabled or disabled.
The method used to enable or disable assertions is implementation specific.


\subsection{Scoping}
\LMLabel{scoping}

\LMHash{}%
A \IndexCustom{compile-time namespace}{namespace!compile-time}
is a partial function that maps names to namespace values.
Compile-time namespaces are used much more frequently than run-time namespaces
\commentary{(defined later in this section)},
so when the word \Index{namespace} is used alone,
it means compile-time namespace.
A \Index{name} is a lexical token which is an \synt{IDENTIFIER},
an \synt{IDENTIFIER} followed by \lit{=}, or
an \synt{operator},
or \code{unary-};
and a \Index{namespace value} is
a declaration, a namespace, or the special value \ConflictValue{}
(\ref{conflictMergingOfNamespaces}).

\LMHash{}%
If $\Namespace{}{n} = V$ then we say that \NamespaceName{}
\IndexCustom{maps}{namespace!maps a key to a value}
the
\IndexCustom{key}{namespace!key}
$n$ to the
\IndexCustom{value}{namespace!value}
$V$,
and that \NamespaceName{}
\IndexCustom{has the binding}{namespace!has a binding}
$n\mapsto{}V$.
\commentary{%
  The fact that \NamespaceName{} is a partial function just means that
  each name is mapped to at most one namespace value.
  That is, if \NamespaceName{} has the bindings
  $n\mapsto{}V_1$ and $n\mapsto{}V_2$
  then $V_1 = V_2$.%
}

\LMHash{}%
Let \NamespaceName{} be a namespace.
We say that a name $n$ \Index{is in} \NamespaceName{}
if $n$ is a key of \NamespaceName.
We say a declaration $d$ \NoIndex{is in} \NamespaceName{}
if a key of \NamespaceName{} is mapped to $d$.

\LMHash{}%
A scope $S_0$ has an associated namespace \NamespaceName{0}.
The bindings of \NamespaceName{0} is specified in this document by saying that
a given declaration \BlindDefineSymbol{D, n}$D$ named $n$
\IndexCustom{introduces}{declaration!introduces an entity into a scope}
a specific entity \DefineSymbol{V} into $S_0$,
which means that the binding $n\mapsto{}V$ is added to \NamespaceName{0}.

\commentary{%
  In some cases, the name of the declaration differs from
  the identifier that occurs in the declaration syntax used to declare it.
  Setters have names that are distinct from the corresponding getters
  because they always have an \lit{=} automatically added at the end,
  and the unary minus operator has the special name \code{unary-}.%
}

\commentary{%
  It is typically the case that $V$ is the declaration $D$ itself,
  but there are exceptions.
  For example,
  a variable declaration introduces an implicitly induced getter declaration,
  and in some cases also an implicitly induced setter declaration into the
  given scope.%
}

\commentary{%
  Note that labels (\ref{labels}) are not included in the namespace of a scope.
  They are resolved lexically rather then being looked up in a namespace.%
}

\LMHash{}%
It is a compile-time error if there is more than one entity with the same name
declared in the same scope.

\commentary{%
  It is therefore impossible, e.g., to define a class that declares
  a method and a getter with the same name in Dart.
  Similarly one cannot declare a top-level function with
  the same name as a library variable or a class
  which is declared in the same library.%
}

\LMHash{}%
We introduce the notion of a
\Index{run-time namespace}.
This is a partial function from names to run-time entities,
in particular storage locations and functions.
Each run-time namespace corresponds to a namespace with the same keys,
but with values that correspond to the semantics of the namespace values.

\rationale{%
  A namespace typically maps a name to a declaration,
  and it can be used statically to figure out what that name refers to.
  For example,
  a variable is associated with an actual storage location at run time.
  We introduce the notion of a run-time namespace based on a namespace,
  such that the dynamic semantics can access run-time entities
  like that storage location.
  The same code may be executed multiple times with the same run-time namespace,
  or with different run-time namespaces for each execution.
  E.g., local variables declared inside a function
  are specific to each invocation of the function,
  and instance variables are specific to an object.%
}

\LMHash{}%
Dart is lexically scoped.
Scopes may nest.
A name or declaration $d$ is \Index{available in scope} $S$
if $d$ is in the namespace induced by $S$ or
if $d$ is available in the lexically enclosing scope of $S$.
We say that a name or declaration $d$ is \Index{in scope}
if $d$ is available in the current scope.

\LMHash{}%
If a declaration $d$ named $n$ is in the namespace induced by a scope $S$,
then $d$ \Index{hides} any declaration named $n$ that is available
in the lexically enclosing scope of $S$.

\commentary{%
  A consequence of these rules is that it is possible to hide a type
  with a method or variable.
  Naming conventions usually prevent such abuses.
  Nevertheless, the following program is legal:%
}

\begin{dartCode}
\CLASS{} HighlyStrung \{
  String() => "?";
\}
\end{dartCode}

\LMHash{}%
Names may be introduced into a scope by declarations within the scope
or by other mechanisms such as imports or inheritance.

\rationale{%
  The interaction of lexical scoping and inheritance is a subtle one.
  Ultimately, the question is whether lexical scoping
  takes precedence over inheritance or vice versa.
  Dart chooses the former.

  Allowing inherited names to take precedence over locally declared names
  could create unexpected situations as code evolves.
  Specifically, the behavior of code in a subclass could silently change
  if a new name is introduced in a superclass.
  Consider:%
}

\begin{dartCode}
\LIBRARY{} L1;
\CLASS{} S \{\}

\LIBRARY{} L2;
\IMPORT{} `L1.dart';
foo() => 42;
\CLASS{} C \EXTENDS{} S\{ bar() => foo();\}
\end{dartCode}

\rationale{%
  Now assume a method \code{foo()} is added to \code{S}.%
}

\begin{dartCode}
\LIBRARY{} L1;
\CLASS{} S \{foo() => 91;\}
\end{dartCode}

\rationale{%
  If inheritance took precedence over the lexical scope,
  the behavior of \code{C} would change in an unexpected way.
  Neither the author of \code{S} nor the author of \code{C}
  are necessarily aware of this.
  In Dart, if there is a lexically visible method \code{foo()},
  it will always be called.

  Now consider the opposite scenario.
  We start with a version of \code{S} that contains \code{foo()},
  but do not declare \code{foo()} in library \code{L2}.
  Again, there is a change in behavior---but the author of \code{L2}
  is the one who introduced the discrepancy that effects their code,
  and the new code is lexically visible.
  Both these factors make it more likely that the problem will be detected.

  These considerations become even more important
  if one introduces constructs such as nested classes,
  which might be considered in future versions of the language.

  Good tooling should of course endeavor to inform programmers
  of such situations (discreetly).
  For example, an identifier that is both inherited and lexically visible
  could be highlighted (via underlining or colorization).
  Better yet, tight integration of source control with language aware tools
  would detect such changes when they occur.%
}


\subsection{Privacy}
\LMLabel{privacy}

\LMHash{}%
Dart supports two levels of \Index{privacy}: public and private.
A declaration is \IndexCustom{private}{private!declaration}
if{}f its name is private,
otherwise it is \IndexCustom{public}{public!declaration}.
A name $q$ is \IndexCustom{private}{private!name}
if{}f any one of the identifiers that comprise $q$ is private,
otherwise it is \IndexCustom{public}{public!name}.
An identifier is \IndexCustom{private}{private!identifier}
if{}f it begins with an underscore (the \_ character)
otherwise it is \IndexCustom{public}{public!identifier}.

\LMHash{}%
A declaration $m$ is \Index{accessible to a library} $L$
if $m$ is declared in $L$ or if $m$ is public.

\commentary{%
  This means private declarations may only be accessed within
  the library in which they are declared.%
}

\rationale{%
  Privacy applies only to declarations within a library,
  not to the library declaration as a whole.
  This is because libraries do not reference each other by name,
  and so the idea of a private library is meaningless
  (\ref{imports}).
  Thus, if the name of a library begins with an underscore,
  it has no effect on the accessibility of the library or its members.%
}

\rationale{%
  Privacy is, at this point, a static notion tied to
  a particular piece of code (a library).
  It is designed to support software engineering concerns
  rather than security concerns.
  Untrusted code should always run in an another isolate.

  Privacy is indicated by the name of a declaration---hence
  privacy and naming are not orthogonal.
  This has the advantage that both humans and machines
  can recognize access to private declarations at the point of use
  without knowledge of the context from which the declaration is derived.%
}


\subsection{Concurrency}
\LMLabel{concurrency}

\LMHash{}%
Dart code is always single threaded.
There is no shared-state concurrency in Dart.
Concurrency is supported via actor-like entities called \Index{isolates}.

\LMHash{}%
An isolate is a unit of concurrency.
It has its own memory and its own thread of control.
Isolates communicate by message passing (\ref{sendingMessages}).
No state is ever shared between isolates.
Isolates are created by spawning (\ref{spawningAnIsolate}).


\section{Errors and Warnings}
\LMLabel{errorsAndWarnings}

\LMHash{}%
This specification distinguishes between several kinds of errors.

\LMHash{}%
\IndexCustom{Compile-time errors}{compile-time error}
are errors that preclude execution.
A compile-time error must be reported by a Dart compiler
before the erroneous code is executed.

\rationale{%
  A Dart implementation has considerable freedom
  as to when compilation takes place.
  Modern programming language implementations
  often interleave compilation and execution,
  so that compilation of a method may be delayed, e.g.,
  until it is first invoked.
  Consequently, compile-time errors in a method $m$ may be reported
  as late as the time of $m$'s first invocation.

  Dart is often loaded directly from source,
  with no intermediate binary representation.
  In the interests of rapid loading, Dart implementations
  may choose to avoid full parsing of method bodies, for example.
  This can be done by tokenizing the input and
  checking for balanced curly braces on method body entry.
  In such an implementation, even syntax errors will be detected
  only when the method needs to be executed,
  at which time it will be compiled (JITed).

  In a development environment a compiler should of course
  report compilation errors eagerly so as to best serve the programmer.

  A Dart development environment might choose to support
   error eliminating program transformations, e.g.,
  replacing an erroneous expression by the invocation of a debugger.
  It is outside the scope of this document
  to specify how such transformations work,
  and where they may be applied.%
}

\LMHash{}%
If an uncaught compile-time error occurs
within the code of a running isolate $A$, $A$ is immediately suspended.
The only circumstance where a compile-time error could be caught would be
via code run reflectively, where the mirror system can catch it.

\rationale{%
  Typically, once a compile-time error is thrown and $A$ is suspended,
  $A$ will then be terminated.
  However, this depends on the overall environment.
  A Dart engine runs in the context of a \Index{runtime},
  a program that interfaces between the engine and
  the surrounding computing environment.
  The runtime may be, for instance, a C++ program on the server.
  When an isolate fails with a compile-time error as described above,
  control returns to the runtime,
  along with an exception describing the problem.
  This is necessary so that the runtime can clean up resources etc.
  It is then the runtime's decision whether to terminate the isolate or not.%
}

\LMHash{}%
\IndexCustom{Static warnings}{static warning}
are situations that do not preclude execution,
but which are unlikely to be intended,
and likely to cause bugs or inconveniences.
A Dart compiler is free to report some, all,
or none of the specified static warnings before the associated code is executed.
A Dart compiler may also choose to report additional warnings
not defined by this specification.

\LMHash{}%
When this specification says that a \Index{dynamic error} occurs,
it means that a corresponding error object is thrown.
When it says that a \Index{dynamic type error} occurs,
it represents a failed type check at run time,
and the object which is thrown implements \code{TypeError}.

\LMHash{}%
Whenever we say that an exception $ex$ is
\IndexCustom{thrown}{throwing an exception},
it acts like an expression had thrown (\ref{statementCompletion})
with $ex$ as exception object and with a stack trace
corresponding to the current system state.
When we say that a $C$ \IndexCustom{is thrown}{throwing a class},
where $C$ is a class, we mean that an instance of class $C$ is thrown.

\LMHash{}%
If an uncaught exception is thrown by a running isolate $A$,
$A$ is immediately suspended.


\section{Variables}
\LMLabel{variables}

\LMHash{}%
Variables are storage locations in memory.

\begin{grammar}
<finalConstVarOrType> ::= \LATE? \FINAL{} <type>?
  \alt \CONST{} <type>?
  \alt \LATE? <varOrType>

<varOrType> ::= \VAR{}
  \alt <type>

<initializedVariableDeclaration> ::= \gnewline{}
  <declaredIdentifier> (`=' <expression>)? (`,' <initializedIdentifier>)*

<initializedIdentifier> ::= <identifier> (`=' <expression>)?

<initializedIdentifierList> ::=
  <initializedIdentifier> (`,' <initializedIdentifier>)*
\end{grammar}

\LMHash{}%
An \synt{initializedVariableDeclaration}
that declares two or more variables
is equivalent to multiple variable declarations declaring
the same set of variable names, in the same order,
with the same initialization, type, and modifiers.

\commentary{%
  For example,
  \code{\VAR{} x, y;}
  is equivalent to
  \code{\VAR{} x; \VAR{} y;}
  and
  \code{\STATIC\,\,\LATE\,\,\FINAL{} String s1, s2 = "foo";}
  is equivalent to having both
  \code{\STATIC\,\,\LATE\,\,\FINAL{} String s1;}
  and
  \code{\STATIC\,\,\LATE\,\,\FINAL{} String s2 = "foo";}.%
}

\LMHash{}%
It is possible for a variable declaration to include the modifier \COVARIANT.
The effect of doing this with an instance variable is described elsewhere
(\ref{instanceVariables}).
It is a \Error{compile-time error} for the declaration of a variable
which is not an instance variable to include the modifier \COVARIANT.

\commentary{%
  A formal parameter declaration induces a local variable into a scope,
  but formal parameter declarations are not variable declarations
  and do not give rise to the above error.
  The effect of having the modifier \COVARIANT{} on a formal parameter
  is described elsewhere
  (\ref{covariantParameters}).%
}

\LMHash{}%
In a variable declaration of one of the forms
\code{$N$\,\,\id;}
or
\code{$N$\,\,\id{} = $e$;}
where $N$ is derived from
\syntax{<metadata> <finalConstVarOrType>} and \id{} is an identifier,
we say that \id{} is a \Index{declaring occurrence} of the identifier.
For every identifier which is not a declaring occurrence,
we say that it is a \Index{referencing occurrence}.
We also abbreviate that to say that an identifier is
a \Index{declaring identifier} respectively an \Index{referencing identifier}.

\commentary{%
  In an expression of the form \code{$e$.$\id'$} it is possible that
  $e$ has static type \DYNAMIC{} and $\id'$ cannot be associated with
  any specific declaration named $\id'$ at compile-time,
  but in this situation $\id'$ is still a referencing identifier.%
}

\LMHash{}%
For brevity, we will refer to a variable using its name,
even though the name of a variable and the variable itself
are very different concepts.

\commentary{%
  So we will talk about ``the variable \id{}'',
  rather than introducing ``the variable $v$ named \id{}''\!,
  in order to be able to say ``the variable $v$'' later on.
  This should not create any ambiguities,
  \emph{because} the concept of a name and the concept of a variable
  are so different.%
}

\LMHash{}%
An \Index{initializing variable declaration}
is a variable declaration whose declaring identifier is
immediately followed by `\code{=}' and an \Index{initializing expression}.

\LMHash{}%
A variable declared at the top-level of a library is referred to as either a
\IndexCustom{library variable}{variable!library} or a
\IndexCustom{top-level variable}{variable!top-level}.
It is a \Error{compile-time error} if a library variable declaration
has the modifier \STATIC.

\LMHash{}%
A \IndexCustom{static variable}{variable!static}
is a variable whose declaration is
immediately nested inside a \CLASS, \MIXIN, \ENUM, or \EXTENSION{} declaration
and includes the modifier \STATIC.

\LMHash{}%
A \Error{compile-time error} occurs if a static or library variable has
no initializing expression and a type which is not nullable
(\ref{typeNullability}),
unless the variable declaration has
the modifier \LATE{} or the modifier \EXTERNAL.

\LMHash{}%
A \IndexCustom{non-local variable}{variable!non-local}
is a library variable, a static variable, or an instance variable.
\commentary{%
  That is, any kind of variable which is not a local variable.%
}

\LMHash{}%
A \IndexCustom{constant variable}{variable!constant}
is a variable whose declaration includes the modifier \CONST.
A constant variable must be initialized to a constant expression
(\ref{constants}),
or a \Error{compile-time error} occurs.

\commentary{%
  An initializing expression $e$ of a constant variable declaration
  occurs in a constant context
  (\ref{constantContexts}).
  This means that \CONST{} modifiers in $e$ need not be specified explicitly.%
}

\rationale{%
  It is grammatically impossible for a constant variable declaration
  to have the modifier \LATE.
  However, even if it had been grammatically possible,
  a \LATE{} constant variable would still have to be a compile-time error,
  because being a compile-time constant is inherently incompatible
  with being computed late.

  Similarly, an instance variable cannot be constant
  (\ref{instanceVariables}).%
}


\subsection{Implicitly Induced Getters and Setters}
\LMLabel{implicitlyInducedGettersAndSetters}

%% TODO(eernst): When inference is specified, we should be able to conclude
%% that the cases with no declared type do not exist after type inference
%% (for instance `var x;` or `var x = e;`), and then we can replace all rules
%% about such cases by commentary saying that they may exist in the input,
%% but they are gone after type inference.
%%
%% At this time we rely on the assumption that type inference has already
%% occurred, which means that we can refer to the declared type of a variable
%% without mentioning type inference.

\LMHash{}%
The following rules on implicitly induced getters and setters
apply to all non-local variable declarations.
\commentary{%
  Local variable declarations
  (\ref{localVariableDeclaration})
  do not induce getters or setters.%
}

\LMHash{}%
\Case{Getter: Variable with declared type}
Consider a variable declaration of one of the forms

\begin{itemize}
\item \code{\STATIC?\,\,\LATE?\,\,\FINAL?\,\,$T$\,\,\id;}
\item \code{\STATIC?\,\,\LATE?\,\,\FINAL?\,\,$T$\,\,\id{} = $e$;}
\item \code{\STATIC?\,\,\CONST\,\,$T$\,\,\id{} = $e$;}
\end{itemize}

\noindent
where $T$ is a type, \id{} is an identifier,
and \lit{?} indicates that the given modifier may be present or absent.
Each of these declarations implicitly induces a getter
(\ref{getters})
with the header \code{$T$\,\,\GET\,\,\id},
whose invocation evaluates as described below
(\ref{evaluationOfImplicitVariableGetters}).
In these cases the declared type of \id{} is $T$.
\EndCase

\LMHash{}%
\Case{Getter: Variable with no declared type}
A variable declaration of one of the forms

\begin{itemize}
\item \code{\STATIC?\,\,\LATE?\,\,\VAR\,\,\id;}
\item \code{\STATIC?\,\,\LATE?\,\,\VAR\,\,\id{} = $e$;}
\item \code{\STATIC?\,\,\LATE?\,\,\FINAL\,\,\id;}
\item \code{\STATIC?\,\,\LATE?\,\,\FINAL\,\,\id{} = $e$;}
\item \code{\STATIC?\,\,\CONST\,\,\id{} = $e$;}
\end{itemize}

\noindent
implicitly induces a getter with the header that
contains \STATIC{} if{}f the declaration contains \STATIC{} and is followed by
\code{$T$\,\,\GET\,\,\id},
where $T$ is obtained from type inference
in the case where $e$ exists,
and $T$ is \DYNAMIC{} otherwise.
The invocation of this getter evaluates as described below
(\ref{evaluationOfImplicitVariableGetters}).
In these cases, the declared type of \id{} is $T$.
\EndCase

\LMHash{}%
\Case{Setter: Mutable variable with declared type}
A variable declaration of one of the forms

\begin{itemize}
\item \code{\STATIC?\,\,\LATE?\,\,$T$\,\,\id;}
\item \code{\STATIC?\,\,\LATE?\,\,$T$\,\,\id{} = $e$;}
\end{itemize}

\noindent
implicitly induces a setter (\ref{setters}) with the header
\code{\VOID\,\,\SET\,\,\id($T$\,\,$x$)},
whose execution sets the value of \id{} to the incoming argument $x$.

\LMHash{}%
\Case{Setter: Mutable variable with no declared type, with initialization}
A variable declaration of the form
\code{\STATIC?\,\,\LATE?\,\,\VAR\,\,\id{} = $e$;}
implicitly induces a setter with the header
\code{\VOID\,\,\SET\,\,\id(\DYNAMIC\,\,$x$)},
whose execution sets the value of \id{} to the incoming argument $x$.

\commentary{%
  Type inference could have provided a type different from \DYNAMIC{}
  (\ref{overview}).%
}
\EndCase

\LMHash{}%
\Case{Setter: Mutable variable with no declared type, no initialization}
A variable declaration of the form
\code{\STATIC?\,\,\LATE?\,\,\VAR\,\,\id;}
implicitly induces a setter with the header
\code{\VOID\,\,\SET\,\,\id(\DYNAMIC\,\,$x$)},
whose execution sets the value of \id{} to the incoming argument $x$.

\commentary{%
  Type inference has not yet been specified in this document
  (\ref{overview}).
  Note that type inference could change, e.g.,
  \code{\VAR\,\,x;} to \code{$T$\,\,x;},
  which would take us to an earlier case.%
}
\EndCase

\LMHash{}%
\Case{Setter: Late-final variable with declared type}
A variable declaration of the form
\code{\STATIC?\,\,\LATE\,\,\FINAL\,\,$T$\,\,\id;}
implicitly induces a setter (\ref{setters}) with the header
\code{\VOID\,\,\SET\,\,\id($T$\,\,$x$)}.
If this setter is executed
in a situation where the variable \id{} has not been bound,
it will bind \id{} to the object that $x$ is bound to.
If this setter is executed
in a situation where the variable \id{} has been bound to an object,
a dynamic error occurs.
\EndCase

\LMHash{}%
\Case{Setter: Late-final variable with no declared type, no initialization}
A variable declaration of the form
\code{\STATIC?\,\,\LATE\,\,\FINAL\,\,\id;}
implicitly induces a setter with the header
\code{\VOID\,\,\SET\,\,\id(\DYNAMIC\,\,$x$)}.
An execution of said setter
in a situation where the variable \id{} has not been bound
will bind \id{} to the object that the argument $x$ is bound to.
An execution of the setter
in a situation where the variable \id{} has been bound to an object
will incur a dynamic error.
\EndCase

\LMHash{}%
The scope into which the implicit getters and setters are introduced
depends on the kind of variable declaration involved.

\LMHash{}%
A library variable introduces a getter into
the library scope of the enclosing library.
A static variable introduces a static getter into
the body scope of the immediately enclosing
class, mixin, enum, or extension declaration.
An instance variable introduces an instance getter into
the body scope of the immediately enclosing
class, mixin, or enum declaration
\commentary{(an extension cannot declare instance variables)}.

\LMHash{}%
A non-local variable introduces a setter if{}f
it does not have the modifier \FINAL{} or the modifier \CONST{},
or it is \LATE{} and \FINAL, but does not have an initializing expression.

\LMHash{}%
A library variable which introduces a setter will introduce
a library setter into the enclosing library scope.
A static variable which introduces a setter will introduce
a static setter into the body scope of the immediately enclosing
class, mixin, enum, or extension declaration.
An instance variable that introduces a setter will introduce
an instance setter into the body scope of the immediately enclosing
class, mixin, or enum declaration
\commentary{(an extension cannot declare instance variables)}.

\LMHash{}%
Let \id{} be a variable declared by a variable declaration
that has an initializing expression $e$.
It is a \Error{compile-time error} if the static type of $e$
is not assignable to the declared type of \id.
It is a \Error{compile-time error} if a final instance variable
whose declaration has an initializer expression
is also initialized by a constructor,
either by an initializing formal or an initializer list entry.

\commentary{%
  It is a compile-time error if a final instance variable
  that has been initialized by means of
  an initializing formal of a constructor $k$
  is also initialized in the initializer list of $k$
  (\ref{initializerLists}).

  A non-late static variable declaration $D$ named \id{}
  that has the modifier \FINAL{} or the modifier \CONST{}
  does not induce a setter.
  However, an assignment to \id{} at a location where $D$ is in scope
  is not necessarily a compile-time error.
  For example, a setter named \code{\id=} could be found by lexical lookup
  (\ref{lexicalLookup}).

  Similarly, a non-late final instance variable \id{} does not induce a setter,
  but an assignment could be an invocation of
  a setter which is provided in some other way.
  For example, it could be that lexical lookup yields nothing,
  and the location of the assignment has access to \THIS,
  and the interface of an enclosing class has a setter named \code{\id=}
  (in this case both the getter and setter are inherited).%
}

\LMHash{}%
Consider a variable \id{}
whose declaration does not have the modifier \LATE.
Assume that \id{} does not have an initializing expression,
and it is not initialized by an initializing formal
(\ref{generativeConstructors}),
nor by an element in a constructor initializer list
(\ref{initializerLists}).
The initial value of \id{} is then the null object
(\ref{null}).

\commentary{%
  Note that there are many situations where such a variable declaration
  is a compile-time error,
  in which case the initial value is of course irrelevant.%
}

\LMHash{}%
Otherwise, variable initialization proceeds as follows:

\LMHash{}%
A declaration of a static or library variable
with an initializing expression is initialized lazily
(\ref{evaluationOfImplicitVariableGetters}).

\rationale{%
  The lazy semantics are given because we do not want a language
  where one tends to define expensive initialization computations,
  causing long application startup times.
  This is especially crucial for Dart,
  which must support the coding of client applications.%
}

\commentary{%
  Initialization of an instance variable with no initializing expression
  takes place during constructor execution
  (\ref{initializerLists}).%
}

\LMHash{}%
\BlindDefineSymbol{\id, o}%
Initialization of an instance variable \id{}
with an initializing expression $e$
proceeds as follows:
$e$ is evaluated to an object $o$
and the variable \id{} is bound to $o$.

\commentary{%
  It is specified elsewhere when this initialization occurs,
  and in which environment
  (p.\,\pageref{executionOfGenerativeConstructors},
  \ref{localVariableDeclaration},
  \ref{bindingActualsToFormals}).%
}

\commentary{%
  If the initializing expression throws then
  access to the uninitialized variable is prevented,
  because the instance creation
  that caused this initialization to take place
  will throw.%
}

\LMHash{}%
% This error can occur due to an implicit downcast from \DYNAMIC.
It is a dynamic type error if the dynamic type of $o$ is not
a subtype of the actual type of the variable \id{}
(\ref{actualTypes}).


\subsection{Evaluation of Implicit Variable Getters}
\LMLabel{evaluationOfImplicitVariableGetters}

\LMHash{}%
We introduce two specific kinds of getters in order to specify
the behavior of various kinds of variables
without duplicating the specification of their common behaviors.

\LMHash{}%
A
\IndexCustom{late-initialized getter}{getter!late-initialized}
is a getter $g$ which is implicitly induced by a non-local variable $v$
that has an initializing expression $e$.
\commentary{%
  It is described below which declarations induce a late-initialized getter.%
}
An invocation of $g$ proceeds as follows:

\LMHash{}%
If the variable $v$ has not been bound to an object then
$e$ is evaluated to an object $o$.
If $v$ has now been bound to an object, and $v$ is final,
a dynamic error occurs. % Implementations throw a 'LateInitializationError'.
Otherwise, $v$ is bound to $o$,
and the evaluation of $g$ completes returning $o$.
If the evaluation of $e$ throws then
the invocation of $g$ completes throwing the same object and stack trace,
and does not change the binding of $v$.

\LMHash{}%
An invocation of $g$ in a situation where $v$ has been bound to an object $o'$
completes immediately, returning $o'$.

\commentary{%
  Consider a non-local variable declaration of the form
  \code{\LATE\,\,\VAR\,\,x = $e$;},
  whose implicitly induced getter is late-initialized.
  Perhaps surprisingly,
  if the variable \code{x} has been bound to an object
  when its getter is invoked for the first time,
  $e$ will never be executed.
  In other words, the initializing expression can be pre-empted
  by an assignment.%
}

\commentary{%
  Also note that an initializing expression can have side effects
  that are significant during initialization.
  For example:%
}

\begin{dartCode}
bool b = \TRUE;
int i = (() => (b = !b) ? (i = 10) : i + 1)();
\\
\VOID{} main() \{
  print(i); // '11'.
\}
\end{dartCode}

\commentary{%
  In this example, \code{main} invokes
  the implicitly induced getter named \code{i},
  and the variable \code{i} has not been bound at this point.
  Hence, evaluation of the initializing expression proceeds.
  This causes \code{b} to be toggled to \FALSE,
  which again causes \code{i + 1} to be evaluated.
  This causes the getter \code{i} to be invoked again,
  and it is still true that the variable has not been bound,
  so the initializing expression is evaluated again.
  This toggles \code{b} to \TRUE,
  which causes \code{i = 10} to be evaluated,
  which causes the implicitly induced setter named \code{i=} to be invoked,
  and the most recent invocation of the getter \code{i}
  returns 10.
  This makes \code{i + 1} evaluate to 11,
  and the variable is then bound to 11.
  Finally, the invocation of the getter \code{i} in \code{main}
  completes returning 11.%
}

\commentary{%
  This is a change from the semantics of older versions of Dart:
  Throwing an exception during initializer evaluation no longer sets the
  variable to \code{null},
  and reading the variable during initializer evaluation
  no longer causes a dynamic error.%
}

\LMHash{}%
A
\IndexCustom{late-uninitialized getter}{getter!late-uninitialized}
is a getter $g$ which is implicitly induced by a non-local variable $v$
that does not have an initializing expression.
\commentary{%
  Again, only \emph{some} non-local variables without an initializing expression
  induce a late-uninitialized getter, as specified below.%
}
An invocation of $g$ proceeds as follows:
If the variable $v$ has not been bound to an object then a dynamic error occurs.
If $v$ has been bound to an object $o'$ then
the invocation of $g$ completes immediately, returning $o'$.

\LMHash{}%
\BlindDefineSymbol{d, \id}%
Let $d$ be the declaration of a non-local variable named \id.
For brevity, we will refer to it below as
`the variable \id' or `the variable $d$', or just as `\id' or `$d$'.
Execution of the implicitly induced getter of \id{} proceeds as follows:

\LMHash{}%
\Case{Non-late instance variable}
If $d$ declares an instance variable which does not have the modifier \LATE,
then the invocation of the implicit getter of \id{} evaluates to
the object that \id{} is bound to.

\commentary{%
  It is not possible to invoke an instance getter on an object
  before the object has been initialized.
  Hence, a non-late instance variable is always bound
  when the instance getter is invoked.%
}
\EndCase

\LMHash{}%
\Case{Late, initialized instance variable}
If $d$ declares an instance variable \id{} which has the modifier \LATE{}
and an initializing expression,
the implicitly induced getter of \id{} is a
late-initialized getter.
This determines the semantics of an invocation.
\EndCase

\LMHash{}%
\Case{Late, uninitialized instance variable}
If $d$ declares an instance variable \id{} which has the modifier \LATE{}
and does not have an initializing expression,
the implicitly induced getter of \id{} is a
late-uninitialized getter.
This determines the semantics of an invocation.

\commentary{%
  In this case it is possible for \id{} to be unbound,
  but there are also several ways to bind \id{} to an object:
  A constructor can have an initializing formal
  (\ref{generativeConstructors})
  or an initializer list entry
  (\ref{initializerLists})
  that will initialize \id{},
  and the implicitly induced setter named \code{\id=} could
  have been invoked and completed normally.%
}
\EndCase

\LMHash{}%
\Case{Static or library variable}
If $d$ declares a static or library variable,
the implicitly induced getter of \id{} executes as follows:

\begin{itemize}
\item \emph{Non-constant variable with an initializer.}
  In the case where $d$ has an initializing expression and is not constant,
  the implicitly induced getter of \id{} is a late-initialized getter.
  This determines the semantics of an invocation.
  \commentary{%
    Note that these static or library variables can be \emph{implicitly}
    late-initialized, in the sense that they do not have
    the modifier \LATE.%
  }
\item \emph{Constant variable.}
  If $d$ declares a constant variable with the initializing expression $e$,
  the result of executing the implicitly induced getter is
  the value of the constant expression $e$.
  \commentary{%
    Note that a constant expression cannot depend on itself,
    so no cyclic references can occur.%
  }
\item \emph{Variable without an initializer.}
  If $d$ declares a variable \id{} without an initializing expression
  and does not have the modifier \LATE,
  an invocation of the implicitly induced getter of \id{} evaluates to
  the object that \id{} is bound to.

  \commentary{%
    The variable is always bound to an object in this case.
    This may be the null object,
    which is the initial value of some variable declarations
    covered by this case.%
  }

  If $d$ declares a variable \id{} without an initializing expression
  and has the modifier \LATE,
  the implicitly induced getter is a late-uninitialized getter.
  This determines the semantics of an invocation.
\end{itemize}

% Reduce whitespace after itemized list: This is just an end symbol.
\vspace{-\baselineskip}\EndCase


\section{Functions}
\LMLabel{functions}

\LMHash{}%
Functions abstract over executable actions.

\begin{grammar}
<functionSignature> ::= \gnewline{}
  <type>? <identifier> <formalParameterPart>

<formalParameterPart> ::= <typeParameters>? <formalParameterList>

<functionBody> ::= \ASYNC? `=>' <expression> `;'
  \alt (\ASYNC{} `*'? | \SYNC{} `*')? <block>

<block> ::= `{' <statements> `}'
\end{grammar}

\LMHash{}%
Functions can be introduced by function declarations
(\ref{functionDeclarations}),
method declarations (\ref{instanceMethods}, \ref{staticMethods}),
getter declarations (\ref{getters}),
setter declarations (\ref{setters}),
and constructor declarations (\ref{constructors});
and they can be introduced by function literals (\ref{functionExpressions}).

\LMHash{}%
A function is \IndexCustom{asynchronous}{function!asynchronous}
if its body is marked with the \ASYNC{} or \code{\ASYNC*} modifier.
Otherwise the function is \IndexCustom{synchronous}{function!synchronous}.
A function is a \IndexCustom{generator}{function!generator}
if its body is marked with the \code{\SYNC*} or \code{\ASYNC*} modifier.
Further details about these concepts are given below.

\commentary{%
  Whether a function is synchronous or asynchronous is orthogonal to
  whether it is a generator or not.
  Generator functions are a sugar for functions
  that produce collections in a systematic way,
  by lazily applying a function that \emph{generates}
  individual elements of a collection.
  Dart provides such a sugar in both the synchronous case,
  where one returns an iterable,
  and in the asynchronous case, where one returns a stream.
  Dart also allows both synchronous and asynchronous functions
  that produce a single value.%
}

\LMHash{}%
Each declaration that introduces a function has a signature that specifies
its return type, name, and formal parameter part,
except that the return type may be omitted,
and getters never have a formal parameter part.
Function literals have a formal parameter part, but no return type and no name.
The formal parameter part optionally specifies
the formal type parameter list of the function,
and it always specifies its formal parameter list.
A function body is either:

\begin{itemize}
\item
  a block statement (\ref{blocks}) containing
  the statements (\ref{statements}) executed by the function,
  optionally marked with one of the modifiers:
  \ASYNC, \code{\ASYNC*} or \code{\SYNC*}.
  %
  Unless it is statically known that the body of the function
  cannot complete normally
  \commentary{%
    (that is, it cannot reach the end and ``fall through'',
    cf.~\ref{statementCompletion})%
  },
  it is a compile-time error if
  the addition of \code{\RETURN;} at the end of the body
  would be a compile-time error.
  \commentary{%
    For instance, it is an error if
    the return type of a synchronous function is \code{int},
    and the body may complete normally.
    The precise rules are given in section~\ref{return}.%
  }

  \commentary{%
    Because Dart supports dynamic function invocations,
    we cannot guarantee that a function that does not return an object
    will not be used in the context of an expression.
    Therefore, every function must either throw or return an object.
    A function body that ends without doing a throw or return
    will cause the function to return the null object (\ref{null}),
    as will a \RETURN{} without an expression.
    For generator functions, the situation is more subtle.
    See further discussion in section~\ref{return}.%
  }

OR
\item
  of the form \code{=> $e$} or the form \code{\ASYNC{} => $e$},
  which both return the value of the expression $e$ as if by a
  \code{return $e$}.
  \commentary{%
    The other modifiers do not apply here,
    because they apply only to generators, discussed below.
    Generators are not allowed to explicitly return anything,
    objects are added to the generated stream or iterable using
    \YIELD{} or \YIELD*.%
  }
  Let $T$ be the declared return type of the function that has this body.
  It is a compile-time error if one of the following conditions hold:

  \begin{itemize}
  \item The function is synchronous, $T$ is not \VOID,
    and it would have been a compile-time error
    to declare the function with the body
    \code{\{ \RETURN{} $e$; \}}
    rather than \code{=> $e$}.
    \commentary{%
      In particular, $e$ can have \emph{any} type
      when the return type is \VOID.%
    }
    \rationale{%
      This enables concise declarations of \VOID{} functions.
      It is reasonably easy to understand such a function,
      because the return type is textually near to the returned expression $e$.
      In contrast, \code{\RETURN{} $e$;} in a block body is only allowed
      for an $e$ with one of a few specific static types,
      because it is less likely that the developer understands
      that the returned object will not be used
      (\ref{return}).%
    }
  \item The function is asynchronous, \flatten{T} is not \VOID,
    and it would have been a compile-time error
    to declare the function with the body
    \code{\ASYNC{} \{ \RETURN{} $e$; \}}
    rather than \code{\ASYNC{} => $e$}.
    \commentary{%
      In particular, $e$ can have \emph{any} type
      when the flattened return type is \VOID,%
    }
    \rationale{%
      and the rationale is similar to the synchronous case.%
    }
  \end{itemize}
\end{itemize}

\LMHash{}%
It is a compile-time error
if an \ASYNC, \code{\ASYNC*} or \code{\SYNC*} modifier is attached to
the body of a setter or constructor.

\rationale{%
An asynchronous setter would be of little use,
since setters can only be used in the context of an assignment
(\ref{assignment}),
and an assignment expression always evaluates to
the value of the assignment's right hand side.
If the setter actually did its work asynchronously,
one might imagine that one would return a future that resolved to
the assignment's right hand side after the setter did its work.

An asynchronous constructor would, by definition, never return
an instance of the class it purports to construct,
but instead return a future.
Calling such a beast via \NEW{} would be very confusing.
If you need to produce an object asynchronously, use a method.

One could allow modifiers for factories.
A factory for \code{Future} could be modified by \ASYNC,
a factory for \code{Stream} could be modified by \code{\ASYNC*},
and a factory for \code{Iterable} could be modified by \code{\SYNC*}.
No other scenario makes sense because
the object returned by the factory would be of the wrong type.
This situation is very unusual so it is not worth making an exception
to the general rule for constructors in order to allow it.%
}

\LMHash{}%
It is a compile-time error if the declared return type of
a function marked \ASYNC{} is not
a supertype of \code{Future<$T$>} for some type $T$.
It is a compile-time error if the declared return type of
a function marked \code{\SYNC*} is not
a supertype of \code{Iterable<$T$>} for some type $T$.
It is a compile-time error if the declared return type of
a function marked \code{\ASYNC*} is not
a supertype of \code{Stream<$T$>} for some type $T$.
It is a compile-time error if the declared return type of
a function marked \code{\SYNC*} or \code{\ASYNC*} is \VOID.

\LMHash{}%
We define the
\Index{union-free type derived from}
a type $T$ as follows:
If $T$ is of the form \code{$S$?}\ or the form \code{FutureOr<$S$>}
then the union-free type derived from $T$ is
the union-free type derived from $S$.
Otherwise, the union-free type derived from $T$ is $T$.
\commentary{%
  For example, the union-free type derived from
  \code{FutureOr<int?>?} is \code{int}.%
}

\LMHash{}%
We define the
\IndexCustom{element type of a generator function}{%
    function!generator!element type}
$f$ as follows:
%
Let $S$ be the union-free type derived from the declared return type of $f$.
%
If $f$ is a synchronous generator and
$S$ implements \code{Iterable<$U$>} for some $U$
(\ref{interfaceSuperinterfaces})
then the element type of $f$ is $U$.
%
If $f$ is an asynchronous generator and
$S$ implements \code{Stream<$U$>} for some $U$
then the element type of $f$ is $U$.
%
Otherwise, if $f$ is a generator (synchronous or asynchronous)
and $S$ is a supertype of \code{Object}
\commentary{(which includes \code{Object} itself)}
then the element type of $f$ is \DYNAMIC.
\commentary{No further cases are possible.}


\subsection{Function Declarations}
\LMLabel{functionDeclarations}

\LMHash{}%
A \Index{function declaration} is a function that
is neither a member of a class nor a function literal.
Function declarations include exactly the following:
\IndexCustom{library functions}{function!library},
which are function declarations
%(including getters and setters)
at the top level of a library, and
\IndexCustom{local functions}{function!local},
which are function declarations declared inside other functions.
Library functions are often referred to simply as top-level functions.

\LMHash{}%
A function declaration consists of an identifier indicating the function's name,
possibly prefaced by a return type.
The function name is followed by a signature and body.
For getters, the signature is empty.
The body is empty for functions that are external.

\LMHash{}%
The scope of a library function is the scope of the enclosing library.
The scope of a local function is described
in section~\ref{localFunctionDeclaration}.
In both cases, the name of the function is in scope
in its formal parameter scope
(\ref{formalParameters}).

\LMHash{}%
It is a compile-time error to preface a function declaration
with the built-in identifier \STATIC.

\LMHash{}%
When we say that a function $f_1$ \Index{forwards} to another function $f_2$,
we mean that invoking $f_1$ causes $f_2$ to be executed
with the same arguments and/or receiver as $f_1$,
and returns the result of executing $f_2$ to the caller of $f_1$,
unless $f_2$ throws an exception,
in which case $f_1$ throws the same exception.
Furthermore, we only use the term for
synthetic functions introduced by the specification.


\subsection{Formal Parameters}
\LMLabel{formalParameters}

\LMHash{}%
Every non-getter function declaration includes a
\Index{formal parameter list},
which consists of a list of required positional parameters
(\ref{requiredFormals}),
followed by any optional parameters (\ref{optionalFormals}).
The optional parameters may be specified either as
a set of named parameters or as a list of positional parameters,
but not both.

\LMHash{}%
Some function declarations include a
\Index{formal type parameter list} (\ref{functions}),
in which case we say that it is a
\IndexCustom{generic function}{function!generic}.
A \IndexCustom{non-generic function}{function!non-generic}
is a function which is not generic.

\LMHash{}%
The \Index{formal parameter part} of a function declaration consists of
the formal type parameter list, if any, and the formal parameter list.

\commentary{%
  The following kinds of functions cannot be generic:
  Getters, setters, operators, and constructors.%
}

\LMHash{}%
The formal type parameter list of a function declaration introduces
a new scope known as the function's
\IndexCustom{type parameter scope}{scope!type parameter}.
The type parameter scope of a generic function $f$ is enclosed in
the scope where $f$ is declared.
Every formal type parameter introduces a type into the type parameter scope.

\LMHash{}%
If it exists, the type parameter scope of a function $f$ is
the current scope for the signature of $f$,
and for the formal type parameter list itself;
otherwise the scope where $f$ is declared is
the current scope for the signature of $f$.

\commentary{%
  This means that formal type parameters are in scope
  in the bounds of parameter declarations,
  allowing for so-called F-bounded type parameters like

  \noindent
  \code{class C<X \EXTENDS{} Comparable<X>{}> \{ \ldots\ \}},

  \noindent
  and the formal type parameters are in scope for each other,
  allowing dependencies like
  \code{class D<X \EXTENDS{} Y, Y> \{ \ldots\ \}}.%
}

\LMHash{}%
The formal parameter list of a function declaration introduces
a new scope known as the function's
\IndexCustom{formal parameter scope}{scope!formal parameter}.
The formal parameter scope of a non-generic function $f$ is enclosed in
the scope where $f$ is declared.
The formal parameter scope of a generic function $f$ is enclosed in
the type parameter scope of $f$.
Every formal parameter introduces a local variable into
the formal parameter scope.
The current scope for the function's signature is
the scope that encloses the formal parameter scope.

\commentary{%
  This means that in a generic function declaration,
  the return type and parameter type annotations can use
  the formal type parameters,
  but the formal parameters are not in scope in the signature.%
}

\LMHash{}%
The body of a function declaration introduces
a new scope known as the function's
\IndexCustom{body scope}{scope!function body}.
The body scope of a function $f$ is enclosed in the scope introduced by
the formal parameter scope of $f$.

\LMHash{}%
It is a compile-time error if a formal parameter
is declared as a constant variable (\ref{variables}).

\begin{grammar}
<formalParameterList> ::= `(' `)'
  \alt `(' <normalFormalParameters> `,'? `)'
  \alt `(' <normalFormalParameters> `,' <optionalOrNamedFormalParameters> `)'
  \alt `(' <optionalOrNamedFormalParameters> `)'

<normalFormalParameters> ::= \gnewline{}
  <normalFormalParameter> (`,' <normalFormalParameter>)*

<optionalOrNamedFormalParameters> ::= <optionalPositionalFormalParameters>
  \alt <namedFormalParameters>

<optionalPositionalFormalParameters> ::= \gnewline{}
  `[' <defaultFormalParameter> (`,' <defaultFormalParameter>)* `,'? `]'

<namedFormalParameters> ::= \gnewline{}
  `{' <defaultNamedParameter> (`,' <defaultNamedParameter>)* `,'? `}'
\end{grammar}

\LMHash{}%
Formal parameter lists allow an optional trailing comma
after the last parameter (\syntax{`,'?}).
A parameter list with such a trailing comma is
equivalent in all ways to the same parameter list without the trailing comma.
All parameter lists in this specification are shown without a trailing comma,
but the rules and semantics apply equally to
the corresponding parameter list with a trailing comma.


\subsubsection{Required Formals}
\LMLabel{requiredFormals}

\LMHash{}%
A \Index{required formal parameter} may be specified in one of three ways:

\begin{itemize}
\item
  By means of a function signature that names the parameter and
  describes its type as a function type (\ref{functionTypes}).
  It is a compile-time error if any default values are specified
  in the signature of such a function type.
\item
  As an initializing formal, which is only valid as a parameter to
  a generative constructor (\ref{generativeConstructors}).
\item
  Via an ordinary variable declaration (\ref{variables}).
\end{itemize}

\begin{grammar}
<normalFormalParameter> ::= \gnewline{}
  <metadata> <normalFormalParameterNoMetadata>

<normalFormalParameterNoMetadata> ::= <functionFormalParameter>
  \alt <fieldFormalParameter>
  \alt <simpleFormalParameter>

<functionFormalParameter> ::= \gnewline{}
  \COVARIANT? <type>? <identifier> <formalParameterPart> `?'?

<simpleFormalParameter> ::= <declaredIdentifier>
  \alt \COVARIANT? <identifier>

<declaredIdentifier> ::= \COVARIANT? <finalConstVarOrType> <identifier>

<fieldFormalParameter> ::= \gnewline{}
  <finalConstVarOrType>? \THIS{} `.' <identifier> (<formalParameterPart> `?'?)?
\end{grammar}

\LMHash{}%
It is a compile-time error if a formal parameter has the modifier \CONST{}
or the modifier \LATE.
It is a compile-time error if \VAR{} occurs as
the first token of a \synt{fieldFormalParameter}.

\LMHash{}%
It is a compile-time error if a parameter derived from
\synt{fieldFormalParameter} occurs as a parameter of a function
which is not a non-redirecting generative constructor.

\commentary{%
  A \synt{fieldFormalParameter} declares an initializing formal,
  which is described elsewhere
  (\ref{generativeConstructors}).%
}

\LMHash{}%
It is possible to include the modifier \COVARIANT{}
in some forms of parameter declarations.
The effect of doing this is described in a separate section
(\ref{covariantParameters}).

\commentary{%
  Note that the non-terminal \synt{normalFormalParameter} is also used
  in the grammar rules for optional parameters,
  which means that such parameters can also be covariant.%
}

\LMHash{}%
It is a compile-time error if the modifier \COVARIANT{} occurs on
a parameter of a function which is not
an instance method, instance setter, or instance operator.


\subsubsection{Optional Formals}
\LMLabel{optionalFormals}

\LMHash{}%
Optional parameters may be specified and provided with default values.

\begin{grammar}
<defaultFormalParameter> ::= <normalFormalParameter> (`=' <expression>)?

<defaultNamedParameter> ::= \gnewline{}
  <metadata> \REQUIRED? <normalFormalParameterNoMetadata>
  \gnewline{} ((`=' | `:') <expression>)?
\end{grammar}

The form \syntax{<normalFormalParameter> `:' <expression>}
is equivalent to the form
\syntax{<normalFormalParameter> `=' <expression>}.
The colon-syntax is included only for backwards compatibility.
It is deprecated and will be removed in
a later version of the language specification.

\LMHash{}%
It is a compile-time error if the default value of an optional parameter is
not a constant expression (\ref{constants}).
If no default is explicitly specified for an optional parameter
an implicit default of \NULL{} is provided.

\LMHash{}%
It is a compile-time error if the name of a named optional parameter
begins with an `_' character.

\rationale{%
  The need for this restriction is a direct consequence of
  the fact that naming and privacy are not orthogonal.
  If we allowed named parameters to begin with an underscore,
  they would be considered private and inaccessible to
  callers from outside the library where it was defined.
  If a method outside the library overrode
  a method with a private optional name,
  it would not be a subtype of the original method.
  The static checker would of course flag such situations,
  but the consequence would be that adding a private named formal would break
  clients outside the library in a way they could not easily correct.%
}


\subsubsection{Covariant Parameters}
\LMLabel{covariantParameters}

\LMHash{}%
Dart allows formal parameters of instance methods,
including setters and operators,
to be declared \COVARIANT.

\commentary{%
  The syntax for doing this is specified in an earlier section
  (\ref{requiredFormals}).%
}

\LMHash{}%
It is a compile-time error if the modifier \COVARIANT{} occurs
in the declaration of a formal parameter of a function
which is not an instance method, an instance setter, or an operator.

\commentary{%
  As specified below, a parameter can also be covariant for other reasons.
  The overall effect of having a covariant parameter $p$
  in the signature of a given method $m$
  is to allow the type of $p$ to be overridden covariantly,
  which means that the type required at run time for a given actual argument
  may be a proper subtype of the type which is known at compile time
  at the call site.%
}

\rationale{%
  This mechanism allows developers to explicitly request that
  a compile-time guarantee which is otherwise supported
  (namely: that an actual argument whose static type satisfies the requirement
  will also do so at run time)
  is replaced by dynamic type checks.
  In return for accepting these dynamic type checks,
  developers can use covariant parameters to express software designs
  where the dynamic type checks are known (or at least trusted) to succeed,
  based on reasoning that the static type analysis does not capture.%
}

\LMHash{}%
\BlindDefineSymbol{m, X_j, s}%
Let $m$ be a method signature with formal type parameters
\List{X}{1}{s},
positional formal parameters \List{p}{1}{n},
\BlindDefineSymbol{p_j, n, q_j, k}%
and named formal parameters \List{q}{1}{k}.
\BlindDefineSymbol{m', X'_j}%
Let $m'$ be a method signature with formal type parameters
\List{X'\!}{1}{s},
positional formal parameters \List{p'\!}{1}{n'},
\BlindDefineSymbol{p'_j, n', q'_j, k'}%
and named formal parameters \List{q'\!}{1}{k'}.
%
Assume that $j \in 1 .. n'$, and $j \leq n$;
we say that $p'_j$ is the parameter in $m'$ that
\IndexCustom{corresponds}{parameter corresponds to parameter}
to the formal parameter $p_j$ in $m$.
Assume that $j \in 1 .. k'$ and $l \in 1 .. k$;
we say that $q'_j$ is the parameter in $m'$ that
\NoIndex{corresponds} to the formal parameter
$q_l$ in $m$ if $q'_j = q_l$.
%
Similarly, we say that the formal type parameter
$X'_j$ from $m'$
\NoIndex{corresponds} to the formal type parameter
$X_j$ from $m$, for all $j \in 1 .. s$.

\commentary{%
  This includes the case where $m$ respectively $m'$ has
  optional positional parameters,
  in which case $k = 0$ respectively $k' = 0$ must hold,
  but we can have $n \not= n'$.
  The case where the numbers of formal type parameters differ is not relevant.%
}

% Being covariant is a property of a parameter of the interface of a class;
% this means that we only talk about the originating keyword \COVARIANT{}
% and the class that contains the relevant declaration when we detect for
% the first time that a given parameter is covariant. From that point and on
% it is "carried" along the subtype links associated with class interfaces,
% such that we can get it inductively from an indirect superinterface just
% by checking whether the direct superinterfaces "have" a method signature
% with the relevant name and a corresponding parameter, and then checking
% that parameter. The same approach is applicable for covariant-by-class.

\LMHash{}%
\BlindDefineSymbol{C, m, p}%
Let $C$ be a class that declares
a method $m$ which has
a parameter $p$ whose declaration has the modifier \COVARIANT;
in this case we say that the parameter $p$ is
\IndexCustom{covariant-by-declaration}{parameter!covariant-by-declaration}.
%
In this case the interface of $C$ has the method signature $m$,
and that signature has the parameter $p$;
we also say that the parameter $p$ in this method signature is
\NoIndex{covariant-by-declaration}.
%
Finally, the parameter $p$ of the method signature $m$
of the interface of a class $C$ is
\NoIndex{covariant-by-declaration}
if a direct superinterface of $C$
has an accessible method signature $m'$ with the same name as $m$,
which has a parameter $p'$ that corresponds to $p$,
such that $p'$ is covariant-by-declaration.

\LMHash{}%
Assume that \BlindDefineSymbol{C, X_j, B_j, s}$C$ is a generic class
with formal type parameter declarations
\code{$X_1\ \EXTENDS\ B_1 \ldots,\ X_s\ \EXTENDS\ B_s$},
\BlindDefineSymbol{m, p, T}%
let $m$ be a declaration of an instance method in $C$
(which can be a method, a setter, or an operator),
let $p$ be a parameter declared by $m$, and
let $T$ be the declared type of $p$.
%
The parameter $p$ is
\IndexCustom{covariant-by-class}{parameter!covariant-by-class}
if, for any $j \in 1 .. s$,
$X_j$ occurs in a covariant or an invariant position in $T$.
%
In this case the interface of $C$ also has the method signature $m$,
and that signature has the parameter $p$;
we also say that the parameter $p$ in this method signature is
\NoIndex{covariant-by-class}.
Finally, the parameter $p$ of the method signature $m$
of the interface of the class $C$ is
\NoIndex{covariant-by-class}
if a direct superinterface of $C$
has an accessible method signature $m'$ with the same name as $m$,
which has a parameter $p'$ that corresponds to $p$,
such that $p'$ is covariant-by-class.

\LMHash{}%
A formal parameter $p$ is
\IndexCustom{covariant}{parameter!covariant}
if $p$ is covariant-by-declaration or $p$ is covariant-by-class.

\commentary{%
  It is possible for a parameter to be simultaneously
  covariant-by-declaration and covariant-by-class.
  Note that a parameter may be
  covariant-by-declaration or covariant-by-class
  based on a declaration in any direct or indirect superinterface,
  including any superclass:
  The definitions above propagate these properties
  to an interface from each of its direct superinterfaces,
  but they will in turn receive
  the property from their direct superinterfaces,
  and so on.%
}


\subsection{Type of a Function}
\LMLabel{typeOfAFunction}

\LMHash{}%
This section specifies the static type which is ascribed to
the function denoted by a function declaration,
and the dynamic type of the corresponding function object.

\LMHash{}%
In this specification,
the notation used to denote the type of a function,
that is, a \Index{function type},
follows the syntax of the language,
except that \EXTENDS{} is abbreviated to
\FunctionTypeExtends.
This means that every function type is of one of the forms
\FunctionTypePositionalStd{T_0}
\FunctionTypeNamedStd{T_0}

\noindent
where $T_0$ is the return type,
$X_j$ are the formal type parameters with bounds $B_j$, $j \in 1 .. s$,
$T_j$ are the formal parameter types for $j \in 1 .. n + k$,
and $x_{n+j}$ are the names of named parameters for $j \in 1 .. k$.
Non-generic function types are covered by the case $s = 0$,
where the type parameter declaration list
\code{<\ldots{}>}
as a whole is omitted.
%
Similarly, the optional brackets \code{[]} and \code{\{\}} are omitted
when there are no optional parameters.

% We promise that the two forms always get the same treatment for k=0.
\commentary{%
  Both forms with optionals cover function types with no optionals
  when $k = 0$,
  and every rule in this specification is such that
  any of the two forms may be used without ambiguity
  to determine the treatment of function types with no optionals.%
}

\LMHash{}%
If a function declaration does not declare a return type explicitly,
its return type is \DYNAMIC{} (\ref{typeDynamic}),
unless it is a constructor,
in which case it is not considered to have a return type,
or it is a setter or operator \code{[]=},
in which case its return type is \VOID.

\LMHash{}%
A function declaration may declare formal type parameters.
The type of the function includes the names of the type parameters
and for each type parameter the upper bound,
which is considered to be the built-in class \code{Object}
if no bound is specified.
When consistent renaming of type parameters
can make two function types identical,
they are considered to be the same type.

\commentary{%
  It is convenient to include the formal type parameter names in function types
  because they are needed in order to express such things as relations among
  different type parameters, F-bounds, and the types of formal parameters.
  However, we do not wish to distinguish between two function types
  if they have the same structure and only differ in the choice of names.
  This treatment of names is also known as alpha-equivalence.%
}

\LMHash{}%
In the following three paragraphs,
if the number \DefineSymbol{s} of formal type parameters is zero then
the type parameter list in the function type is omitted.

\LMHash{}%
Let $F$ be a function with
type parameters \TypeParametersStd,
required formal parameter types \List{T}{1}{n},
return type $T_0$,
and no optional parameters.
Then the static type of $F$ is
\FunctionTypeAllRequiredStd{T_0}.

\LMHash{}%
Let $F$ be a function with
type parameters \TypeParametersStd,
required formal parameter types \List{T}{1}{n},
return type $T_0$
and positional optional parameter types \List{T}{n+1}{n+k}.
Then the static type of $F$ is
\FunctionTypePositionalStd{T_0}.

\LMHash{}%
Let $F$ be a function with
type parameters \TypeParametersStd,
required formal parameter types \List{T}{1}{n},
return type $T_0$,
and named parameters \PairList{T}{x}{n+1}{n+k},
where $x_{n+j}$, $j \in 1 .. k$ may or may not have a default value.
Then the static type of $F$ is
\FunctionTypeNamedStd{T_0}.

\LMHash{}%
Let $T$ be the static type of a function declaration $F$.
Let $u$ be the run-time type of a function object $o$ obtained by
function closurization
(\ref{functionClosurization})
or instance method closurization
(\ref{instanceMethodClosurization})
applied to $F$,
and let $t$ be the actual type corresponding to $T$
at the occasion where $o$ was created
(\ref{actualTypes}).
\commentary{%
  $T$ may contain free type variables, but $t$ contains their actual values.%
}
The following must then hold:
$u$ is a class that implements the built-in class \FUNCTION;
$u$ is a subtype of $t$;
and $u$ is not a subtype of any function type which is a proper subtype of $t$.
\commentary{%
  If we had omitted the last requirement then
  \code{f \IS{} int\,\FUNCTION([int])}
  could evaluate to \TRUE{} with the declaration
  \code{\VOID{} f()\,\{\}},
  which is obviously not the intention.%
}

\rationale{%
  It is up to the implementation to choose
  an appropriate representation for function objects.
  For example, consider that
  a function object produced via property extraction
  treats equality differently from other function objects,
  and is therefore likely a different class.
  Implementations may also use different classes for function objects
  based on arity and or type.
  Arity may be implicitly affected by whether a function is
  an instance method (with an implicit receiver parameter) or not.
  The variations are manifold and, e.g.,
  one cannot assume that any two distinct function objects
  will necessarily have the same run-time type.%
}


\subsection{External Functions}
\LMLabel{externalFunctions}

\LMHash{}%
An \IndexCustom{external function}{function!external}
is a function whose body is provided separately from its declaration.
An external function may be
a top-level function (\ref{librariesAndScripts}),
a method (\ref{instanceMethods}, \ref{staticMethods}),
a getter (\ref{getters}),
a setter (\ref{setters}),
or a non-redirecting constructor
(\ref{generativeConstructors}, \ref{factories}).
External functions are introduced via the built-in identifier \EXTERNAL{}
(\ref{identifierReference})
followed by the function signature.

\rationale{%
  External functions allow us to introduce type information for code
  that is not statically known to the Dart compiler.%
}

\commentary{%
  Examples of external functions might be foreign functions
  (defined in C, or Javascript etc.),
  primitives of the implementation (as defined by the Dart run-time system),
  or code that was dynamically generated
  but whose interface is statically known.
  However, an abstract method is different from an external function,
  as it has \emph{no} body.%
}

\LMHash{}%
An external function is connected to its body by
an implementation specific mechanism.
Attempting to invoke an external function
that has not been connected to its body
will throw a \code{NoSuchMethodError} or some subclass thereof.

\LMHash{}%
An implementation specific compile-time error can be raised
at an \EXTERNAL{} function declaration.

\commentary{%
  Such errors are intended to indicate that
  every invocation of that function would throw, e.g.,
  because it is known that it will not be connected to a body.%
}

\LMHash{}%
The actual syntax is given in
sections \ref{classes} and \ref{librariesAndScripts} below.


\section{Classes}
\LMLabel{classes}

\LMHash{}%
A \Index{class} defines the form and behavior of a set of objects which are its
\IndexCustom{instances}{instance}.
Classes may be defined by class declarations as described below,
or via mixin applications (\ref{mixinApplication}).

\begin{grammar}
<classDeclaration> ::=
  \ABSTRACT? \CLASS{} <typeIdentifier> <typeParameters>?
  \gnewline{} <superclass>? <interfaces>?
  \gnewline{} `{' (<metadata> <memberDeclaration>)* `}'
  \alt \ABSTRACT? \CLASS{} <mixinApplicationClass>

<typeNotVoidList> ::= <typeNotVoid> (`,' <typeNotVoid>)*

<memberDeclaration> ::= <declaration> `;'
  \alt <methodSignature> <functionBody>

<methodSignature> ::= <constructorSignature> <initializers>?
  \alt <factoryConstructorSignature>
  \alt \STATIC? <functionSignature>
  \alt \STATIC? <getterSignature>
  \alt \STATIC? <setterSignature>
  \alt <operatorSignature>

<declaration> ::= \EXTERNAL{} <factoryConstructorSignature>
  \alt \EXTERNAL{} <constantConstructorSignature>
  \alt \EXTERNAL{} <constructorSignature>
  \alt (\EXTERNAL{} \STATIC?)? <getterSignature>
  \alt (\EXTERNAL{} \STATIC?)? <setterSignature>
  \alt (\EXTERNAL{} \STATIC?)? <functionSignature>
  \alt \EXTERNAL? <operatorSignature>
  \alt \STATIC{} \CONST{} <type>? <staticFinalDeclarationList>
  \alt \STATIC{} \FINAL{} <type>? <staticFinalDeclarationList>
  \alt \STATIC{} \LATE{} \FINAL{} <type>? <initializedIdentifierList>
  \alt \STATIC{} \LATE? <varOrType> <initializedIdentifierList>
  \alt \COVARIANT{} \LATE{} \FINAL{} <type>? <identifierList>
  \alt \COVARIANT{} \LATE? <varOrType> <initializedIdentifierList>
  \alt \LATE? \FINAL{} <type>? <initializedIdentifierList>
  \alt \LATE? <varOrType> <initializedIdentifierList>
  \alt <redirectingFactoryConstructorSignature>
  \alt <constantConstructorSignature> (<redirection> | <initializers>)?
  \alt <constructorSignature> (<redirection> | <initializers>)?

<staticFinalDeclarationList> ::= \gnewline{}
  <staticFinalDeclaration> (`,' <staticFinalDeclaration>)*

<staticFinalDeclaration> ::= <identifier> `=' <expression>
\end{grammar}

\LMHash{}%
It is possible to include the modifier \COVARIANT{}
in some forms of declarations.
The effect of doing this is described elsewhere
(\ref{covariantParameters}).

\LMHash{}%
A class has constructors, instance members and static members.
The members are declared by
\IndexCustom{member declarations}{member declaration}.
The \IndexCustom{instance members}{members!instance} of a class
are its instance methods, getters, setters and instance variables.
The \IndexCustom{static members}{members!static} of a class
are its static methods, getters, setters, and variables.
The \IndexCustom{members}{members} of a class
are its static and instance members.

\LMHash{}%
A class declaration introduces two scopes:

\begin{itemize}
\item
  A \IndexCustom{type-parameter scope}{scope!type parameter},
  which is empty if the class is not generic (\ref{generics}).
  The enclosing scope of the type-parameter scope of a class declaration is
  the library scope of the current library.
\item
  A \IndexCustom{body scope}{scope!class body}.
  The enclosing scope of the body scope of a class declaration is
  the type parameter scope of the class declaration.
\end{itemize}

\LMHash{}%
The current scope of an instance member declaration,
a static member declaration,
or a constructor declaration is
the body scope of the class in which it is declared.

\LMHash{}%
The current instance
\commentary{(and hence its members)}
can only be accessed at specific locations in a class:
We say that a location $\ell$
\IndexCustom{has access to \THIS}{has access to this@has access to \THIS}
if{}f $\ell$ is inside the body of a declaration of
an instance member or a generative constructor,
or in the initializing expression of a \LATE{} instance variable declaration.

\commentary{%
  Note that an initializing expression for a non-\LATE{} instance variable
  does not have access to \THIS,
  and neither does any part of a declaration marked \STATIC.%
}

\LMHash{}%
Every class has a single superclass
except class \code{Object} which has no superclass.
A class may implement a number of interfaces
by declaring them in its implements clause (\ref{superinterfaces}).

\LMHash{}%
An \IndexCustom{abstract class declaration}{class declaration!abstract}
is a class declaration that is explicitly declared
with the \ABSTRACT{} modifier.
A \IndexCustom{concrete class declaration}{class declaration!concrete}
is a class declaration that is not abstract.
An \IndexCustom{abstract class}{class!abstract} is a class
whose declaration is abstract, and
a \IndexCustom{concrete class}{class!concrete} is a class
whose declaration is concrete.

\rationale{%
  We want different behavior for concrete classes and abstract classes.
  If $A$ is intended to be abstract,
  we want the static checker to warn about any attempt to instantiate $A$,
  and we do not want the checker to complain about unimplemented methods in $A$.
  In contrast, if $A$ is intended to be concrete,
  the checker should warn about all unimplemented methods,
  but allow clients to instantiate it freely.%
}

\commentary{%
  The interface of a class $C$ is
  an implicit interface that declares instance member signatures
  that correspond to the instance members declared by $C$,
  and whose direct superinterfaces are
  the direct superinterfaces of $C$
  (\ref{interfaces}, \ref{superinterfaces}).%
}

\LMHash{}%
When a class name appears as a type,
that name denotes the interface of the class.

\LMHash{}%
It is a compile-time error if a class named $C$ declares
a member with basename (\ref{classMemberConflicts}) $C$.
If a generic class named $G$ declares a type variable named $X$,
it is a compile-time error
if $X$ is equal to $G$,
or if $G$ has a member whose basename is $X$,
or if $G$ has a constructor named \code{$G$.$X$}.

\commentary{%
  Here are simple examples, that illustrate the difference between
  ``has a member'' and ``declares a member''.
  For example, \code{B} \IndexCustom{declares}{declares member}
  one member named \code{f},
  but it \IndexCustom{has}{has member} two such members.
  The rules of inheritance determine what members a class has.%
}

\begin{dartCode}
\CLASS{} A \{
  \VAR{} i = 0;
  \VAR{} j;
  f(x) => 3;
\}
\\
\CLASS{} B \EXTENDS{} A \{
  int i = 1; // \comment{getter i and setter i= override versions from A}
  \STATIC{} j; // \comment{compile-time error: static getter \& setter conflict}
  // \comment{with instance getter \& setter}
\\
  // \comment{compile-time error: static method conflicts with instance method}
  \STATIC{} f(x) => 3;
\}
\end{dartCode}


\subsection{Fully Implementing an Interface}
\LMLabel{fullyImplementingAnInterface}

% Note that rules here and in \ref{instanceMethods} overlap, but they are
% both needed: This section is concerned with concrete methods, including
% inherited ones, and \ref{instanceMethods} is concerned with instance
% members declared in $C$, including both concrete and abstract ones.

\LMHash{}%
% The use of `concrete member' below may seem redundant, because a class
% does not inherit abstract members from its superclass, but this
% underscores the fact that even when an abstract declaration of $m$ is
% declared in $C$, $C$ does not "have" an $m$ which will suffice here.
A concrete class must fully implement its interface.
\BlindDefineSymbol{C, I, m}%
Let $C$ be a concrete class declared in library $L$, with interface $I$.
Assume that $I$ has a member signature $m$ which is accessible to $L$.
It is a compile-time error if $C$ does not have
a concrete member with the same name as $m$ and accessible to $L$,
unless $C$ has a non-trivial \code{noSuchMethod}
(\ref{theMethodNoSuchMethod}).

\LMHash{}%
Each concrete member must have a suitable signature:
Assume that $C$ has a concrete member with
the same name as $m$ and accessible to $L$,
and let \DefineSymbol{m''} be its member signature.
\commentary{%
  The concrete member may be declared in $C$ or inherited from a superclass.%
}
Let \DefineSymbol{m'} be the member signature which is obtained from $m''$
by adding, if not present already, the modifier \COVARIANT{}
(\ref{covariantParameters})
to each parameter $p$ in $m''$ where
the corresponding parameter in $m$ has the modifier \COVARIANT.
It is a compile-time error if $m'$ is not a correct override of $m$
(\ref{correctMemberOverrides}),
unless that concrete member is a \code{noSuchMethod} forwarder
(\ref{theMethodNoSuchMethod}).

\commentary{%
  Consider a concrete class \code{C},
  and assume that \code{C} declares or inherits
  a member implementation with the same name
  for every member signature in its interface.
  It is still an error if one or more of those member implementations
  has parameters or types such that they do not satisfy
  the corresponding member signature in the interface.
  For this check, any missing \COVARIANT{} modifiers are implicitly added
  to the signature of an inherited member (this is how we get $m'$ from $m''$).
  When the modifier \COVARIANT{} is added to one or more parameters
  (which will only happen when the concrete member is inherited),
  an implementation may choose to implicitly induce a forwarding method
  with the same signature as $m'$,
  in order to perform the required dynamic type check,
  and then invoke the inherited method.%
}

\LMHash{}%
It is an implementation specific choice whether or not
an implicitly induced forwarding method is used
when the modifier \COVARIANT{} is added to
one or more parameters in $m'$.

\commentary{%
  This is true in spite of the fact that
  such forwarding methods can be observed.
  E.g., we can compare
  the run-time type of a tearoff of the method from
  a receiver of type \code{C}
  to the run-time type of a tearoff of the super-method from
  a location in the body of \code{C}.%
}

\LMHash{}%
With or without a forwarding method,
the member signature in the interface of $C$ is $m$.

\commentary{%
  The forwarding method does not change the interface of \code{C},
  it is an implementation detail.
  In particular, this holds even in the case where
  an explicit declaration of the forwarding method would have
  changed the interface of \code{C}, because $m'$ is a subtype of $m$.

  When a class has a non-trivial \code{noSuchMethod},
  the class may leave some members unimplemented,
  and the class is allowed to have a \code{noSuchMethod} forwarder
  which does not satisfy the class interface
  (in which case it will be overridden by
  another \code{noSuchMethod} forwarder).

  Here is an example:%
}

\begin{dartCode}
\CLASS\ B \{
  \VOID\ m(int i) \{\} // \comment{Signature $m''$: \VOID\ m(int).}
\}
\\
\ABSTRACT\ \CLASS\ I \{
  \VOID\ m(\COVARIANT\ num n); // \comment{Signature: \VOID\ m(\COVARIANT\ num).}
\}
\\
\CLASS\ C \EXTENDS\ B \IMPLEMENTS\ I \{
  // \comment{Signature $m$: \VOID\ m(\COVARIANT\ num).}
  //
  // \comment{To check that this class fully implements its interface,}
  // \comment{check that $m'$, that is, \VOID\ m(\COVARIANT\ int),}
  // \comment{correctly overrides $m$: OK!}
\}
\end{dartCode}

\LMHash{}%
Parameters that are covariant-by-declaration
must also satisfy the following constraint:
Assume that the parameter $p$ of $m'$ has the modifier \COVARIANT.
Assume that a direct or indirect superinterface of $C$ has
a method signature $m_s$ with the same name as $m'$ and accessible to $L$,
such that $m_s$ has a parameter $p_s$ that corresponds to $p$.
In this situation, a compile-time error occurs
if the type of $p$ is not a subtype and not a supertype of the type of $p_s$.

\commentary{%
  This ensures that an inherited method satisfies the same constraint
  for each formal parameter which is covariant-by-declaration
  as the constraint which is specified for a declaration in $C$
  (\ref{instanceMethods}).%
}


\subsection{Instance Methods}
\LMLabel{instanceMethods}

\LMHash{}%
\IndexCustom{Instance methods}{method!instance}
are functions (\ref{functions})
whose declarations are immediately contained within a class declaration
and that are not declared \STATIC.
The \Index{instance methods of a class} $C$ are
the instance methods declared by $C$
and the instance methods inherited by $C$ from its superclass
(\ref{inheritanceAndOverriding}).

\LMHash{}%
\BlindDefineSymbol{C, D, m}%
Consider a class $C$
and an instance member declaration $D$ in $C$, with member signature $m$
(\ref{interfaces}).
It is a compile-time error if $D$ overrides a declaration
% Note that $m'$ is accessible, due to the definition of `overrides'.
with member signature $m'$
from a direct superinterface of $C$
(\ref{interfaceInheritanceAndOverriding}),
unless $m$ is a correct member override of $m'$
(\ref{correctMemberOverrides}).

\commentary{%
  This is not the only kind of conflict that may exist:
  An instance member declaration $D$ may conflict with another declaration $D'$,
  even in the case where they do not have the same name
  or they are not the same kind of declaration.
  E.g., $D$ could be an instance getter and $D'$ a static setter
  (\ref{classMemberConflicts}).%
}

\LMHash{}%
For each parameter $p$ of $m$ where \COVARIANT{} is present,
it is a compile-time error if there exists
a direct or indirect superinterface of $C$ which has
an accessible method signature $m''$ with the same name as $m$,
such that $m''$ has a parameter $p''$ that corresponds to $p$
(\ref{covariantParameters}),
unless the type of $p$ is a subtype or a supertype of the type of $p''$.

\commentary{%
  This means that
  a parameter which is covariant-by-declaration can have a type
  which is a supertype or a subtype of the type of
  a corresponding parameter in a superinterface,
  but the two types cannot be unrelated.
  Note that this requirement must be satisfied
  for each direct or indirect superinterface separately,
  because that relationship is not transitive.%
}

\rationale{%
  The superinterface may be the statically known type of the receiver,
  so this means that we relax the potential typing relationship
  between the statically known type of a parameter and the
  type which is actually required at run time
  to the subtype-or-supertype relationship,
  rather than the strict supertype relationship
  which applies to a parameter which is not covariant.
  It should be noted that it is not statically known
  at the call site whether any given parameter is covariant,
  because the covariance could be introduced in
  a proper subtype of the statically known type of the receiver.
  We chose to give priority to flexibility rather than safety here,
  because the whole point of covariant parameters is that developers
  can make the choice to increase the flexibility
  in a trade-off where some static type safety is lost.%
}


\subsubsection{Operators}
\LMLabel{operators}

\LMHash{}%
\IndexCustom{Operators}{operators} are instance methods with special names,
except for operator \lit{[]} which is an instance getter
and operator \lit{[]=} which is an instance setter.

\begin{grammar}
<operatorSignature> ::= \gnewline{}
  <type>? \OPERATOR{} <operator> <formalParameterList>

<operator> ::= `~'
  \alt <binaryOperator>
  \alt `[]'
  \alt `[]='

<binaryOperator> ::= <multiplicativeOperator>
  \alt <additiveOperator>
  \alt <shiftOperator>
  \alt <relationalOperator>
  \alt `=='
  \alt <bitwiseOperator>
\end{grammar}

\LMHash{}%
An operator declaration is identified using the built-in identifier
(\ref{identifierReference})
\OPERATOR.

\LMHash{}%
The following names are allowed for user-defined operators:
\lit{<},
\lit{>},
\lit{<=},
\lit{>=},
\lit{==},
\lit{-},
\lit{+},
\lit{/},
\lit{\gtilde/},
\lit{*},
\lit{\%},
\lit{|},
\lit{\^},
\lit{\&},
\lit{\ltlt},
\lit{\gtgtgt},
\lit{\gtgt},
\lit{[]=},
\lit{[]},
\lit{\gtilde}.

\LMHash{}%
It is a compile-time error if the arity of the user-declared operator
\lit{[]=} is not 2.
It is a compile-time error if the arity of a user-declared operator
with one of the names:
\lit{<},
\lit{>},
\lit{<=},
\lit{>=},
\lit{==},
\lit{-},
\lit{+},
\lit{\gtilde/},
\lit{/},
\lit{*},
\lit{\%},
\lit{|},
\lit{\^},
\lit{\&},
\lit{\ltlt},
\lit{\gtgtgt},
\lit{\gtgt},
\lit{[]}
is not 1.
It is a compile-time error if the arity of the user-declared operator
\lit{-}
is not 0 or 1.

\commentary{%
  The \lit{-} operator is unique
  in that two overloaded versions are permitted.
  If the operator has no arguments, it denotes unary minus.
  If it has an argument, it denotes binary subtraction.%
}

\LMHash{}%
The name of the unary operator \lit{-} is \code{unary-}.

\rationale{%
  This device allows the two methods to be distinguished
  for purposes of method lookup, override and reflection.%
}

\LMHash{}%
It is a compile-time error if the arity of the user-declared operator
\lit{\gtilde}
is not 0.

\LMHash{}%
It is a compile-time error to declare an optional parameter in an operator.

\LMHash{}%
It is a compile-time error if a user-declared operator \lit{[]=}
declares a return type other than \VOID.

\commentary{%
  If no return type is specified for a user-declared operator
  \lit{[]=},
  its return type is \VOID{} (\ref{typeOfAFunction}).%
}

\rationale{%
  The return type is \VOID{} because
  a return statement in an implementation of operator
  \lit{[]=}
  does not return an object.
  Consider a non-throwing evaluation of an expression $e$ of the form
  \code{$e_1$[$e_2$] = $e_3$},
  and assume that the evaluation of $e_3$ yields an object $o$.
  $e$ will then evaluate to $o$,
  and even if the executed body of operator
  \lit{[]=}
  completes with an object $o'$,
  that is, if $o'$ is returned it is simply ignored.
  The rationale for this behavior is that
  assignments should be guaranteed to evaluate to the assigned object.%
}


\subsubsection{The Method \code{noSuchMethod}}
\LMLabel{theMethodNoSuchMethod}

\LMHash{}%
The method \code{noSuchMethod} is invoked implicitly during execution
in situations where one or more member lookups fail
(\ref{ordinaryInvocation},
\ref{getterAccessAndMethodExtraction},
\ref{assignment}).

\commentary{%
  We may think of \code{noSuchMethod} as a backup
  which kicks in when an invocation of a member $m$ is attempted,
  but there is no member named $m$,
  or it exists,
  but the given invocation has an argument list shape
  that does not fit the declaration of $m$
  (passing fewer positional arguments than required or more than supported,
  or passing named arguments with names not declared by $m$).
  % The next sentence covers both function objects and instances of
  % a class with a method named \CALL, because we would have a
  % compile-time error invoking \CALL{} with a wrongly shaped argument
  % list unless the type is \DYNAMIC{} or \FUNCTION.
  This can only occur for an ordinary method invocation
  when the receiver has static type \DYNAMIC,
  or for a function invocation when
  the invoked function has static type \FUNCTION{} or \DYNAMIC.
  %
  The method \code{noSuchMethod} can also be invoked in other ways, e.g.,
  it can be called explicitly like any other method,
  and it can be invoked from a \code{noSuchMethod} forwarder,
  as explained below.%
}

\LMHash{}%
We say that a class $C$ \Index{has a non-trivial \code{noSuchMethod}}
if $C$ has a concrete member named \code{noSuchMethod}
which is distinct from the one declared in the built-in class \code{Object}.

\commentary{%
  Note that it must be a method that accepts one positional argument,
  in order to correctly override \code{noSuchMethod} in \code{Object}.
  For instance, it can have signature
  \code{noSuchMethod(Invocation i)} or
  \code{noSuchMethod(Object i, [String s = ''])},
  but not
  \code{noSuchMethod(Invocation i, String s)}.
  This implies that the situation where \code{noSuchMethod} is invoked
  (explicitly or implicitly)
  with one actual argument cannot fail for the reason that
  ``there is no such method'',
  such that we would enter an infinite loop
  trying to invoke \code{noSuchMethod}.
  It \emph{is} possible, however, to encounter a dynamic error
  during an invocation of \code{noSuchMethod}
  because the actual argument fails to satisfy a type check,
  but that situation will give rise to a dynamic type error
  rather than a repeated attempt to invoke \code{noSuchMethod}
  (\ref{bindingActualsToFormals}).
  Here is an example where a dynamic type error occurs because
  an attempt is made to pass an \code{Invocation}
  where only the null object is accepted:%
}

\begin{dartCode}
\CLASS{} A \{
  noSuchMethod(\COVARIANT{} Null n) => n;
\}
\\
\VOID{} main() \{
  \DYNAMIC{} d = A();
  d.foo(42); // Dynamic type error when invoking noSuchMethod.
\}
\end{dartCode}

\LMHash{}%
\BlindDefineSymbol{C, L, m}%
Let $C$ be a concrete class,
let $L$ be the library that contains the declaration of $C$,
and let $m$ be a name.
Then $m$ is \Index{noSuchMethod forwarded} in $C$ if{}f
one of the following is true:

\begin{itemize}
\item \textbf{Requested in program:}
  $C$ has a non-trivial \code{noSuchMethod},
  the interface of $C$ contains a member signature $S$ named $m$,
  and $C$ has no concrete member named $m$ and accessible to $L$
  that correctly overrides $S$
  \commentary{%
    (that is, no member named $m$ is declared or inherited by $C$,
    or one is inherited, but it does not have the required signature)%
  }.
  In this case we also say that $S$ is noSuchMethod forwarded.
\item
  \textbf{Forced by privacy:}
  There exists a direct or indirect superinterface
  $D$ of $C$ which is declared in a library $L_2$ different from $L$,
  the interface of $D$ contains a member signature $S$ named $m$,
  $m$ is a private name,
  and no superclass of $C$ has
  a concrete member named $m$ accessible to $L_2$
  that correctly overrides $S$.
  In this case we also say that $S$ is noSuchMethod forwarded.
\end{itemize}

\LMHash{}%
For a concrete class $C$, a
\Index{noSuchMethod forwarder}
is implicitly induced for each member signature
which is noSuchMethod forwarded.

\LMHash{}%
It is a compile-time error if the name $m$ is noSuchMethod forwarded
in a concrete class $C$,
and a superclass of $C$ has an accessible concrete declaration of $m$
which is not a noSuchMethod forwarder.

\LMHash{}%
%% TODO(eernst): We used to say `the interface of $C$ or $D$'; but we
%% need to change `accessible' to a scheme similar to name-merging everywhere
%% in order to be able to say this precisely.
A noSuchMethod forwarder is a concrete member of $C$
with the signature taken from the interface of $C$,
and with the same default value for each optional parameter.
It can be invoked in an ordinary invocation and in a superinvocation,
and when $m$ is a method it can be closurized
(\ref{instanceMethodClosurization})
using a property extraction
(\ref{propertyExtraction}).

\commentary{%
  The error concerned with an implictly induced forwarder
  that would override a human-written declaration
  can only occur if that concrete declaration does not
  correctly override $S$. Consider the following example:%
}

\begin{dartCode}
\CLASS{} A \{
  foo(int i) => \NULL;
\}

\ABSTRACT{} \CLASS{} B \{
  foo([int i]);
\}

\CLASS{} C \EXTENDS{} A \IMPLEMENTS{} B \{
  noSuchMethod(Invocation i) => ...;
  // Error: noSuchMethod forwarder cannot override `A.foo`.
\}
\end{dartCode}

\commentary{%
  In this example,
  an implementation with signature \code{foo(int i)} is inherited by \code{C},
  and the superinterface \code{B} declares
  the signature \code{foo([int i])}.
  This is a compile-time error because \code{C} does not have
  a method implementation with signature \code{foo([int])}.
  We do not wish to implicitly induce
  a \code{noSuchMethod} forwarder with signature \code{foo([int])}
  because it would override \code{A.foo},
  and that is likely to be highly confusing for developers.
  %
  In particular, it would cause an invocation like \code{C().foo(42)}
  to invoke \code{noSuchMethod},
  even though that is an invocation which is correct for
  the declaration of \code{foo} in \code{A}.
  %
  Hence, we require developers to explicitly resolve the conflict
  whenever an implicitly induced \code{noSuchMethod} forwarder
  would override an explicitly declared inherited implementation.
  %
  It is no problem, however,
  to let a \code{noSuchMethod} forwarder override
  another \code{noSuchMethod} forwarder,
  and hence there is no error in that situation.%
}

\commentary{%
  This implies that a \code{noSuchMethod} forwarder has the same
  properties as an explicitly declared concrete member,
  except of course that a \code{noSuchMethod} forwarder
  does not prevent itself or another noSuchMethod forwarder from being induced.
  We do not specify the body of a \code{noSuchMethod} forwarder,
  but it will invoke \code{noSuchMethod},
  and we specify the dynamic semantics of executing it below.%
}

\commentary{%
  At the beginning of this section we mentioned that implicit invocations
  of \code{noSuchMethod} can only occur
  with a receiver of static type \DYNAMIC{}
  or a function of static type \DYNAMIC{} or \FUNCTION.
  With a \code{noSuchMethod} forwarder,
  \code{noSuchMethod} can also be invoked
  on a receiver whose static type is not \DYNAMIC.
  No similar situation exists for functions,
  because it is impossible to induce a \code{noSuchMethod} forwarder
  into the class of a function object.%
}

\commentary{%
  For a concrete class $C$,
  we may think of a non-trivial \code{noSuchMethod}
  (declared in or inherited by $C$)
  as a request for ``automatic implementation'' of all unimplemented members
  in the interface of $C$ as \code{noSuchMethod} forwarders.
  Similarly, there is an implicit request for
  automatic implementation of all unimplemented
  inaccessible members of any concrete class,
  whether or not there is a non-trivial \code{noSuchMethod}.
  Note that the latter cannot be written explicitly in Dart,
  because their names are inaccessible;
  but the language can still specify that they are induced implicitly,
  because compilers control the treatment of private names.%
}

\LMHash{}%
\BlindDefineSymbol{C, m, X_j, r}%
For the dynamic semantics,
assume that a class $C$ has an implicitly induced
\code{noSuchMethod} forwarder named $m$,
with formal type parameters
\code{$X_1,\ \ldots,\ X_r$},
positional formal parameters
\BlindDefineSymbol{a_j, k, x_j, n}%
\code{$a_1,\ \ldots,\ a_k$}
\commentary{(some of which may be optional when $n = 0$)},
and named formal parameters with names
\code{$x_1,\ \ldots,\ x_n$}
\commentary{(with default values as mentioned above)}.

\commentary{%
  For this purpose we need not distinguish between
  a signature that has optional positional parameters and
  a signature that has named parameters,
  because the former is covered by $n = 0$.%
}

\LMHash{}%
The execution of the body of $m$ creates
an instance \DefineSymbol{im} of the predefined class \code{Invocation}
such that:

\begin{itemize}
\item \code{$im$.isMethod} evaluates to \TRUE{} if{}f $m$ is a method.
\item \code{$im$.isGetter} evaluates to \TRUE{} if{}f $m$ is a getter.
\item \code{$im$.isSetter} evaluates to \TRUE{} if{}f $m$ is a setter.
\item \code{$im$.memberName} evaluates to the symbol \code{m}.
\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
  whose dynamic type implements \code{List<Object>},
  containing the same objects as the list resulting from evaluation of
  \code{<Object>[$a_1, \ldots,\ a_k$]}.
\item \code{$im$.namedArguments} evaluates to an unmodifiable map
  whose dynamic type implements \code{Map<Symbol, Object>},
  with the same keys and values as the map resulting from evaluation of

  \code{<Symbol, Object>\{$\#x_1$: $x_1, \ldots,\ \#x_m$: $x_m$\}}.
\item \code{$im$.typeArguments} evaluates to an unmodifiable list
  whose dynamic type implements \code{List<Type>},
  containing the same objects as the list resulting from evaluation of
  \code{<Type>[$X_1, \ldots,\ X_r$]}.
\end{itemize}

\LMHash{}%
Next, \code{noSuchMethod} is invoked with $im$ as the actual argument,
and the result obtained from there is returned by the execution of $m$.

\commentary{%
  This is an ordinary method invocation of \code{noSuchMethod}
  (\ref{ordinaryInvocation}).
  That is, a \code{noSuchMethod} forwarder in a class $C$ can invoke
  an implementation of \code{noSuchMethod} that is declared in
  a subclass of $C$.

  Dynamic type checks on the actual arguments passed to $m$
  are performed in the same way as for an invocation of an
  explicitly declared method.
  In particular, an actual argument passed to a covariant parameter
  will be checked dynamically.

  Also, like other ordinary method invocations,
  it is a dynamic type error if the result returned by
  a \code{noSuchMethod} forwarder has a type which is not a subtype
  of the return type of the forwarder.

  One special case to be aware of is where a forwarder is torn off
  and then invoked with an actual argument list which does not match
  the formal parameter list.
  In that situation we will get an invocation of
  \code{Object.noSuchMethod}
  rather than the \code{noSuchMethod} in the original receiver,
  because this is an invocation of a function object
  (and they do not override \code{noSuchMethod}):%
}

\begin{dartCode}
\CLASS{} A \{
  noSuchMethod(Invocation i) => \NULL;
  \VOID{} foo();
\}
\\
\VOID{} main() \{
  A a = A();
  \FUNCTION{} f = a.foo;
  // Invokes `Object.noSuchMethod`, which throws.
  f(42);
\}
\end{dartCode}


\subsubsection{The Operator `==' and Primitive Equality}
\LMLabel{theOperatorEqualsEquals}

\LMHash{}%
The operator \lit{==} is used implicitly in certain situations,
and in particular constant expressions
(\ref{constants})
give rise to constraints on that operator.
The situation is similar with the getter \code{hashCode}.
In order to specify these constraints just once we introduce the notion of
\Index{primitive equality}.

\rationale{%
  Certain constant expressions are known to have a value
  whose equality is primitive.
  This is useful to know because it allows
  the value of equality expressions
  and the value of invocations of \code{hashCode}
  to be computed at compile-time.
  In particular, this can be used to build
  constant collections at compile-time,
  and it can be used to check that
  all elements in a constant set are distinct,
  and all keys in a constant map are distinct.%
}

\begin{itemize}
\item The null object has primitive equality
  (\ref{null}).
\item Every instance of type \code{bool}, \code{int}, and \code{String}
  has primitive equality.
\item Every instance of type \code{Symbol}
  which was originally obtained by evaluation of a literal symbol or
  a constant invocation of a constructor of the \code{Symbol} class
  has primitive equality.
\item
  %% TODO(eernst): With Dart 2.15, we need to mention `List<int>` here,
  %% unless 'constant type literal' includes that case.
  Every instance of type \code{Type}
  which was originally obtained by evaluating a constant type literal
  (\ref{dynamicTypeSystem})
  has primitive equality.
\item
  Let $o$ be an object obtained by evaluation of a constant list literal
  (\ref{lists}),
  a constant map literal
  (\ref{maps}), or
  a constant set literal
  (\ref{sets}),
  then $o$ has primitive equality.
\item
  %% TODO(eernst): With Dart 2.15, consider `f<int>`.
  A function object obtained by function closurization of
  a static method or a top-level function
  (\ref{functionClosurization})
  as the value of a constant expression
  has primitive equality.
\item
  An instance $o$ has primitive equality
  if the dynamic type of $o$ is a class $C$,
  and $C$ has primitive equality.
\item
  The class \code{Object} has primitive equality.
\item
  A class $C$ has primitive equality
  if it does not have an implementation of the operator \lit{==}
  that overrides the one inherited from \code{Object},
  and it does not have an implementation of the getter \code{hashCode}
  that overrides the one inherited from \code{Object}.
\end{itemize}

\LMHash{}%
When we say that a given instance or class
\IndexCustom{does not have primitive equality}{%
  primitive equality!does not have},
it means that it is not true that said instance or class
has primitive equality.


\subsection{Getters}
\LMLabel{getters}

\LMHash{}%
Getters are functions (\ref{functions}) that are used
to retrieve the values of object properties.

\begin{grammar}
<getterSignature> ::= <type>? \GET{} <identifier>
\end{grammar}

\LMHash{}%
If no return type is specified, the return type of the getter is \DYNAMIC.

\LMHash{}%
A getter definition that is prefixed with the \STATIC{} modifier defines
a static getter.
Otherwise, it defines an instance getter.
The name of the getter is given by the identifier in the definition.

\LMHash{}%
The \Index{instance getters of a class} $C$ are
those instance getters declared by $C$,
either implicitly or explicitly,
and the instance getters inherited by $C$ from its superclass.
The \Index{static getters of a class} $C$ are
those static getters declared by $C$.

\commentary{%
  A getter declaration may conflict with other declarations
  (\ref{classMemberConflicts}).
  In particular, a getter can never override a method,
  and a method can never override a getter or an instance variable.
  The rules for when a getter correctly overrides another member
  are given elsewhere
  (\ref{correctMemberOverrides}).%
}


\subsection{Setters}
\LMLabel{setters}

\LMHash{}%
Setters are functions (\ref{functions}) that are used to set
the values of object properties.

\begin{grammar}
<setterSignature> ::= <type>? \SET{} <identifier> <formalParameterList>
\end{grammar}

\commentary{%
  If no return type is specified, the return type of the setter is \VOID{}
  (\ref{typeOfAFunction}).%
}

\LMHash{}%
A setter definition that is prefixed with the \STATIC{} modifier defines
a static setter.
Otherwise, it defines an instance setter.
The name of a setter is obtained by appending the string `=' to
the identifier given in its signature.

\commentary{%
  Hence, a setter name can never conflict with, override or be overridden by
  a getter or method.%
}

\LMHash{}%
The \Index{instance setters of a class} $C$ are
those instance setters declared by $C$
either implicitly or explicitly,
and the instance setters inherited by $C$ from its superclass.
The \Index{static setters of a class} $C$ are
those static setters declared by $C$,
either implicitly or explicitly.

\LMHash{}%
It is a compile-time error if a setter's formal parameter list
does not consist of exactly one required formal parameter $p$.
\rationale{%
  We could enforce this via the grammar,
  but we'd have to specify the evaluation rules in that case.%
}

\LMHash{}%
It is a compile-time error if a setter declares a return type other than \VOID.
It is a compile-time error if a class has
a setter named \code{$v$=} with argument type $T$ and
a getter named $v$ with return type $S$,
and $S$ may not be assigned to $T$.

\commentary{%
  The rules for when a setter correctly overrides another member
  are given elsewhere
  (\ref{correctMemberOverrides}).
  A setter declaration may conflict with other declarations as well
  (\ref{classMemberConflicts}).%
}


\subsection{Abstract Instance Members}
\LMLabel{abstractInstanceMembers}

\LMHash{}%
An \IndexCustom{abstract method}{method!abstract}
(respectively,
\IndexCustom{abstract getter}{getter!abstract} or
\IndexCustom{abstract setter}{setter!abstract})
is an instance method, getter or setter that is not declared \EXTERNAL{}
and does not provide an implementation.
A \IndexCustom{concrete method}{method!concrete}
(respectively,
\IndexCustom{concrete getter}{getter!concrete} or
\IndexCustom{concrete setter}{setter!concrete})
is an instance method, getter or setter that is not abstract.

\rationale{%
  Abstract instance members are useful because of their interplay with classes.
  Every Dart class induces an implicit interface,
  and Dart does not support specifying interfaces explicitly.
  Using an abstract class instead of a traditional interface
  has important advantages.
  An abstract class can provide default implementations.
  It can also provide static methods,
  obviating the need for service classes
  such as \code{Collections} or \code{Lists},
  whose entire purpose is to group utilities related to a given type.%
}

\commentary{%
  Invocation of an abstract method, getter, or setter cannot occur,
  because lookup (\ref{lookup}) will never yield
  an abstract member as its result.
  One way to think about this is that
  an abstract member declaration in a subclass
  does not override or shadow an inherited member implementation.
  It only serves to specify the signature of the given member that
  every concrete subtype must have an implementation of;
  that is, it contributes to the interface of the class,
  not to the class itself.%
}

\rationale{%
  The purpose of an abstract method is to provide a declaration
  for purposes such as type checking and reflection.
  In mixins, it is often useful to introduce such declarations for methods that
  the mixin expects will be provided by the superclass the mixin is applied to.%
}

\rationale{%
  We wish to detect if one declares a concrete class with abstract members.
  However, code like the following should work:%
}

\begin{dartCode}
class Base \{
  int get one => 1;
\}
\\
\ABSTRACT{} \CLASS{} Mix \{
  int get one;
  int get two => one + one;
\}
\\
\CLASS{} C extends Base with Mix \{ \}
\end{dartCode}

\rationale{%
  At run time, the concrete method \code{one} declared in \code{Base}
  will be executed,
  and no problem should arise.
  Therefore no error should be raised
  if a corresponding concrete member exists in the hierarchy.%
}


\subsection{Instance Variables}
\LMLabel{instanceVariables}

\LMHash{}%
\IndexCustom{Instance variables}{variables!instance}
are variables whose declarations
are immediately contained within a class declaration
and that are not declared \STATIC.
The \Index{instance variables of a class} $C$ are
the instance variables declared by $C$
and the instance variables inherited by $C$ from its superclass.

\LMHash{}%
It is a compile-time error if an instance variable is declared to be constant.

\rationale{%
  The notion of a constant instance variable
  is subtle and confusing to programmers.
  An instance variable is intended to vary per instance.
  A constant instance variable would have the same value for all instances,
  and as such is already a dubious idea.

  The language could interpret const instance variable declarations as
  instance getters that return a constant.
  However, a constant instance variable could not be treated as
  a true compile-time constant,
  as its getter would be subject to overriding.

  Given that the value does not depend on the instance,
  it is better to use a static variable.
  An instance getter for it can always be defined manually if desired.%
}

\LMHash{}%
It is possible for the declaration of an instance variable
to include the modifier \COVARIANT{}
(\ref{variables}).
The effect of this is that the formal parameter of
the corresponding implicitly induced setter
is considered to be covariant-by-declaration
(\ref{covariantParameters}).

\commentary{%
  The modifier \COVARIANT{} on an instance variable has no other effects.
  In particular, the return type of the implicitly induced getter
  can already be overridden covariantly without \COVARIANT,
  and it can never be overridden to a supertype or an unrelated type,
  regardless of whether the modifier \COVARIANT{} is present.%
}


\subsection{Constructors}
\LMLabel{constructors}

\LMHash{}%
A \Index{constructor} is a special function that is used
in instance creation expressions (\ref{instanceCreation}) to obtain objects,
typically by creating or initializing them.
Constructors may be generative (\ref{generativeConstructors})
or they may be factories (\ref{factories}).

\LMHash{}%
A \Index{constructor name} always begins with
the name of its immediately enclosing class,
and may optionally be followed by a dot and an identifier \id.
It is a compile-time error if the name of a constructor
is not a constructor name.

\LMHash{}%
The
\IndexCustom{function type of a constructor}{function type!of a constructor}
$k$ is the function type
whose return type is the class that contains the declaration of $k$,
and whose formal parameter types, optionality, and names of named parameters
correspond to the declaration of $k$.

\commentary{%
  Note that the function type $F$ of a constructor $k$ may contain
  type variables declared by the enclosing class $C$.
  In that case we can apply a substitution to $F$, as in
  $[T_1/X_1, \ldots, T_m/X_m]F$,
  where $X_j, j \in 1 .. m$ are the formal type parameters of $C$
  and $T_j, j \in 1 .. m$ are specified in the given context.
  We may also omit such a substitution when the given context is
  the body scope of $C$, where $X_1, \ldots, X_m$ are in scope.%
}

\commentary{%
  A constructor declaration may conflict with static member declarations
  (\ref{classMemberConflicts}).%
}

\commentary{%
  A constructor declaration does not introduce a name into a scope.
  If a function expression invocation
  (\ref{functionExpressionInvocation})
  or an instance creation
  (\ref{instanceCreation})
  denotes a constructor as
  $C$, \code{$prefix$.$C$}, \code{$C$.\id}, or \code{\metavar{prefix}.$C$.\id},
  resolution relies on the library scope to determine the class
  (possibly via an import prefix).
  The class declaration is then directly checked for
  whether it has a constructor named $C$ respectively \code{$C$.\id}.
  It is not possible for an identifier to directly refer to a constructor,
  since the constructor is not in any scope used for resolving identifiers.%
}

\LMHash{}%
If{}f no constructor is specified for a class $C$,
it implicitly has a default constructor \code{C():\ \SUPER()\ \{\}},
unless $C$ is the built-in class \code{Object}.
%% TODO(eernst): With null safety, add `or \code{Null}`.


\subsubsection{Generative Constructors}
\LMLabel{generativeConstructors}

\LMHash{}%
A \IndexCustom{generative constructor}{constructor!generative}
declaration consists of a constructor name, a formal parameter list
(\ref{formalParameters}),
and either a redirect clause or an initializer list and an optional body.

\begin{grammar}
<constructorSignature> ::= <constructorName> <formalParameterList>

<constructorName> ::= <typeIdentifier> (`.' <identifier>)?
\end{grammar}

\commentary{%
  See \synt{declaration} and \synt{methodSignature} for grammar rules
  introducing a redirection or an initializer list and a body.%
}

%% TODO(eernst): Add `\Error{...}` below when that command is added.
\LMHash{}%
A compile-time error occurs if a generative constructor declaration
has a body of the form `\code{=>\,\,$e$;}'.

\commentary{%
  In other function declarations,
  this kind of body is taken to imply that the value of $e$ is returned,
  but generative constructors do not return anything.%
}

\LMHash{}%
If a formal parameter declaration $p$ is derived from
\synt{fieldFormalParameter},
it declares an \Index{initializing formal parameter}.
A term of the form \code{\THIS.\id} is contained in $p$,
and \id{} is the \NoIndex{name} of $p$.
It is a compile-time error if \id{} is not also the name of
an instance variable of the immediately enclosing class or enum.

\LMHash{}%
It is a compile-time error for an initializing formal parameter
to occur in any function which is not a generative constructor.
Also, it is a compile-time error for an initializing formal parameter
to occur in a redirecting or external constructor.
\commentary{In particuar, there is always an enclosing class or enum.}

\LMHash{}%
Assume that $p$ is a declaration of an initializing formal parameter named \id.
Let $T_{id}$ be the type of the instance variable named \id{} in
the immediately enclosing class or enum.
If $p$ has a type annotation $T$ then the declared type of $p$ is $T$.
Otherwise, the declared type of $p$ is $T_{id}$.
It is a compile-time error if the declared type of $p$
is not a subtype of $T_{id}$.

\LMHash{}%
Initializing formals constitute an exception to the rule that
every formal parameter introduces a local variable into
the formal parameter scope (\ref{formalParameters}).
When the formal parameter list of a non-redirecting generative constructor
contains any initializing formals, a new scope is introduced, the
\IndexCustom{formal parameter initializer scope}{%
  scope!formal parameter initializer},
which is the current scope of the initializer list of the constructor,
and which is enclosed in the scope where the constructor is declared.
Each initializing formal in the formal parameter list
introduces a final local variable into the formal parameter initializer scope,
but not into the formal parameter scope;
every other formal parameter introduces a local variable into
both the formal parameter scope and the formal parameter initializer scope.

\commentary{%
  This means that formal parameters, including initializing formals,
  must have distinct names, and that initializing formals
  are in scope for the initializer list,
  but they are not in scope for the body of the constructor.
  When a formal parameter introduces a local variable into two scopes,
  it is still one variable and hence one storage location.
  The type of the constructor is defined in terms of its formal parameters,
  including the initializing formals.%
}

\LMHash{}%
Initializing formals are executed during
the execution of generative constructors detailed below.
Executing an initializing formal \code{\THIS.\id}
causes the instance variable \id{} of the immediately surrounding class
to be assigned the value of the corresponding actual parameter,
% This can occur due to a failing implicit cast.
unless the assigned object has a dynamic type
which is not a subtype of the declared type of the instance variable \id,
in which case a dynamic error occurs.

\commentary{%
  The above rule allows initializing formals to be used as optional parameters:%
}

\begin{dartCode}
class A \{
  int x;
  A([this.x]);
\}
\end{dartCode}

\commentary{%
  is legal, and has the same effect as%
}

\begin{dartCode}
class A \{
  int x;
  A([int x]): this.x = x;
\}
\end{dartCode}

\LMHash{}%
A \Index{fresh instance} is an instance whose identity is distinct from
any previously allocated instance of its class.
A generative constructor always operates on a fresh instance of
its immediately enclosing class.

\commentary{%
  The above holds if the constructor is actually run, as it is by \NEW.
  If a constructor $c$ is referenced by \CONST, $c$ may not be run;
  instead, a canonical object may be looked up.
  See the section on instance creation (\ref{instanceCreation}).%
}

\LMHash{}%
If a generative constructor $c$ is not a redirecting constructor
and no body is provided, then $c$ implicitly has an empty body \code{\{\}}.


\paragraph{Redirecting Generative Constructors}
\LMLabel{redirectingGenerativeConstructors}

\LMHash{}%
A generative constructor may be
\IndexCustom{redirecting}{constructor!redirecting},
in which case its only action is to invoke another generative constructor.
A redirecting constructor has no body;
instead, it has a redirect clause that specifies
which constructor the invocation is redirected to,
and with which arguments.

\begin{grammar}
<redirection> ::= `:' \THIS{} (`.' <identifier>)? <arguments>
\end{grammar}

\def\ConstMetavar{\mbox{\CONST?}}

\LMHash{}%
\BlindDefineSymbol{C, X_j, B_j, m}%
Assume that
\code{$C$<$X_1\ \EXTENDS\ B_1 \ldots,\ X_m\ \EXTENDS\ B_m$>}
is the name and formal type parameters of the enclosing class,
\BlindDefineSymbol{\ConstMetavar}%
$\ConstMetavar$ stands for either \CONST{} or nothing,
$N$ is $C$ or $C.\id_0$ for some identifier $\id_0$,
\BlindDefineSymbol{N, \id}%
and \id{} is an identifier.
Consider a declaration of a redirecting generative constructor
of one of the forms

\noindent
\code{$\ConstMetavar$ $N$($T_1\ x_1 \ldots,\ T_n\ x_n,\ $[$T_{n+1}\ x_{n+1} = d_1 \ldots,\ T_{n+k}\ x_{n+k} = d_k$]):\ $R$;}

\noindent
\code{$\ConstMetavar$ $N$($T_1\ x_1 \ldots,\ T_n\ x_n,\ $\{$T_{n+1}\ x_{n+1} = d_1 \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}):\ $R$;}

\noindent
where $R$ is of one of the forms

\noindent
\code{$\THIS{}$($e_1 \ldots,\ e_p,\ x_1$:\ $e_{p+1}, \ldots,\ x_q$:\ $e_{p+q}$)}

\noindent
\code{$\THIS.\id$($e_1 \ldots,\ e_p,\ x_1$:\ $e_{p+1}, \ldots,\ x_q$:\ $e_{p+q}$)}.

\LMHash{}%
The
\IndexCustom{redirectee constructor}{constructor!redirectee}
for this declaration is then the constructor denoted by
\code{$C$<$X_1 \ldots,\ X_m$>} respectively \code{$C$<$X_1 \ldots,\ X_m$>.\id}.
It is a compile-time error if the static argument list type
(\ref{actualArgumentLists})
of \code{($e_1 \ldots,\ e_p,\ x_1$:\ $e_{p+1}, \ldots,\ x_q$:\ $e_{p+q}$)}
is not an assignable match for the formal parameter list of the redirectee.

\commentary{%
  Note that the case where no named parameters are passed
  is covered by letting $q$ be zero,
  and the case where $C$ is a non-generic class
  is covered by letting $m$ be zero,
  in which case the formal type parameter list and actual type argument lists
  are omitted
  (\ref{generics}).%
}

\rationale{%
  We require an assignable match rather than the stricter subtype match
  because a generative redirecting constructor $k$ invokes its redirectee $k'$
  in a manner which resembles function invocation in general.
  For instance, $k$ could accept an argument \code{x}
  and pass on an expression $e_j$ using \code{x} such as \code{x.f(42)} to $k'$,
  and it would be surprising
  if $e_j$ were subject to more strict constraints than the ones applied to
  actual arguments to function invocations in general.%
}

\LMHash{}%
A redirecting generative constructor $q'$ is \Index{redirection-reachable}
from a redirecting generative constructor $q$ if{}f
$q'$ is the redirectee constructor of $q$,
or $q''$ is the redirectee constructor of $q$
and $q'$ is redirection-reachable from $q''$.
It is a compile-time error if a redirecting generative constructor
is redirection-reachable from itself.

\LMHash{}%
When $\ConstMetavar$ is \CONST,
it is a compile-time error if the redirectee is not a constant constructor.
Moreover, when $\ConstMetavar$ is \CONST, each
$e_i,\ i \in 1 .. p+q$,
must be a potentially constant expression (\ref{constantConstructors}).

\LMHash{}%
% This error can occur due to a failed implicit cast.
It is a dynamic type error if an actual argument passed
in an invocation of a redirecting generative constructor $k$
is not a subtype of the actual type (\ref{actualTypes})
of the corresponding formal parameter in the declaration of $k$.
% This error can occur due to a failed implicit cast.
It is a dynamic type error if an actual argument passed
to the redirectee $k'$ of a redirecting generative constructor
is not a subtype of the actual type
(\ref{actualTypes})
of the corresponding formal parameter in the declaration of the redirectee.


\paragraph{Initializer Lists}
\LMLabel{initializerLists}

\LMHash{}%
An initializer list begins with a colon,
and consists of a comma-separated list of individual \Index{initializers}.

\commentary{%
  There are three kinds of initializers.

  \begin{itemize}
  \item[$\bullet$] A \emph{superinitializer} identifies a
    \emph{superconstructor}\,---\,that is,
    a specific constructor of the superclass.
    Execution of the superinitializer causes
    the initializer list of the superconstructor to be executed.
  \item[$\bullet$] An \emph{instance variable initializer}
    assigns an object to an individual instance variable.
  \item[$\bullet$] An assertion.
  \end{itemize}%
}

\begin{grammar}
<initializers> ::= `:' <initializerListEntry> (`,' <initializerListEntry>)*

<initializerListEntry> ::= \SUPER{} <arguments>
  \alt \SUPER{} `.' <identifier> <arguments>
  \alt <fieldInitializer>
  \alt <assertion>

<fieldInitializer> ::= \gnewline{}
  (\THIS{} `.')? <identifier> `=' <initializerExpression>

<initializerExpression> ::= \gnewline{}
  <assignableExpression> <assignmentOperator> <expression>
  \alt <conditionalExpression>
  \alt <cascade>
  \alt <throwExpression>
\end{grammar}

%% TODO(eernst): When #54262 is resolved, delete the next paragraph.
%% If <expression> is changed such that it derives <functionExpression>,
%% the following error will simply be a property of the grammar rule
%% because <initializerExpression> will _not_ derive <functionExpression>.
\LMHash{}%
As a special disambiguation rule,
an \synt{initializerExpression} can not derive a \synt{functionExpression}.

\rationale{%
  This resolves a near-ambiguity:
  In \code{A()\,:\,\,x\,\,=\,\,()\,\,\{\,\ldots\,\}},
  \code{x} could be initialized to the empty record,
  and the block could be the body of the constructor.
  Alternatively, \code{x} could be initialized to a function object,
  and the constructor would then not have a body.
  It would only be known which case we have when we encounter
  (or do not encounter)
  a semicolon at the very end.
  That was considered unreadable.
  Hence, parsers can commit to not parsing a function expression
  in this situation.
  Note that it is still possible for \synt{initializerExpression} to derive
  a term that contains a function expression as a subterm, e.g.,
  \code{A()\,:\,\,x\,\,=\,\,(()\,\,\{\,\ldots\,\});}.%
}

\LMHash{}%
An initializer of the form \code{$v$ = $e$} is equivalent to
an initializer of the form \code{\THIS.$v$ = $e$},
and both forms are called \Index{instance variable initializers}.
It is a compile-time error if the enclosing class
does not declare an instance variable named $v$.
It is a compile-time error unless the static type of $e$
is assignable to the declared type of $v$.

\LMHash{}%
Consider a \Index{superinitializer} $s$ of the form

\noindent
\code{\SUPER($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}
respectively

\noindent
\code{\SUPER.\id($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}.

\noindent{}%
Let $S$ be the superclass of the enclosing class of $s$.
It is a compile-time error if class $S$ does not declare
a generative constructor named $S$ (respectively \code{$S$.\id}).
Otherwise, the static analysis of $s$ is performed
as specified in Section~\ref{bindingActualsToFormals},
as if \code{\SUPER} respectively \code{\SUPER.\id}
had had the function type of the denoted constructor,
%% TODO(eernst): The following is very imprecise, it just serves to remember
%% that we must specify how to deal with the type variables in that parameter
%%  part. One thing that we weasel over is that the superclass may be a mixin
%% application.
and substituting the formal type variables of the superclass
for the corresponding actual type arguments passed to the superclass
in the header of the current class.

\LMHash{}%
Let \DefineSymbol{k} be a generative constructor.
Then $k$ may include at most one superinitializer in its initializer list
or a compile-time error occurs.
If no superinitializer is provided,
an implicit superinitializer of the form \SUPER{}() is added
at the end of $k$'s initializer list,
unless the enclosing class is class \code{Object}.
It is a compile-time error if a superinitializer appears
in $k$'s initializer list at any other position than at the end.
It is a compile-time error if more than one initializer corresponding
to a given instance variable appears in $k$'s initializer list.
It is a compile-time error if $k$'s initializer list contains
an initializer for a variable that is initialized by means of
an initializing formal of $k$.
It is a compile-time error if $k$'s initializer list contains
an initializer for a final variable $f$ whose declaration includes
an initialization expression.
It is a compile-time error if $k$ includes an initializing formal
for a final variable $f$ whose declaration includes
an initialization expression.

\LMHash{}%
Let \DefineSymbol{f} be a final instance variable declared in
the immediately enclosing class or enum.
A compile-time error occurs unless $f$ is initialized
by one of the following means:

\begin{itemize}
\item $f$ is declared by an initializing variable declaration.
\item $f$ is initialized by means of an initializing formal of $k$.
\item $f$ has an initializer in $k$'s initializer list.
\end{itemize}

\LMHash{}%
It is a compile-time error if $k$'s initializer list contains
an initializer for a variable that is not
an instance variable declared in the immediately surrounding class.

\commentary{%
  The initializer list may of course contain an initializer for
  any instance variable declared by the immediately surrounding class,
  even if it is not final.%
}

\LMHash{}%
It is a compile-time error if a generative constructor of class \code{Object}
includes a superinitializer.


\paragraph{Execution of Generative Constructors}
\LMLabel{executionOfGenerativeConstructors}

\LMHash{}%
\BlindDefineSymbol{k, T, i}%
Execution of a generative constructor $k$ of type $T$
to initialize a fresh instance $i$
is always done with respect to a set of bindings for its formal parameters
and the type parameters of the immediately enclosing class or enum bound to
a set of actual type arguments of $T$, \DefineSymbol{\List{t}{1}{m}}.

\commentary{%
  These bindings are usually determined by the instance creation expression
  that invoked the constructor (directly or indirectly).
  However, they may also be determined by a reflective call.%
}

\LMHash{}%
If $k$ is redirecting then its redirect clause has the form

\noindent
\code{\THIS.$g$($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}

where \DefineSymbol{g} identifies another generative constructor
of the immediately surrounding class.
Then execution of $k$ to initialize $i$ proceeds by
evaluating the argument list
\code{($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}
to an actual argument list $a$ of the form
\code{($o_1, \ldots,\ o_n,\ x_{n+1}$:\ $o_{n+1}, \ldots,\ x_{n+k}$:\ $o_{n+k}$)}
in an environment where the
type parameters of the enclosing class are bound to
$t_1, \ldots, t_m$.

\LMHash{}%
Next, the body of $g$ is executed to initialize $i$
with respect to the bindings that map
the formal parameters of $g$ to the corresponding objects
in the actual argument list $a$,
with \THIS{} bound to $i$,
and the type parameters of the immediately enclosing class or enum bound to
\List{t}{1}{m}.

\LMHash{}%
Otherwise, $k$ is not redirecting.
Execution then proceeds as follows:

\LMHash{}%
The instance variable declarations of the immediately enclosing class or enum
are visited in the order they appear in the program text.
For each such declaration $d$, if $d$ has the form
\code{\synt{finalConstVarOrType} $v$ = $e$; }
then $e$ is evaluated to an object $o$
and the instance variable $v$ of $i$ is bound to $o$.

\LMHash{}%
Any initializing formals declared in $k$'s parameter list
are executed in the order they appear in the program text.
% In fact, this order is unobservable; this could be done any time
% prior to running the body, since these only effect \THIS.
Then, the initializers of $k$'s initializer list are executed to initialize $i$
in the order they appear in the program, as described below
(p.\,\pageref{executionOfInitializerLists}).

\rationale{%
  We could observe the order by side effecting external routines called.
  So we need to specify the order.%
}

\LMHash{}%
Then if any instance variable of $i$ declared
by the immediately enclosing class or enum
is not yet bound to an object,
all such variables are initialized with the null object (\ref{null}).

\LMHash{}%
Then, unless the enclosing class is \code{Object}, the explicitly specified or
implicitly added superinitializer (\ref{initializerLists}) is executed to
further initialize $i$.

\LMHash{}%
After the superinitializer has completed, the body of $k$ is executed
in a scope where \THIS{} is bound to $i$.

\rationale{%
  This process ensures that no uninitialized final instance variable
  is ever seen by code.
  Note that \THIS{} is not in scope on the right hand side of an initializer
  (see \ref{this})
  so no instance method can execute during initialization:
  an instance method cannot be directly invoked,
  nor can \THIS{} be passed into any other code being invoked
  in the initializer.%
}


\paragraph{Execution of Initializer Lists}
\LMLabel{executionOfInitializerLists}

\LMHash{}%
During the execution of a generative constructor to initialize an instance
\DefineSymbol{i},
execution of an initializer of the form \code{\THIS.$v$ = $e$}
proceeds as follows:

\LMHash{}%
First, the expression $e$ is evaluated to an object $o$.
Then, the instance variable $v$ of $i$ is bound to $o$.
% This error can occur due to an implicit cast.
It is a dynamic type error if the dynamic type of $o$ is not
a subtype of the actual type
(\ref{actualTypes})
of the instance variable $v$.

\LMHash{}%
Execution of an initializer that is an assertion proceeds by
executing the assertion (\ref{assert}).

\LMHash{}%
Consider a superinitializer \DefineSymbol{s} of the form

\noindent
\code{\SUPER($a_1, \ldots,\ a_n,\ x_{n+1}:\ a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}
respectively

\noindent
\code{\SUPER.\id($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}.

\LMHash{}%
\BlindDefineSymbol{C, S, u_j, p}%
Let $C$ be the class in which $s$ appears and let $S$ be the superclass of $C$.
If $S$ is generic (\ref{generics}),
let $u_1, \ldots, u_p$ be the actual type arguments passed to $S$,
obtained by substituting the actual bindings \List{t}{1}{m}
of the formal type parameters of $C$
in the superclass as specified in the header of $C$.
Let \DefineSymbol{k} be the constructor declared in $S$ and named
$S$ respectively \code{$S$.\id}.

\LMHash{}%
Execution of $s$ proceeds as follows:
The argument list
\code{($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
is evaluated to an actual argument list $a$ of the form
\code{($o_1, \ldots,\ o_n,\ x_{n+1}$: $o_{n+1}, \ldots,\ x_{n+k}$: $o_{n+k}$)}.
Then the body of the superconstructor $k$ is executed
in an environment where the formal parameters of $k$ are bound to
the corresponding actual arguments from $a$,
and the formal type parameters of $S$ are bound to $u_1, \ldots, u_p$.


\subsubsection{Factories}
\LMLabel{factories}

\LMHash{}%
A \IndexCustom{factory}{constructor!factory}
is a constructor prefaced by the built-in identifier
(\ref{identifierReference})
\FACTORY.

\begin{grammar}
<factoryConstructorSignature> ::= \gnewline{}
  \CONST? \FACTORY{} <constructorName> <formalParameterList>
\end{grammar}

\LMHash{}%
The return type of a factory whose signature is of
the form \FACTORY{} $M$ or
the form \FACTORY{} \code{$M$.\id}
is $M$ if $M$ is not a generic type;
otherwise the return type is
\code{$M$<$T_1, \ldots,\ T_n$>}
where $T_1, \ldots, T_n$ are the type parameters of the enclosing class.

\LMHash{}%
It is a compile-time error if $M$ is not the name of
%% TODO(eernst): Come Dart 3.0, add 'mixin'.
the immediately enclosing class or enum.

\LMHash{}%
% This error can occur due to an implicit cast.
It is a dynamic type error if a factory returns a non-null object
whose type is not a subtype of its actual
(\ref{actualTypes})
return type.

\rationale{%
  It seems useless to allow a factory to return the null object (\ref{null}).
  But it is more uniform to allow it, as the rules currently do.%
}

\rationale{%
  Factories address classic weaknesses associated with constructors
  in other languages.
  Factories can produce instances that are not freshly allocated:
  they can come from a cache.
  Likewise, factories can return instances of different classes.%
}


\paragraph{Redirecting Factory Constructors}
\LMLabel{redirectingFactoryConstructors}

\LMHash{}%
A \IndexCustom{redirecting factory constructor}{constructor!redirecting factory}
specifies a call to a constructor of another class that is to be used
whenever the redirecting constructor is called.

\begin{grammar}
<redirectingFactoryConstructorSignature> ::= \gnewline{}
  \CONST? \FACTORY{} <constructorName> <formalParameterList> `=' \gnewline{}
  <constructorDesignation>

<constructorDesignation> ::= <typeIdentifier>
  \alt <qualifiedName>
  \alt <typeName> <typeArguments> (`.' <identifier>)?
\end{grammar}

Assume that
\BlindDefineSymbol{C, X_j, B_j, m}%
\code{$C$<$X_1\ \EXTENDS\ B_1 \ldots,\ X_m\ \EXTENDS\ B_m$>}
is the name and formal type parameters of the enclosing class,
\BlindDefineSymbol{\ConstMetavar, N}%
$\ConstMetavar$ is \CONST{} or empty,
$N$ is $C$ or $C.\id_0$ for some identifier $\id_0$,
and \DefineSymbol{\id} is an identifier,
then consider a declaration of a redirecting factory constructor
\DefineSymbol{k} of one of the forms

\begin{normativeDartCode}
$\ConstMetavar$ \FACTORY{}
    $N$($T_1\ x_1 \ldots,\ T_n\ x_n,\ $[$T_{n+1}\ x_{n+1}$=$d_1, \ldots,\ T_{n+k}\ x_{n+k}$=$d_k$]) = $R$;
\\
$\ConstMetavar$ \FACTORY{}
    $N$($T_1\ x_1 \ldots,\ T_n\ x_n,\ $\{$T_{n+1}\ x_{n+1}$=$d_1, \ldots,\ T_{n+k}\ x_{n+k}$=$d_k$\}) = $R$;
\end{normativeDartCode}

\noindent
\BlindDefineSymbol{R, T}%
where $R$ is of one of the forms
\code{$T$<$S_1 \ldots,\ S_p$>} or
\code{$T$<$S_1 \ldots,\ S_p$>.\id}.

\LMHash{}%
It is a compile-time error if $T$ does not denote
a class accessible in the current scope.
If $T$ does denote such a class $D$,
it is a compile-time error if $R$ does not denote a constructor.
% It is by induction sufficient to check for abstractness one level down,
% because it is an error on the redirectee if this occurs after multiple
% redirections:
Otherwise, it is a compile-time error
if $R$ denotes a generative constructor and $D$ is abstract.
Otherwise, the
\IndexCustom{redirectee constructor}{constructor!redirectee}
for this declaration is the constructor \DefineSymbol{k'} denoted by $R$.

\LMHash{}%
A redirecting factory constructor $q'$ is \Index{redirection-reachable}
from a redirecting factory constructor $q$ if{}f
$q'$ is the redirectee constructor of $q$,
or $q''$ is the redirectee constructor of $q$
and $q'$ is redirection-reachable from $q''$.
It is a compile-time error if a redirecting factory constructor
is redirection-reachable from itself.

\LMHash{}%
Let $\argumentList{T}$ be the static argument list type
(\ref{actualArgumentLists})
\code{($T_1 \ldots,\ T_{n+k}$)}
when $k$ takes no named arguments, and
\code{($T_1 \ldots,\ T_n,\ T_{n+1}\ x_{n+1},\ \ldots,\ T_{n+k}\ x_{n+k}$)}
when $k$ takes some named arguments.
It is a compile-time error if $\argumentList{T}$
is not a subtype match for the formal parameter list of the redirectee.

\rationale{%
  We require a subtype match
  (rather than the more forgiving assignable match
  which is used with a generative redirecting constructor),
  because a factory redirecting constructor $k$ always invokes
  its redirectee $k'$ with
  exactly the same actual arguments that $k$ received.
  This means that a downcast on an actual argument
  ``between'' $k$ and $k'$
  would either be unused because the actual argument has
  the type required by $k'$,
  or it would amount to a dynamic error which is simply delayed a single step.%
}

\commentary{%
  Note that the non-generic case is covered by
  letting $m$ or $p$ or both be zero,
  in which case the formal type parameter list of the class $C$
  and/or the actual type argument list of
  the redirectee constructor is omitted
  (\ref{generics}).%
}

\LMHash{}%
It is a compile-time error if $k$ explicitly specifies
a default value for an optional parameter.

\rationale{%
  Default values specified in $k$ would be ignored,
  since it is the \emph{actual} parameters that are passed to $k'$.
  Hence, default values are disallowed.%
}

\LMHash{}%
It is a compile-time error if a formal parameter of $k'$ has a default value
whose type is not a subtype of the type annotation
on the corresponding formal parameter in $k$.

\commentary{%
  Note that it is not possible to modify the arguments being passed to $k'$.%
}

\rationale{%
  At first glance, one might think that
  ordinary factory constructors could simply create
  instances of other classes and return them,
  and that redirecting factories are unnecessary.
  However, redirecting factories have several advantages:

  \begin{itemize}
  \item
    An abstract class may provide a constant constructor
    that utilizes the constant constructor of another class.
  \item
    A redirecting factory constructor avoids the need for forwarders
    to repeat the formal parameters and their default values.
  \end{itemize}%
}

\LMHash{}%
It is a compile-time error if $k$ is prefixed with the \CONST{} modifier
but $k'$ is not a constant constructor (\ref{constantConstructors}).

\LMHash{}%
Let \DefineSymbol{\List{T}{1}{m}} be the actual type arguments passed to $k'$
in the declaration of $k$.
Let \DefineSymbol{\List{X}{1}{m}} be the formal type parameters declared by
the class that contains the declaration of $k'$.
Let \DefineSymbol{F'} be the function type of $k'$ (\ref{constructors}).
It is a compile-time error if $[T_1/X_1, \ldots, T_m/X_m]F'$
is not a subtype of the function type of $k$.

\commentary{%
  In the case where the two classes are non-generic
  this is just a subtype check on the function types of the two constructors.
  In general, this implies that the resulting object conforms to
  %% TODO(eernst): Come Dart 3.0, add 'mixin'.
  the interface of the class or enum that immediately encloses $k$.%
}

\LMHash{}%
For the dynamic semantics,
assume that \DefineSymbol{k} is a redirecting factory constructor
and \DefineSymbol{k'} is the redirectee of $k$.

\LMHash{}%
% This error can occur due to an implicit cast.
It is a dynamic type error if an actual argument passed in an invocation of $k$
is not a subtype of the actual type (\ref{actualTypes})
of the corresponding formal parameter in the declaration of $k$.

\LMHash{}%
When the redirectee $k'$ is a factory constructor,
execution of $k$ amounts to execution of $k'$
with the actual arguments passed to $k$.
The result of the execution of $k'$ is the result of $k$.

\LMHash{}%
When the redirectee $k'$ is a generative constructor,
let $o$ be a fresh instance (\ref{generativeConstructors})
of the class that contains $k'$.
Execution of $k$ then amounts to execution of $k'$ to initialize $o$,
governed by the same rules as an instance creation expression
(\ref{instanceCreation}).
If $k'$ completed normally then the execution of $k$
completes normally returning $o$,
otherwise $k$ completes by throwing the exception and stack trace
thrown by $k'$.


\subsubsection{Constant Constructors}
\LMLabel{constantConstructors}

\LMHash{}%
A \IndexCustom{constant constructor}{constructor!constant}
may be used to create compile-time constant (\ref{constants}) objects.
A constant constructor is prefixed by the reserved word \CONST.

\begin{grammar}
<constantConstructorSignature> ::= \gnewline{}
  \CONST{} <constructorName> <formalParameterList>
\end{grammar}

\commentary{%
  Constant constructors have stronger constraints than other constructors.
  For instance, all the work of
  a non-redirecting generative constant constructor
  must be done in its initializers
  and in the initializing expressions of
  the instance variables of the enclosing class
  (and the latter may already have happened earlier,
  because those initializing expressions must be constant).%
}

\LMHash{}%
Constant redirecting generative and factory constructors are specified elsewhere
(p.\,\pageref{redirectingGenerativeConstructors},
p.\,\pageref{redirectingFactoryConstructors}).
This section is henceforth concerned with
non-redirecting generative constant constructors.

\LMHash{}%
It is a compile-time error if a non-redirecting generative constant constructor
is declared by a class that has a instance variable which is not final.

\commentary{%
  The above refers to both locally declared and inherited instance variables.%
}

\LMHash{}%
If a non-redirecting generative constant constructor \DefineSymbol{k}
is declared by a class $C$,
it is a compile-time error
for an instance variable declared in $C$
to have an initializing expression that is not a constant expression.

\commentary{%
  A superclass of $C$ cannot have such an initializing expression $e$ either.
  If it has a non-redirecting generative constant constructor
  then $e$ is an error,
  and if it does not have such a constructor
  then the (implicit or explicit) superinitializer in $k$ is an error.%
}

\LMHash{}%
The superinitializer that appears, explicitly or implicitly,
in the initializer list of a constant constructor
must specify a generative constant constructor of
the superclass of the immediately enclosing class,
or a compile-time error occurs.

\LMHash{}%
Any expression that appears within
the initializer list of a constant constructor
must be a potentially constant expression
(\ref{constants}),
or a compile-time error occurs.

\LMHash{}%
When a constant constructor \DefineSymbol{k} is invoked from
a constant object expression,
it is a compile-time error if
the invocation of $k$ at run time would throw an exception,
and it is a compile-time error if
substitution of the actual arguments for the formal parameters
yields an initializing expression $e$ in the initializer list of $k$
which is not a constant expression.

\commentary{%
  For instance, if $e$ is \code{a.length}
  where \code{a} is a formal argument of $k$ with type \DYNAMIC,
  $e$ is potentially constant and can be used in the initializer list of $k$.
  It is an error to invoke $k$ with an argument of type \code{C}
  if \code{C} is a class different from \code{String},
  even if \code{C} has a \code{length} getter,
  and that same expression would evaluate without errors at run time.%
}


\subsection{Static Methods}
\LMLabel{staticMethods}

\LMHash{}%
\IndexCustom{Static methods}{method!static}
are functions, other than getters or setters,
whose declarations are immediately contained within a class declaration
and that are declared \STATIC.
The static methods of a class $C$ are those static methods declared by $C$.

\rationale{%
  Inheritance of static methods has little utility in Dart.
  Static methods cannot be overridden.
  Any required static method can be obtained from its declaring library,
  and there is no need to bring it into scope via inheritance.
  Experience shows that developers are confused by
  the idea of inherited methods that are not instance methods.

  Of course, the entire notion of static methods is debatable,
  but it is retained here because so many programmers are familiar with it.
  Dart static methods may be seen as functions of the enclosing library.%
}

\commentary{%
  Static method declarations may conflict with other declarations
  (\ref{classMemberConflicts}).%
}


\subsection{Superclasses}
\LMLabel{superclasses}

%% TODO(eernst): We need to say that the superclass which is obtained
%% by mixin application is generic when $C$ is generic, or at least
%% when one or more of $C$'s type variables are used by the classes
%% in the \EXTENDS{} or \WITH{} clause of $C$. It says below that
%% these clauses are in the type parameter scope of $C$, but that does
%% not allow us to talk about the superclass as an actual, stand-alone
%% class (unless we start defining nested classes, such that the
%% superclass can be declared in that scope).

\LMHash{}%
The superclass $S'$ of a class $C$ whose declaration has a with clause
\code{\WITH{} $M_1, \ldots,\ M_k$}
and an extends clause
\code{\EXTENDS{} $S$}
is the abstract class obtained by application of
mixin composition (\ref{mixins}) $M_k* \cdots * M_1$ to $S$.
The name $S'$ is a fresh identifier.
If no \WITH{} clause is specified then the \EXTENDS{} clause of
a class $C$ specifies its superclass.
If no \EXTENDS{} clause is specified, then either:

\begin{itemize}
\item $C$ is \code{Object}, which has no superclass. OR
\item Class $C$ is deemed to have an \EXTENDS{} clause of the form
  \code{\EXTENDS{} Object}, and the rules above apply.
\end{itemize}

\LMHash{}%
It is a compile-time error to specify an \EXTENDS{} clause
for class \code{Object}.

\begin{grammar}
<superclass> ::= \EXTENDS{} <typeNotVoid> <mixins>?
    \alt <mixins>

<mixins> ::= \WITH{} <typeNotVoidList>
\end{grammar}

\LMHash{}%
The scope of the \EXTENDS{} and \WITH{} clauses of a class $C$ is
the type-parameter scope of $C$.

\LMHash{}%
It is a compile-time error if the type
in the \EXTENDS{} clause of a class $C$ is
a type variable (\ref{generics}),
a type alias that does not denote a class (\ref{typedef}),
an enumerated type (\ref{enums}),
a deferred type (\ref{staticTypes}), type \DYNAMIC{} (\ref{typeDynamic}),
or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).

\commentary{%
  Note that \VOID{} is a reserved word,
  which implies that the same restrictions apply for the type \VOID,
  and similar restrictions are specified for other types like
  \code{Null} (\ref{null}) and
  \code{String} (\ref{strings}).%
}

\commentary{%
  The type parameters of a generic class are available in
  the lexical scope of the superclass clause,
  potentially shadowing classes in the surrounding scope.
  The following code is therefore illegal
  and should cause a compile-time error:%
}

\begin{dartCode}
class T \{\}
\\
/* Compilation error: Attempt to subclass a type parameter */
class G<T> extends T \{\}
\end{dartCode}

\LMHash{}%
%% TODO(eernst): Consider replacing all occurrences of `a superclass`
%% by `a direct or indirect superclass`, because it's too confusing.
A class $S$ is a \Index{superclass} of a class $C$ if{}f either:

\begin{itemize}
\item $S$ is the superclass of $C$, or
\item $S$ is a superclass of a class $S'$,
  and $S'$ is the superclass of $C$.
\end{itemize}

\LMHash{}%
It is a compile-time error if a class $C$ is a superclass of itself.


\subsubsection{Inheritance and Overriding}
\LMLabel{inheritanceAndOverriding}

\LMHash{}%
Let $C$ be a class, let $A$ be a superclass of $C$, and
let $S_1, \ldots, S_k$ be superclasses of $C$ that are also subclasses of $A$.
$C$ \Index{inherits} all concrete, accessible instance members of $A$
that have not been overridden by a concrete declaration in $C$
or in at least one of $S_1, \ldots, S_k$.

\rationale{%
  It would be more attractive to give a purely local definition of inheritance,
  that depended only on the members of the direct superclass $S$.
  However, a class $C$ can inherit a member $m$ that
  is not a member of its superclass $S$.
  This can occur when the member $m$ is private to the library $L_1$ of $C$,
  whereas $S$ comes from a different library $L_2$,
  but the superclass chain of $S$ includes a class declared in $L_1$.%
}

\LMHash{}%
A class may override instance members
that would otherwise have been inherited from its superclass.

\LMHash{}%
Let $C = S_0$ be a class declared in library $L$, and
let $\{S_1, \ldots, S_k\}$ be the set of all superclasses of $C$,
where $S_i$ is the superclass of $S_{i-1}$ for $i \in 1 .. k$.
\commentary{$S_k$ is the built-in class \code{Object}.}
Let $C$ declare a concrete member $m$, and
let $m'$ be a concrete member of $S_j, j \in 1 .. k$, that has
the same name as $m$,
such that $m'$ is accessible to $L$.
Then $m$ overrides $m'$
if $m'$ is not already overridden by a concrete member of
at least one of $S_1, \ldots, S_{j-1}$
and neither $m$ nor $m'$ are instance variables.

\commentary{%
  Instance variables never override each other.
  The getters and setters induced by instance variables do.%
}

\rationale{%
  Again, a local definition of overriding would be preferable,
  but fails to account for library privacy.%
}

\commentary{%
  Whether an override is legal or not is specified relative to
  all direct superinterfaces, not just the interface of the superclass,
  and that is described elsewhere
  (\ref{instanceMethods}).
  Static members never override anything,
  but they may participate in some conflicts
  involving declarations in superinterfaces
  (\ref{classMemberConflicts}).%
}

\commentary{%
  For convenience, here is a summary of the relevant rules,
  using `error' to denote compile-time errors.
  Remember that this is not normative.
  The controlling language is in the relevant sections of the specification.

  \begin{enumerate}
  \item There is only one namespace
    for getters, setters, methods and constructors (\ref{scoping}).
    A non-local variable $f$ introduces a getter $f$,
    and a non-local variable $f$
    also introduces a setter
    if it is not final and not constant,
    or it is late and final and has no initializing expression
    \code{$f$=} (\ref{instanceVariables}, \ref{variables}).
    When we speak of members here, we mean
    accessible instance, static, or library variables,
    getters, setters, and methods
    (\ref{classes}).
  \item You cannot have two members with the same name in the same class---be
    they declared or inherited (\ref{scoping}, \ref{classes}).
  \item Static members are never inherited.
  \item It is an error if you have a static member named $m$ in your class
    and an instance member of the same basename
    (\ref{classMemberConflicts}).
  \item It is an error if you have a static setter \code{$v$=},
    and an instance member $v$ (\ref{setters}).
  \item It is an error if you have a static getter $v$
    and an instance setter \code{$v$=} (\ref{getters}).
  \item If you define an instance member named $m$,
    and your superclass has an instance member of the same name,
    they override each other.
    This may or may not be legal.
  \item \label{typeSigAssignable}
    If two members override each other,
    it is an error unless it is a correct override
    (\ref{correctMemberOverrides}).
  \item Setters, getters and operators never have
    optional parameters of any kind;
    it's an error (\ref{operators}, \ref{getters}, \ref{setters}).
  \item
    It is an error if a member has the same name as its enclosing class
    (\ref{classes}).
  \item A class has an implicit interface (\ref{classes}).
  \item Superinterface members are not inherited by a class,
    but are inherited by its implicit interface.
    Interfaces have their own inheritance rules
    (\ref{interfaceInheritanceAndOverriding}).
  \item A member is abstract if
    it has no body and is not labeled \EXTERNAL{}
    (\ref{abstractInstanceMembers}, \ref{externalFunctions}).
  \item A class is abstract if{}f it is explicitly labeled \ABSTRACT.
  \item It is an error if a concrete class does not implement some member
    of its interface, and there is no non-trivial \code{noSuchMethod}
    (\ref{classes}).
  \item It is an error to call a non-factory constructor of an abstract class
    using an instance creation expression (\ref{instanceCreation}),
    such a constructor may only be invoked from another constructor
    using a superinvocation (\ref{superInvocations}).
  \item If a class defines an instance member named $m$,
    and any of its superinterfaces have a member signature named $m$,
    the interface of the class contains the $m$ from the class itself.
  \item An interface inherits all members of its superinterfaces
    that are not overridden and not members of multiple superinterfaces.
  \item If multiple superinterfaces of an interface
    define a member with the same name as $m$,
    then at most one member is inherited.
    That member (if it exists) is the one whose type is a subtype
    of all the others.
    If there is no such member, an error occurs
    (\ref{interfaceInheritanceAndOverriding}).
  \item Rule \ref{typeSigAssignable} applies to interfaces as well as classes
    (\ref{interfaceInheritanceAndOverriding}).
  \item It is an error if a concrete class does not have an implementation
    for a method in its interface
    unless it has a non-trivial \code{noSuchMethod}
    (\ref{theMethodNoSuchMethod}).
  \item The identifier of a named constructor cannot be the same as
    the basename of a static member declared in the same class
    (\ref{classMemberConflicts}).
  \end{enumerate}%
}


\subsection{Superinterfaces}
\LMLabel{superinterfaces}

\LMHash{}%
A class has a set of \Index{direct superinterfaces}.
This set contains the interface of its superclass
and the interfaces of the classes specified in
the \IMPLEMENTS{} clause of the class.

\begin{grammar}
<interfaces> ::= \IMPLEMENTS{} <typeNotVoidList>
\end{grammar}

\LMHash{}%
The scope of the \IMPLEMENTS{} clause of a class $C$ is
the type-parameter scope of $C$.

\LMHash{}%
It is a compile-time error if an element
in the type list of the \IMPLEMENTS{} clause of a class $C$ is
a type variable (\ref{generics}),
a type alias that does not denote a class (\ref{typedef}),
an enumerated type (\ref{enums}),
a deferred type (\ref{staticTypes}), type \DYNAMIC{} (\ref{typeDynamic}),
or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
It is a compile-time error if two elements in the type list of
%% TODO(eernst): Refer to nnbd notion of 'same type'.
the \IMPLEMENTS{} clause of a class $C$ specifies the same type $T$.
It is a compile-time error if the superclass of a class $C$ is
one of the elements of the type list of the \IMPLEMENTS{} clause of $C$.

\rationale{%
  One might argue that it is harmless
  to repeat a type in the superinterface list,
  so why make it an error?
  The issue is not so much that the situation is erroneous,
  but that it is pointless.
  As such, it is an indication that the programmer may very well have meant
  to say something else---and that is a mistake that should be
  called to her or his attention.%
}

\LMHash{}%
It is a compile-time error if a class $C$ has two superinterfaces
that are different instantiations of the same generic class.
\commentary{%
  For example, a class can not have
  both \code{List<\VOID>} and \code{List<\DYNAMIC>} as superinterfaces,
  directly or indirectly.%
}

\LMHash{}%
When a generic class $C$ declares a type parameter $X$,
it is a compile-time error if $X$ occurs in a non-covariant position
% Could say `a direct superinterface', but it is easy to see that it is
% enough to check direct superinterfaces, and it is then true
% for indirect ones as well.
in a type which specifies a superinterface of $C$.
\commentary{%
  For example, the class can not have
  \code{List<\VOID{} \FUNCTION($X$)>}
  in its \EXTENDS{} or \IMPLEMENTS{} clause.%
}

\LMHash{}%
It is a compile-time error if the interface of a class $C$ is
a superinterface of itself.

\commentary{%
  A class does not inherit members from its superinterfaces.
  However, its implicit interface does.%
}


\subsection{Class Member Conflicts}
\LMLabel{classMemberConflicts}

\LMHash{}%
Some pairs of class, mixin, enum, and extension member declarations
cannot coexist,
even though they do not both introduce the same name into the same scope.
This section specifies these errors.

\LMHash{}%
The \Index{basename} of a getter or method named $n$ is $n$;
the basename of a setter named \code{$n$=} is $n$.
The basename of an operator named $n$ is $n$,
except for operator \code{[]=} whose basename is \code{[]}.

\LMHash{}%
Let \DefineSymbol{C} be a class.
It is a compile-time error if $C$
declares a constructor named \code{$C$.$n$} and
a static member with basename $n$.
It is a compile-time error if $C$
declares a static member with basename $n$ and
the interface of $C$ has an instance member with basename $n$.
It is a compile-time error if the interface of $C$
has an instance method named $n$ and an instance setter with basename $n$.
It is a compile-time error if $C$ declares a static method named $n$
and a static setter with basename $n$.

\LMHash{}%
When \DefineSymbol{C} is a mixin or an extension,
the compile-time errors occur according to the same rules.
\commentary{%
  This is redundant in some cases.
  For instance, it is already an error for a mixin to declare a constructor.
  But useful cases exist as well, e.g., a conflict between a static member
  and an instance member.%
}

\LMHash{}%
These errors occur when the getters or setters are defined explicitly
as well as when they are induced by variable declarations.

\commentary{%
  Note that other errors which are similar in nature are covered elsewhere.
  For instance, if $C$ is a class that has two superinterfaces $I_1$ and $I_2$,
  where $I_1$ has a method named $m$
  and $I_2$ has a getter named $m$,
  then it is an error because the computation of the interface of $C$
  includes a computation of the combined member signature
  (\ref{combinedMemberSignatures})
  of that getter and that method,
  and it is an error for a combined member signature
  to include a getter and a non-getter.%
}


\section{Interfaces}
\LMLabel{interfaces}

\LMHash{}%
This section introduces the notion of interfaces.
We define the notion of member signatures first,
because that concept is needed in the definition of interfaces.

% We need a separate concept of instance member signatures,
% such that we can obtain a clean treatment of how to compute
% the interface of a class and the common interface of a set
% of superinterfaces, e.g., the superinterfaces of a class or
% the common interface represented by an `on` clause in a
% `mixin`. For instance, we do not want to specify each time
% we check for conflicts that the body doesn't matter, or
% that the metadata doesn't matter, the interface of a class
% should simply never contain a body of any member in the
% first place. Also the clear separation of a syntactic
% declaration and a member signature provides a well-defined
% occasion to introduce transformations, e.g., to replace
% some parameter types by others, which is needed for the
% specification of a correct override relation.

\LMHash{}%
A \Index{member signature} $s$
can be derived from a class instance member declaration $D$.
It contains the same information as $D$,
except that $s$ omits the body, if any;
it contains the return type and parameter types
even if they are implicit in $D$;
it omits the names of positional parameters;
it omits the modifier \FINAL{} from each parameter, if any;
it omits metadata
(\ref{metadata});
and it omits information about whether the member is
\EXTERNAL, \ASYNC, \ASYNC*, or \SYNC*.
It makes no difference whether $D$ is given as explicit syntax
or it is induced implicitly, e.g., by a variable declaration.
Finally, if $s$ has formal parameters,
each of them has the modifier \COVARIANT{}
(\ref{requiredFormals})
if and only if that parameter is covariant-by-declaration
(\ref{covariantParameters}).

\LMHash{}%
We use a syntax similar to that of an abstract member declaration
to specify member signatures.
The difference is that the names of positional parameters are omitted.
This syntax is only used for the purposes of specification.

\rationale{%
  Member signatures are synthetic entities, that is,
  they are not supported as concrete syntax in a Dart program,
  they are computed entities used during static analysis.
  However, it is useful to be able to indicate the
  properties of a member signature in this specification
  via a syntactic representation.
  A member signature makes it explicit
  whether a parameter is covariant-by-declaration,
  but it remains implicit whether it is covariant-by-class
  (\ref{covariantParameters}).
  The reason for this is that the rule for determining whether
  a given override relation is correct
  (\ref{correctMemberOverrides})
  depends on the former and not on the latter.%
}

\LMHash{}%
Let \DefineSymbol{m} be a method signature of the form

\noindent
\code{$T_0$ \id<\TypeParametersStd>(}

\noindent
\code{\qquad\qquad\List{\COVARIANT?\ T}{1}{n},}

\noindent
\code{\qquad\qquad[\PairList{\COVARIANT?\ T}{= d}{n+1}{n+k}])}.

\noindent
The \IndexCustom{function type of}{method signature!function type}
$m$ is then

\noindent
\FunctionTypePositionalStd{T_0}.

\LMHash{}%
Let \DefineSymbol{m} be a method signature of the form

\noindent
\code{$T_0$ \id<\TypeParametersStd>(}

\noindent
\code{\qquad\qquad\List{\COVARIANT?\ T}{1}{n},}

\noindent
\code{\qquad\qquad\{\TripleList{\COVARIANT?\ T}{x}{= d}{n+1}{n+k}\})}.

\noindent
The \NoIndex{function type of} $m$ is then

\noindent
\FunctionTypeNamedStd{T_0}.

\LMHash{}%
Let \DefineSymbol{m} be a setter signature of the form
\code{\VOID\ \SET\ \id(\COVARIANT?\ $T$ $p$)}.
The \NoIndex{function type of} $m$ is then
\FunctionTypeSimple{\VOID}{$T$}.

\LMHash{}%
The function type of a member signature remains unchanged if
some or all default values are omitted.

\commentary{%
  We do not specify the function type of a getter signature.
  For such signatures we will instead directly refer to the return type.%
}

\LMHash{}%
An \Index{interface} is a synthetic entity that defines
how one may interact with an object.
An interface has method, getter and setter signatures,
and a set of superinterfaces,
which are again interfaces.
Each interface is the implicit interface of a class,
in which case we call it a
\IndexCustom{class interface}{interface!class},
or a combination of several other interfaces,
in which case we call it a
\IndexCustom{combined interface}{interface!combined}.

\LMHash{}%
Let $C$ be a class.
The \Index{class interface} $I$ of $C$ is the interface that declares
a member signature derived from
each instance member declared by $C$.
The \Index{direct superinterfaces} of $I$ are the direct superinterfaces of $C$
(\ref{superinterfaces}).

\commentary{%
  We say that the class interface `declares' these member signatures,
  such that we can say that an interface `declares' or `has' a member,
  just like we do for classes.
  Note that a member signature $s$ of the interface of class $C$
  may have a parameter $p$ with modifier \COVARIANT,
  even though $s$ was derived from a declaration $D$ in $C$
  and the parameter corresponding to $p$ in $D$ does not
  have that modifier.
  This is because $p$ may have ``inherited''
  the property of being covariant-by-declaration
  from one of its superinterfaces
  (\ref{covariantParameters}).%
}

\LMHash{}%
For the purpose of performing static checks on ordinary method invocations
(\ref{ordinaryInvocation})
and property extractions
(\ref{propertyExtraction}),
any type $T$ which is $T_0$ bounded
(\ref{bindingActualsToFormals}),
where $T_0$ is a class with interface $I$,
is also considered to have interface $I$.
Similarly, when $T$ is $T_0$ bounded where $T_0$ is a function type,
$T$ is considered to have a method named \CALL{} with signature $m$,
such that the function type of $m$ is $T_0$.

\LMHash{}%
\BlindDefineSymbol{I, \List{I}{1}{k}}%
The \Index{combined interface} $I$ of a list of interfaces \List{I}{1}{k}
is the interface that declares the set of member signatures $M$,
where $M$ is determined as specified below.
The \Index{direct superinterfaces} of $I$ is the set \List{I}{1}{k}.

\LMHash{}%
Let $M_0$ be the set of all member signatures declared by \List{I}{1}{k}.
\DefineSymbol{M} is then the smallest set satisfying the following:

\begin{itemize}
\item For each name \id{} and library $L$ such that $M_0$ contains
  a member signature named \id{} which is accessible to $L$,
  let $m$ be the combined member signature named \id{}
  from \List{I}{1}{k} with respect to $L$.
  It is a compile-time error
  if the computation of this combined member signature failed.
  Otherwise, $M$ contains $m$.
\end{itemize}

\rationale{%
  Interfaces must be able to contain inaccessible member signatures,
  because they may be accessible from the interfaces associated with
  declarations of subtypes.%
}

\commentary{%
  For instance, class $C$ in library $L$ may declare a private member named
  \code{\_foo},
  a class $D$ in a different library $L_2$ may extend $C$,
  and a class $E$ in library $L$ may extend $D$;
  $E$ may then declare a member that overrides \code{\_foo} from $C$,
  and that override relation must be checked based on the interface of $D$.
  So we cannot allow the interface of $D$
  to ``forget'' inaccessible members like \code{\_foo}.

  For conflicts the situation is even more demanding:
  Classes $C_1$ and $C_2$ in library $L$ may declare private members
  \code{String \_foo(int i)} and \code{int get \_foo},
  and a subtype $D_{12}$ in a different library $L_2$ may have
  an \IMPLEMENTS{} clause listing both $C_1$ and $C_2$.
  In that case we must report a conflict even though the conflicting
  declarations are not accessible to $L_2$,
  because those member signatures are then noSuchMethod forwarded
  (\ref{theMethodNoSuchMethod}),
  and an invocation of \code{\_foo} on an instance of $D$ in $L$
  must return an `int` according to the first member signature,
  and it must return a function object according to the second one,
  and an invocation of \code{\_foo(42)}
  must return a \code{String} with the first member signature, and it must fail
  (at compile time or, for a dynamic invocation, run time) with the second.%
}

\rationale{%
  It may not be possible to satisfy such constraints simultaneously,
  and it will inevitably be a complex semantics,
  so we have chosen to make it an error.
  It is unfortunate that the addition of a private declaration
  in one library may break existing code in a different library.
  But it should be noted that the conflicts can be detected locally
  in the library where the private declarations exist,
  because they only arise for private members with
  the same name and incompatible signatures.
  Renaming that private member to anything not used in that library
  will eliminate the conflict and will not break any clients.%
}


\subsection{Combined Member Signatures}
\LMLabel{combinedMemberSignatures}

\LMHash{}%
This section specifies how to compute a member signature which will
appropriately stand for a prioritized set of several member signatures,
taken from a given list of interfaces.

\commentary{%
  In general, a combined member signature has a type which is
  a subtype of all the types given for that member.
  This is needed in order to ensure that the type of
  a member \id{} of a class $C$ is well-defined,
  even in the case where $C$ inherits
  several different declarations of \id{}
  and does not override \id.
  In case of failure, it serves to specify the situations
  where a developer must add a declaration in order to resolve an ambiguity.
  The member signatures are prioritized in the sense that we will select
  a member signature from the interface with the lowest possible index
  in the case where several member signatures are equally suitable
  to be chosen as the combined member signature.
  That is, ``the first interface wins''.%
}

\LMHash{}%
For the purposes of computing a combined member signature,
we need a special notion of
\IndexCustom{equality}{member signature equality}
of member signatures.
Two member signatures $m_1$ and $m_2$ are equal
if{}f they have the same name,
are accessible to the same set of libraries,
have the same same return type (for getters),
or the same function type and the same occurrences of \COVARIANT{}
(for methods and setters).

\commentary{%
  In particular, private methods from different libraries are never equal.
  Top types differ as well.
  For instance,
  \FunctionTypeSimple{\DYNAMIC}{} and \FunctionTypeSimple{\code{Object}}{}
  are not equal, even though they are subtypes of each other.
  We need this distinction because management of top type discrepancies is
  one of the purposes of computing a combined interface.%
}

\LMHash{}%
\BlindDefineSymbol{\id, L, I_j, k}%
Now we define combined member signatures.
Let \id{} be an identifier, $L$ a library,
\List{I}{1}{k} a list of interfaces,
and \DefineSymbol{M_0} the set of
all member signatures from \List{I}{1}{k} named \id{}
and accessible to $L$.
The
\IndexCustom{combined member signature
  named \id{} from \List{I}{1}{k} with respect to $L$}{%
  combined member signature}
is the member signature which is obtained as follows:

\LMHash{}%
If $M_0$ is empty, computation of the combined member signature failed.

\LMHash{}%
If $M_0$ contains exactly one member signature $m'$,
the combined member signature is $m'$.

\LMHash{}%
Otherwise, $M_0$ contains more than one member signature
\DefineSymbol{\List{m}{1}{q}}.

\LMHash{}%
\Case{Failing mixtures}
If $M_0$ contains at least one getter signature
and at least one non-getter signature,
the computation of the combined member signature failed.
\EndCase

\LMHash{}%
\Case{Getters}
If $M_0$ contains getter signatures only,
the computation of the combined member signature proceeds as described below
for methods and setters,
except that it uses the return type of the getter signature
where methods and setters use the function type of the member signature.
\EndCase

\LMHash{}%
\Case{Methods and setters}
In this case $M_0$ consists of setter signatures only,
or method signatures only,
because the name \id{} in the former case always ends in \lit{=},
which is never true in the latter case.

\LMHash{}%
\BlindDefineSymbol{N}%
Determine whether there exists a non-empty set $N \subseteq 1 .. q$ such that
for each $i \in N$,
the function type of $m_i$ is a subtype of
the function type of $m_j$ for each $j \in 1 .. q$.
%
If no such set exists, the computation of the combined member signature failed.
\commentary{%
  A useful intuition about this situation is that
  the given member signatures do not agree on
  which type is suitable for the member named \id.
  Otherwise we have a set of member signatures which are ``most specific''
  in the sense that their function types are subtypes of them all.%
}

{ % Scope for N_min, M_min, N_firstMin.

\def\Nall{\ensuremath{N_{\mbox{\scriptsize{}all}}}}
\def\Mall{\ensuremath{M_{\mbox{\scriptsize{}all}}}}
\def\MallFirst{\ensuremath{M_{\mbox{\scriptsize{}first}}}}

\LMHash{}%
Otherwise, when a set $N$ as specified above exists,
let \Nall{} be the greatest set satisfying the requirement on $N$,
\BlindDefineSymbol{\Mall}%
and let $\Mall{} = \{ m_i\;|\;i \in \Nall\}$.
\commentary{%
  That is, \Mall{} contains all member signatures named \id{}
  with the most specific type.
  Dart subtyping is a partial pre-order,
  which ensures that such a greatest set of least elements exists,
  if any non-empty set of least elements exist.
  We can have several such signatures because member signatures
  can be such that they are not equal,
  and yet their function types are subtypes of each other.
  We need to compute one member signature from \Mall,
  and we do that by using the ordering of the given interfaces.%
}

\LMHash{}%
\BlindDefineSymbol{\MallFirst}%
Let $j \in 1 .. k$ be the smallest number such that
$\MallFirst{} = \Mall{} \cap I_j$ is non-empty.
Let $m_i$ be the single element that \MallFirst{} contains.
\commentary{%
  This set contains exactly one element because it is non-empty
  and no interface contains more than one member signature named \id.
  In other words, we choose $m_i$ as the member signature from
  the first possible interface
  among the most specific member signatures \Mall.%
}
}

\LMHash{}%
The combined member signature is then $m'$,
which is obtained from $m_i$ by adding the modifier \COVARIANT{}
to each parameter $p$ (if it is not already present)
when there exists a $j \in 1 .. q$
such that the parameter corresponding to $p$
(\ref{covariantParameters})
has the modifier \COVARIANT.
\commentary{%
  In other words,
  each parameter in the combined member signature is marked covariant
  if any of the corresponding parameters are marked covariant,
  not just among the most specific signatures,
  but among \emph{all} signatures named \id{} (which are accessible to $L$)
  in the given list of interfaces.%
}
\EndCase


\subsection{Superinterfaces}
\LMLabel{interfaceSuperinterfaces}

\LMHash{}%
An interface has a set of direct superinterfaces
(\ref{interfaces}).
An interface $J$ is a \Index{superinterface} of an interface $I$
if{}f either $J$ is a direct superinterface of $I$
or $J$ is a superinterface of a direct superinterface of $I$.

\LMHash{}%
When we say that a type $S$
\IndexCustom{implements}{type!implements a type}
another type $T$,
this means that $T$ is a superinterface of $S$,
or $S$ is $S_0$ bounded for some type $S_0$
(\ref{bindingActualsToFormals}),
and $T$ is a superinterface of $S_0$.
Assume that $G$ is a raw type
(\ref{instantiationToBound})
whose declaration declares $s$ type parameters.
When we say that a type $S$
\IndexCustom{implements}{type!implements a raw type}
$G$,
this means that there exist types \List{U}{1}{s}
such that $S$ implements \code{$G$<\List{U}{1}{s}>}.

\commentary{%
  Note that this is not the same as being a subtype.
  For instance, \code{List<int>} implements \code{Iterable<int>},
  but it does not implement \code{Iterable<num>}.
  Similarly, \code{List<int>} implements \code{Iterable}.
  Also, note that when $S$ implements $T$
  where $T$ is not a subtype of \code{Null},
  $S$ cannot be a subtype of \code{Null}.%
}

\LMHash{}%
Assume that $S$ is a type and $G$ is a raw type such that $S$ implements $G$.
Then there exist unique types \List{U}{1}{s} such that
$S$ implements \code{$G$<\List{U}{1}{s}>}.
We then say that \List{U}{1}{s} are the
\IndexCustom{actual type arguments of $S$ at $G$}{%
  type arguments!of a type at a raw type},
and we say that $U_j$ is the
\IndexCustom{$j$th actual type argument of $S$ at $G$}{%
  type arguments!of a type at a raw type, $j$th},
for any $j \in 1 .. s$.

\commentary{%
  For instance, the type argument of \code{List<int>} at \code{Iterable}
  is \code{int}.
  This concept is particularly useful when
  the chain of direct superinterfaces from $S$ to $G$
  does not just pass all type arguments on unchanged, e.g.,
  with a declaration like
  \code{\CLASS\,\,C<X,\,Y>\,\,\EXTENDS\,\,B<List<Y>,\,Y,\,X> \{\}}.%
}


\subsubsection{Inheritance and Overriding}
\LMLabel{interfaceInheritanceAndOverriding}

\LMHash{}%
\BlindDefineSymbol{J, K}%
Let $J$ be an interface and $K$ be a library.
We define $\inherited{J, K}$ to be the set of member signatures
\DefineSymbol{m}
such that all of the following hold:

\begin{itemize}
\item $m$ is accessible to $K$ and
\item $A$ is a direct superinterface of $J$ and either
  \begin{itemize}
  \item $A$ declares a member signature $m$ or
  \item $m$ is a member of $\inherited{A, K}$.
  \end{itemize}
\item $m$ is not overridden by $J$.
\end{itemize}

\LMHash{}%
Furthermore, we define $\overrides{J, K}$ to be
the set of member signatures \DefineSymbol{m'}
such that all of the following hold:

\begin{itemize}
\item $J$ is the interface of a class $C$.
\item $C$ declares a member signature $m$.
\item $m'$ has the same name as $m$.
\item $m'$ is accessible to $K$.
\item $A$ is a direct superinterface of $J$ and either
  \begin{itemize}
  \item $A$ declares a member signature $m'$ or
  \item $m'$ is a member of $inherited(A, K)$.
  \end{itemize}
\end{itemize}

\LMHash{}%
Let $I$ be the interface of a class $C$ declared in library $L$.
$I$ \Index{inherits} all members of $\inherited{I, L}$
and $I$ \Index{overrides} $m'$ if $m' \in \overrides{I, L}$.

\LMHash{}%
All the compile-time errors pertaining to the overriding of instance members
given in section~\ref{classes} hold for overriding between interfaces as well.

\LMHash{}%
If the above rule would cause multiple member signatures
with the same name \id{} to be inherited then
exactly one member is inherited, namely
the combined member signature named \id,
from the direct superinterfaces
% This is well-defined because $I$ is a class interface.
in the textual order that they are declared,
with respect to $L$
(\ref{combinedMemberSignatures}).
It is a compile-time error
if the computation of said combined member signature fails.


\subsubsection{Correct Member Overrides}
\LMLabel{correctMemberOverrides}

\LMHash{}%
\BlindDefineSymbol{m, m', \id}%
Let $m$ and $m'$ be member signatures with the same name \id.
Then $m$ is a \Index{correct override} of $m'$
if{}f the following criteria are all satisfied:

\begin{itemize}
\item
  $m$ and $m'$ are both methods, both getters, or both setters.
\item
  If $m$ and $m'$ are both getters:
  The return type of $m$ must be a subtype of the return type of $m'$.
\item
  If $m$ and $m'$ are both methods or both setters:
  Let $F$ be the function type of $m$
  except that the parameter type is the built-in class \code{Object}
  for each parameter of $m$ which is covariant-by-declaration
  (\ref{covariantParameters}).
  Let $F'$ be the function type of $m'$.
  $F$ must then be a subtype of $F'$.

  \commentary{%
    The subtype requirement ensures that argument list shapes
    that are admissible for an invocation of a method with signature $m'$
    are also admissible for an invocation of a method with signature $m$.
    For instance, $m'$ may accept 2 or 3 positional arguments,
    and $m$ may accept 1, 2, 3, or 4 positional arguments, but not vice versa.
    This is a built-in property of the function type subtype rules.
  }
\item
  %% TODO(eernst): Come nnbd, this warning is removed.
  If $m$ and $m'$ are both methods,
  $p$ is an optional parameter of $m$,
  $p'$ is the parameter of $m'$ corresponding to $p$,
  $p$ has default value $d$ and $p'$ has default value $d'$,
  then $d$ and $d'$ must be identical,
  or a static warning occurs.
\end{itemize}

\commentary{%
  Note that a parameter which is covariant-by-declaration
  must have a type which satisfies one more requirement,
  relative to the corresponding parameters in all superinterfaces,
  both direct and indirect
  (\ref{instanceMethods}).
  We cannot make that requirement a part of the notion of correct overrides,
  because correct overrides are only concerned with
  the relation to a single superinterface.%
}


\section{Mixins}
\LMLabel{mixins}

\LMHash{}%
A mixin describes the difference between a class and its superclass.
A mixin is either derived from an existing class declaration
or introduced by a mixin declaration.
It is a compile-time error to derive a mixin from
a class that declares a generative constructor,
or from a class that has a superclass other than \code{Object}.

\LMHash{}%
Mixin application occurs when one or more mixins are mixed into
a class declaration via its \WITH{} clause (\ref{mixinApplication}).
Mixin application may be used to extend a class per section \ref{classes};
alternatively, a class may be defined as a mixin application
as described in the following section.


\subsection{Mixin Classes}
\LMLabel{mixinClasses}

\begin{grammar}
<mixinApplicationClass> ::= \gnewline{}
  <identifier> <typeParameters>? `=' <mixinApplication> `;'

<mixinApplication> ::= <typeNotVoid> <mixins> <interfaces>?
\end{grammar}

\LMHash{}%
It is a compile-time error if an element in
the type list of the \WITH{} clause of a mixin application is
a type variable (\ref{generics}),
a function type (\ref{functionTypes}),
a type alias that does not denote a class (\ref{typedef}),
an enumerated type (\ref{enums}),
a deferred type (\ref{staticTypes}),
type \DYNAMIC{} (\ref{typeDynamic}),
type \VOID{} (\ref{typeVoid}),
or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
If $T$ is a type in a \WITH{} clause, \IndexCustom{the mixin of}{type!mixin of}
$T$ is either the mixin derived from $T$ if $T$ denotes a class,
or the mixin introduced by $T$ if $T$ denotes a mixin declaration.

\LMHash{}%
Let $D$ be a mixin application class declaration of the form

\begin{normativeDartCode}
\ABSTRACT? \CLASS{} $N$ = $S$ \WITH{} $M_1$, \ldots, $M_n$ \IMPLEMENTS{} $I_1$, \ldots, $I_k$;
\end{normativeDartCode}

\LMHash{}%
It is a compile-time error if $S$ is an enumerated type (\ref{enums}).
It is a compile-time error if any of $M_1, \ldots, M_k$ is an enumerated type
(\ref{enums}).

\LMHash{}%
The effect of $D$ in library $L$ is to introduce the name $N$ into
the scope of $L$, bound to the class (\ref{classes}) defined by the clause
\code{$S$ \WITH{} $M_1$, \ldots, $M_n$}
with name $N$, as described below.
If $k > 0$ then the class also implements $I_1$, \ldots, $I_k$.
If{}f the class declaration is prefixed by the built-in identifier \ABSTRACT,
the class being defined is made an abstract class.

\LMHash{}%
A clause of the form \code{$S$ \WITH{} $M_1$, \ldots, $M_n$}
with name $N$ defines a class as follows:

\LMHash{}%
If there is only one mixin ($n = 1$), then \code{$S$ \WITH{} $M_1$}
defines the class yielded by the mixin application (\ref{mixinApplication})
of the mixin of $M_1$ (\ref{mixinDeclaration}) to the class denoted by
$S$ with name $N$.

\LMHash{}%
If there is more than one mixin ($n > 1$), then
let $X$ be the class defined by \code{$S$ \WITH{} $M_1$, \ldots, $M_{n-1}$}
with name $F$, where $F$ is a fresh name, and make $X$ abstract.
Then \code{$S$ \WITH{} $M_1$, \ldots, $M_n$} defines the class yielded
by the mixin application of the mixin of $M_n$ to the class $X$ with name $N$.

\LMHash{}%
In either case, let $K$ be a class declaration with
the same constructors, superclass, interfaces and instance members as
the defined class.
It is a compile-time error if the declaration of $K$ would cause
a compile-time error.
% TODO(eernst): Not completely!
% We do not want super-invocations on covariant implementations
% to be compile-time errors.

\commentary{%
  It is an error, for example, if $M$ contains a member declaration $d$
  which overrides a member signature $m$ in the interface of $S$,
  but which is not a correct override of $m$
  (\ref{correctMemberOverrides}).%
}

\subsection{Mixin Declaration}
\LMLabel{mixinDeclaration}

\LMHash{}%
A mixin defines zero or more
\IndexCustom{member declarations}{member declaration},
zero or more
\IndexCustom{required superinterfaces}{mixin!required superinterface},
one
\IndexCustom{combined superinterface}{mixin!combined superinterface},
and zero or more
\IndexCustom{implemented interfaces}{mixin!implemented interface}.

\LMHash{}%
The mixin derived from a class declaration:

\begin{normativeDartCode}
\ABSTRACT? \CLASS{} $X$ \IMPLEMENTS{} $I_1$, \ldots, $I_k$ \{
  \metavar{members}
\}
\end{normativeDartCode}

\noindent
has \code{Object} as required superinterface
and combined superinterface,
$I_1$, \ldots, $I_k$ as implemented interfaces,
and the instance members of \metavar{members} as mixin member declarations.
If $X$ is generic, so is the mixin.

\LMHash{}%
A mixin declaration introduces a mixin and provides a scope
for static member declarations.

\begin{grammar}
<mixinDeclaration> ::= \MIXIN{} <typeIdentifier> <typeParameters>?
  \gnewline{} (\ON{} <typeNotVoidList>)? <interfaces>?
  \gnewline{} `\{' (<metadata> <memberDeclaration>)* `\}'
\end{grammar}

\LMHash{}%
It is a compile-time error to declare a constructor in a mixin-declaration.

\LMHash{}%
A mixin declaration with no \code{\ON} clause is equivalent
to one with the clause \code{\ON{} Object}.

\LMHash{}%
Let $M$ be a \MIXIN{} declaration of the form

\begin{normativeDartCode}
\MIXIN{} $N$<\TypeParametersStd> \ON{} \List{T}{1}{n}
    \IMPLEMENTS{} \List{I}{1}{k} \{
  \metavar{members}
\}
\end{normativeDartCode}

\LMHash{}%
It is a compile-time error if any of the types $T_1$ through $T_n$
or $I_1$ through $I_k$ is
a type variable (\ref{generics}),
a function type (\ref{functionTypes}),
a type alias not denoting a class (\ref{typedef}),
an enumerated type (\ref{enums}),
a deferred type (\ref{staticTypes}),
type \DYNAMIC{} (\ref{typeDynamic}),
type \VOID{} (\ref{typeVoid}),
or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).

\LMHash{}%
Let $M_S$ be the interface declared by the class declaration

\begin{normativeDartCode}
\ABSTRACT{} \CLASS{} $M_{super}$<$P_1$, \ldots, $P_m$> \IMPLEMENTS{} $T_1$, $\dots{}$, $T_n$ \{\}
\end{normativeDartCode}

\noindent
where $M_{super}$ is a fresh name.
It is a compile-time error for the mixin declaration if the $M_S$
class declaration would cause a compile-time error,
\commentary{%
  that is, if any member is declared by more than one declared superinterface,
  and there is not a most specific signature for that member among the super
  interfaces%
}.
The interface $M_S$ is called the
\Index{superinvocation interface} of the mixin declaration $M$.
\commentary{%
  If the mixin declaration $M$ has only one declared superinterface, $T_1$,
  then the superinvocation interface $M_S$ has exactly the same members
  as the interface $T_1$.%
}

\LMHash{}%
Let $M_I$ be the interface that would be defined by the class declaration

\begin{normativeDartCode}
\ABSTRACT{} \CLASS{} $N$<\TypeParametersStd>
    \IMPLEMENTS{} \List{T}{1}{n}, \List{I}{1}{k} \{
  $\metavar{members}'$
\}
\end{normativeDartCode}

\noindent
where $\metavar{members}'$ are the member declarations of
the mixin declaration $M$ except that all superinvocations are treated
as if \SUPER{} was a valid expression with static type $M_S$.
It is a compile-time error for the mixin $M$ if this $N$ class
declaration would cause a compile-time error,
\commentary{%
  that is, if the required superinterfaces, the implemented interfaces
  and the declarations do not define a consistent interface,
  if any member declaration contains a compile-time error
  other than a super-invocation,
  or if a super-invocation is not valid against the interface $M_S$.%
}
The interface introduced by the mixin declaration $M$ has the same member
signatures and superinterfaces as $M_I$.

\LMHash{}%
The mixin declaration $M$ introduces a mixin
with the \NoIndex{required superinterface}s $T_1$, \ldots, $T_n$,
the \NoIndex{combined superinterface} $M_S$,
\NoIndex{implemented interface}s $I_1$, \ldots, $I_k$
and the instance members declared in $M$ as \Index{member declarations}.


\subsection{Mixin Application}
\LMLabel{mixinApplication}

\LMHash{}%
A mixin may be applied to a superclass, yielding a new class.

\LMHash{}%
Let $S$ be a class,
$M$ be a mixin with \NoIndex{required superinterface}s $T_1$, \ldots, $T_n$,
\NoIndex{combined superinterface} $M_S$,
\NoIndex{implemented interfaces} $I_1$, \ldots, $I_k$ and
\metavar{members} as \NoIndex{member declarations},
and let $N$ be a name.

\LMHash{}%
It is a compile-time error to apply $M$ to $S$ if $S$ does not implement,
directly or indirectly, all of $T_1$, \ldots, $T_n$.
It is a compile-time error if any of \metavar{members} contains a
super-invocation of a member $m$
\commentary{%
  (for example \code{super.foo}, \code{super\,\,+\,\,2},
  or \code{super[1]\,=\,2}),%
}
and $S$ does not have a concrete
implementation of $m$ which is a valid override of the member $m$ in
the interface $M_S$.
\rationale{%
  We treat super-invocations in mixins as
  interface invocations on the combined superinterface,
  so we require the superclass of a mixin application to have
  valid implementations of those interface members
  that are actually super-invoked.%
}

\LMHash{}%
The mixin application of $M$ to $S$ with name $N$ introduces a new
class, $C$, with name $N$, superclass $S$,
implemented interface $M$
and \metavar{members} as instance members.
The class $C$ has no static members.
If $S$ declares any generative constructors, then the application
introduces generative constructors on $C$ as follows:

\LMHash{}%
Let $L_C$ be the library containing the mixin application.
\commentary{%
  That is, the library containing the clause \code{$S$ \WITH{} $M$}
  or the clause \code{$S_0$ \WITH{} $M_1$, \ldots,\ $M_k$, $M$}
  giving rise to the mixin application.%
}

Let $S_N$ be the name of $S$.

For each generative constructor of the form
\code{$S_q$($T_{1}$ $a_{1}$, $\ldots$, $T_{k}$ $a_{k}$)}
of $S$ that is accessible to $L_C$, $C$ has
an implicitly declared constructor of the form

\begin{normativeDartCode}
$C_q$($T_{1}$ $a_{1}$, \ldots, $T_{k}$ $a_{k}$): $\SUPER_q$($a_{1}$, $\ldots$, $a_{k}$);
\end{normativeDartCode}

\noindent
where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$,
which denote the superclass, by $N$, and $\SUPER_q$ is obtained from $S_q$ by
replacing occurrences of $S_N$ which denote the superclass by \SUPER.
If $S_q$ is a generative const constructor, and $C$ does not declare any
instance variables, $C_q$ is also a const constructor.

\LMHash{}%
For each generative constructor of the form
\code{$S_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, [$T_{k+1}$ $a_{k+1}$ = $d_1$, \ldots , $T_{k+p}$ $a_{k+p}$ = $d_p$])}
of $S$ that is accessible to $L_C$, $C$ has
an implicitly declared constructor of the form

\begin{normativeDartCode}
$C_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, [$T_{k+1}$ $a_{k+1}$ = $d'_{1}$, \ldots , $T_{k+p}$ $a_{k+p}$ = $d'_p$])
    : $\SUPER_q$($a_{1}$, \ldots , $a_{k}$, $a_{k+1}$, \ldots, $a_p$);
\end{normativeDartCode}

\noindent
where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$,
which denote the superclass, by $N$,
$\SUPER_q$ is obtained from $S_q$ by replacing occurrences of $S_N$
which denote the superclass by \SUPER,
and $d'_i$, $i \in 1..p$, is a constant expression evaluating
to the same value as $d_i$.
If $S_q$ is a generative const constructor, and $MC$ does not declare any
instance variables, $C_q$ is also a const constructor.

\LMHash{}%
For each generative constructor of the form
\code{$S_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, \{$T_{k+1}$ $a_{k+1}$ = $d_1$, \ldots , $T_{k+n}$ $a_{k+n}$ = $d_n$\})}
of $S$ that is accessible to $L_C$, $C$ has
an implicitly declared constructor of the form

\begin{normativeDartCode}
$C_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, \{$T_{k+1}$ $a_{k+1}$ = $d'_1$, \ldots , $T_{k+n}$ $a_{k+n}$ = $d'_n$\})
    : $\SUPER_q$($a_{1}$, \ldots , $a_{k}$, $a_{k+1}$: $a_{k+1}$, \ldots, $a_p$: $a_p$);
\end{normativeDartCode}

\noindent
where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$
which denote the superclass by $N$,
$\SUPER_q$ is obtained from $S_q$ by replacing occurrences of $S_N$
which denote the superclass by \SUPER,
and $d'_i$, $i \in 1..n$, is a constant expression evaluating to
the same value as $d_i$.
If $S_q$ is a generative const constructor, and $M$ does not declare any
fields, $C_q$ is also a const constructor.

\LMHash{}%
If $S$ does not declare any generative constructors then the application
does not implicitly induce any forwarding constructors.
In particular, it does not induce a default constructor
(\ref{constructors}).

\commentary{%
  The default constructor would have a superinitializer
  that attempts to invoke a constructor that does not exist.
  Developers would have no way to eliminate this error.%
}


\section{Extensions}
\LMLabel{extensions}

\LMHash{}%
This section specifies extensions.
This mechanism supports the declaration of functions
that are similar to instance methods in use,
but similar to non-method functions in that
they are declared outside the target class,
and they are resolved statically.
The resolution is based on whether the relevant extension is in scope,
and whether the invocation satisfies several other requirements.

\begin{grammar}
<extensionDeclaration> ::= \gnewline{}
  \EXTENSION{} <typeIdentifierNotType>? <typeParameters>? \ON{} <type>
  \gnewline{} `\{' (<metadata> <memberDeclaration>)* `\}'
\end{grammar}

\LMHash{}%
A declaration derived from \synt{extensionDeclaration} is known as an
\IndexCustom{extension declaration}{extension!declaration}.
It introduces an
\Index{extension}
with the given \synt{identifier}, if present,
into the namespace of the enclosing library
\commentary{(and hence into the library scope)},
and provides a scope for the declaration of
extension members.
Additionally, the extension is introduced into the library namespace
with a fresh, private name.
The former is known as the
\IndexCustom{declared name}{extension!declared name}
of the extension,
and the latter is known as the
\IndexCustom{fresh name}{extension!fresh name}
of the extension.

\commentary{%
  A fresh name is also introduced into
  the library namespace of the current library
  for each imported extension,
  even when it is imported with a prefix
  (\ref{theImportedNamespace}).
  %
  The declared name of an extension $E$ is
  introduced into the library scope of the current library
  following the same rules as the names of
  other locally declared or imported declarations like classes.
  %
  A fresh name of $E$ is introduced in these cases,
  but also in one additional case:
  when there is a name clash on the declared name of $E$.%
}

\commentary{%
  The fresh name makes it possible for an extension to be used
  in an implicit invocation
  (\ref{implicitExtensionInvocations}),
  even in the case where the declared name
  or an import prefix that provides access to the declared name
  is shadowed by a declaration in an intermediate scope,
  or conflicted by a name clash.%
}

\rationale{%
  The fact that an extension can be used implicitly even in the case where
  it does not have a declared name
  or the declared name is shadowed or conflicted
  reflects the fact that the primary intended usage is implicit invocation.
  Even though a developer cannot know (and hence cannot use) the fresh name
  of a given extension, an implicit invocation can use it.%
}

\LMHash{}%
It is a compile-time error if the current library has
a deferred import of a library $L'$
such that the imported namespace from $L'$ contains
a name denoting an extension.

\commentary{%
  This implies that the import must use \HIDE{} or \SHOW{} to eliminate
  the names of extensions from the deferred import.%
}

\rationale{%
  This restriction ensures that no extensions are introduced
  using deferred imports,
  which allows us to introduce a semantics for such extensions in the future
  without affecting existing code.%
}

\LMHash{}%
The \synt{type} in an extension declaration
is known as the extension's
\IndexCustom{\ON{} type}{extension!\ON{} type}.
The \ON{} type can be any valid type, including a type variable.

\commentary{%
  The basic intuition is that an extension \code{E} may have
  an \ON{} type $T$ (specifying the type of receiver) and a set of members.
  If $e$ is an expression whose static type is $T$
  and \code{foo()} is a member declared by \code{E},
  \code{$e$.foo()} may invoke said member with the value of $e$ bound to \THIS.
  An explicitly resolved form \code{E($e$).foo()} is available,
  such that \code{E.foo} can be invoked even in the case
  where \code{$e$.foo()} would invoke some other function
  because some other extension is more specific.
  Details of these concepts, rules, and mechanisms are given
  in this section and its subsections.%
}

\LMHash{}%
The declared name of an extension does not denote a type,
but it can be used to denote the extension itself
\commentary{%
  (e.g., in order to access static members of the extension,
  or in order to resolve an invocation explicitly)%
}.

\LMHash{}%
An extension declaration introduces two scopes:

\begin{itemize}
\item
  A \IndexCustom{type-parameter scope}{scope!type parameter},
  which is empty if the extension is not generic (\ref{generics}).
  The enclosing scope of the type-parameter scope of an extension declaration is
  the library scope of the current library.
  The type parameter scope is the current scope for
  the type parameters and for the extension's \ON{} \synt{type}.
\item
  A \IndexCustom{body scope}{scope!extension body}.
  The enclosing scope of the body scope of an extension declaration is
  the type parameter scope of the extension declaration.
  The current scope for an extension member declaration is
  the body scope of the enclosing extension declaration.
\end{itemize}

\LMHash{}%
\BlindDefineSymbol{D, \code{E}}%
Let $D$ be an extension declaration with declared name \code{E}.
A member declaration in $D$ with the modifier \STATIC{} is designated as a
\IndexCustom{static member}{extension!static member}
declaration.
%
A member declaration in $D$ without the modifier \STATIC{} is designated as an
\IndexCustom{instance member}{extension!instance member}
declaration.
%
Member naming conflict errors may occur in $D$
in situations that also occur in classes and mixins
(\ref{classMemberConflicts}).
Moreover, a compile-time error occurs in the following situations:

\begin{itemize}
\item $D$ declares a member whose basename is \code{E}.
\item $D$ declares a type parameter named \code{E}.
\item $D$ declares a member whose basename is the name of a type parameter
  of $D$.
\item $D$ declares an instance member or a static member whose basename is
  \code{hashCode}, \code{noSuchMethod}, \code{runtimeType}, \code{toString},
  or \lit{==}.
  \commentary{%
    That is, a member whose basename is also the name of
    an instance member that every object has.%
  }
\item $D$ declares a constructor.
\item $D$ declares an instance variable.
\item $D$ declares an abstract member.
\item $D$ declares a method with a formal parameter
  with the modifier \COVARIANT.
\end{itemize}

\rationale{%
  Abstract members are not allowed because there is
  no support for providing an implementation.
  %
  Constructors are not allowed since the extension
  does not introduce any type that can be constructed.
  %
  Instance variables are not allowed because no memory is allocated
  for each object accessed as \THIS{} in the members.
  Developers can emulate per-\THIS{} state if needed,
  e.g., using an \code{Expando}.
  %
  Members with the same basename as members of \code{Object}
  are not allowed because they could only be invoked using explicit resolution,
  as in \code{E(e).toString(14)},
  which would be confusing and error-prone.%
}


\subsection{Explicit Invocation of an Instance Member of an Extension}
\LMLabel{explicitExtensionInvocations}

\LMHash{}%
Let \DefineSymbol{E} be a simple or qualified identifier
that denotes an extension.
An \IndexCustom{extension application}{extension!application}
is then an expression of the form
\syntax{$E$ <typeArguments>? `(' <expression> `)'}.
An extension member with a name accessible to the current library
can be invoked explicitly on a particular object
by performing a member invocation
(\ref{memberInvocations})
where the receiver is an extension application.

\commentary{%
  Type inference is not yet specified in this document,
  and is assumed to have taken place already
  (\ref{overview}),
  but the following describes the intended treatment.
  This section and its subsections have similar commentary about type inference
  below, marked 'With type inference: \ldots'.

  Let $E$ be a simple or qualified identifier denoting
  an extension named \code{E} and declared as follows:%
}

\begin{dartCode}
\EXTENSION{} E<\TypeParametersStd> on $T$ \{\,\ldots\,\}
\end{dartCode}

\noindent
\commentary{%
  Type inference for an extension application
  of the form \code{$E$($e$)}
  is done exactly the same as it would be for
  the same syntax considered as a constructor invocation
  where $E$ is assumed to denote the following class,
  and the context type is empty (implying no requirements):%
}

\begin{dartCode}
\CLASS{} E<\TypeParametersStd> \{
  final $T$ target;
  E(this.target);
\}
\end{dartCode}

\commentary{%
  This will infer type arguments for \code{$E$($e$)}, and it will
  introduce a context type for the expression $e$.
  For example, if $E$ is declared as
  \code{\EXTENSION{} E<T> on Set<T> \{\,\ldots\,\}}
  then \code{E(\{\})} will provide the expression \code{\{\}} with
  a context type that makes it a set literal.%
}

\LMHash{}%
\BlindDefineSymbol{a, E, T_j, e}%
Let $a$ be an extension application of the form
\code{$E$<\List{T}{1}{s}>($e$)},
where $E$ denotes an extension declared as

\noindent
\BlindDefineSymbol{X_j, B_j, s, T}%
\EXTENSION{} E<\TypeParametersStd> \ON{} $T$ \{\,\ldots\,\}.

\LMHash{}%
We define the
\IndexCustom{instantiated \ON{} type}{extension!instantiated \ON{} type}
of $a$ as $[T_1/X_1, \ldots, T_s/X_s]T$.
We define the
\IndexCustom{instantiation-to-bound \ON{} type}{%
  extension!instantiation-to-bound \ON{} type}
of $a$ as $[U_1/X_1, \ldots, U_s/X_s]T$,
where \List{U}{1}{s} is the result of instantiation to bound
on the type parameters of $E$
(\ref{instantiationToBound}).
%
A compile-time error occurs unless
\SubtypeNE{T_j}{[T_1/X_1, \ldots, T_s/X_s]B_j},
$j \in 1 .. s$
\commentary{(that is, the bounds cannot be violated)}.
%
A compile-time error occurs unless the static type of $e$ is assignable to
the instantiated \ON{} type of $a$.
\commentary{%
  Note that a compile-time error occurs as well
  if the static type of $e$ is \VOID{}
  (\ref{typeVoid}).%
}

\LMHash{}%
It is a compile-time error if an extension application occurs
in a location where it is \emph{not} the syntactic receiver of
a simple or composite member invocation
(\ref{memberInvocations}).

\commentary{%
  That is, the only valid use of an extension application is
  to invoke or tear off members on it.
  This is similar to how prefix names can also only be used as
  member invocation targets,
  except that extensions can also declare operators.
  For instance, \code{$E$($e$) + 1} can be a valid invocation of
  an operator \lit{+} declared in an extension $E$.%
}

\LMHash{}%
An extension application does not have a type.

\commentary{%
  This is consistent with the fact that any use of an extension application
  where a type is needed is a compile-time error.%
}

\LMHash{}%
\BlindDefineSymbol{i, r}%
Let $i$ be a simple member invocation
(\ref{memberInvocations})
whose receiver $r$ is an extension application of the form
\BlindDefineSymbol{E, T_j, k, e}%
\code{$E$<\List{T}{1}{k}>($e$)}
\commentary{(which is \code{$E$($e$)} when $k$ is zero)}
whose corresponding member name is \DefineSymbol{n},
and assume that $r$ has no compile-time errors.
A compile-time error occurs unless the extension denoted by $E$
declares a member named $n$.
Otherwise let \DefineSymbol{\List{X}{1}{k}} be
the type parameters of said extension.
Let \DefineSymbol{s} be the member signature of the member $n$ declared by $E$.
Exactly the same compile-time errors occur for $i$ as
the ones that would occur for a member invocation $i_1$
which is obtained from $i$ by replacing $r$ by
a variable whose type is
a class $C$ declared in the same scope as $E$
that declares a member $n$ with member signature
$s_1 = [T_1/X_1, \ldots, T_k/X_k]s$:

\begin{normativeDartCode}
\ABSTRACT{} \CLASS{} $C$ \{
  $D$ // \comment{Member declaration with signature $s_1$.}
\}
\end{normativeDartCode}

\LMHash{}%
The member signature $s_1$ is called the
\IndexCustom{invocation member signature}{%
  extension!invocation member signature}
of $i$.
The static type of $i$ is the return type of
the invocation member signature of $i$.
\commentary{For example:}

\begin{dartCode}
\EXTENSION{} E<X> \ON{} List<X> \{
  List<List<X>{}> split(int at) =>
      [this.sublist(0, at), this.sublist(at)];
\}
\\
\VOID{} main() \{
  List<num> xs = [1, 2, 3];
  \VAR{} ys = E<num>(xs).split(1); // \comment{(*)}
\}
\\
\ABSTRACT{} \CLASS{} C \{
  // \comment{Declaration with invocation member signature for (*).}
  List<List<num>{}> split(int at);
\}
\end{dartCode}

\commentary{%
  With type inference:
  In the case where the invocation member signature $s_1$ is generic,
  type inference occurs on $i$ in the same way as it
  would occur for an invocation of a function whose type is the
  function type of $s_1$.%
}

\LMHash{}%
\BlindDefineSymbol{i, r}%
For the dynamic semantics,
let $i$ be a simple, unconditional member invocation
whose receiver $r$ is an extension application of the form
\BlindDefineSymbol{E, T_j, k, e}%
\code{$E$<\List{T}{1}{k}>($e$)}
where the type parameters of $E$ are \DefineSymbol{\List{X}{1}{k}}
and the actual values of \List{T}{1}{k} are \DefineSymbol{\List{t}{1}{k}}
(\ref{actualTypes}),
\BlindDefineSymbol{n, m}%
and whose corresponding member name is $n$.
Let $m$ be the member of $E$ that has the name $n$.
Evaluation of $i$ proceeds by evaluating
$e$ to an object $o$,
evaluating and binding the actual arguments to the formal parameters
(\ref{bindingActualsToFormals}),
and finally executing $m$
in a binding environment where \List{X}{1}{k} are bound to \List{t}{1}{k},
\THIS{} is bound to $o$,
and each formal parameter is bound to the corresponding actual argument.
The value of $i$ is the value returned by the invocation of $m$.

\LMHash{}%
When $i$ is a conditional or composite member invocation,
the static analysis and dynamic semantics is determined by
member invocation desugaring
(\ref{memberInvocations}).

\rationale{%
  Note that a cascade (\ref{cascades})
  whose receiver is an extension application $a$ is a compile-time error.
  This is so because it implies that $a$ denotes an object, which is not true,
  and also because it would force each \synt{cascadeSection}
  to invoke a member of the same extension,
  which is unlikely to be desirable.%
}


\subsection{Implicit Invocation of an Instance Member of an Extension}
\LMLabel{implicitExtensionInvocations}

\LMHash{}%
Instance members of an extension can be invoked or closurized implicitly
\commentary{(without mentioning the name of the extension)},
as if they were instance members of the receiver of
the given member invocation.

\commentary{%
  For instance, if \code{E<$T_1, T_2$>($e_1$).m<$T_3$>($e_2$)} is
  a correct explicit invocation of the instance member \code{m} of
  an extension \code{E},
  then \code{$e_1$.m<$T_3$>($e_2$)} may be
  a correct implicit invocation with the same meaning.
  In other words,
  the receiver $r$ of a member invocation can be implicitly replaced by
  an extension application with receiver $r$,
  if a number of requirements that are detailed below are satisfied.%
}

\rationale{%
  Implicit invocation is intended as the primary way to use extensions,
  with explicit invocation as a fallback
  in case the implicit invocation is an error, or
  the implicit invocation resolves to an instance member of
  a different extension than the intended one.%
}

\LMHash{}%
\BlindDefineSymbol{i, r, m}%
An implicit extension member invocation occurs
for a member invocation $i$
(\ref{memberInvocations})
with receiver $r$ and corresponding member name $m$ if{}f
(1) $r$ is not a type literal,
(2) the interface of the static type of $r$ does not have a member
whose basename is the basename of $m$,
and (3) there exists a unique most specific
(\ref{extensionSpecificity})
extension denoted by $E$ which is accessible
(\ref{extensionAccessibility})
and applicable
(\ref{extensionApplicability})
to $i$.

\LMHash{}%
In the case where no compile-time error occurs,
$i$ is treated as $i'$, which is obtained from $i$ by
replacing the leading $r$ by \code{$E$($r$)}.

\commentary{%
  With type inference:
  When $E$ is generic,
  type inference applied to \code{$E$($r$)} may provide actual type arguments,
  yielding an $i'$ of the form \code{$E$<\List{T}{1}{k}>($r$)}.
  If this type inference step fails then $E$ is not applicable
  (\ref{extensionApplicability}).%
}

\commentary{%
  Implicit invocation of an instance member of an extension
  in a cascade is also possible,
  because a cascade is desugared to an expression that contains
  one or more member invocations.%
}


\subsubsection{Accessibility of an Extension}
\LMLabel{extensionAccessibility}

\LMHash{}%
An extension $E$ is
\IndexCustom{accessible}{extension!accessibility}
in a given scope $S$
if there exists a name $n$ such that a lexical lookup for $n$ from $S$
(\ref{lexicalLookup})
yields $E$.

\commentary{%
  The name $n$ can be the declared name of $E$ or the fresh name of $E$,
  but since the fresh name is always in scope
  whenever the declared name is in scope,
  it is sufficient to consider the fresh name.
  %
  When the fresh name of $E$ is in the library scope,
  it is available in \emph{any} scope,
  because the name is fresh and hence it cannot be shadowed
  by any declaration in any intermediate scope.
  %
  This implies that if $E$ is accessible anywhere in a given library $L$
  then it is accessible everywhere in $L$.%
}


\subsubsection{Applicability of an Extension}
\LMLabel{extensionApplicability}

\LMHash{}%
\BlindDefineSymbol{E, e, r, S, m}%
Let $E$ be an extension.
Let $e$ be a member invocation
(\ref{memberInvocations})
with a receiver $r$ with static type $S$
and with a corresponding member name whose basename is $m$.
We say that $E$ is
\IndexCustom{applicable}{extension!is applicable}
to $e$ if the following conditions are all satisfied:

\begin{itemize}
\item
  $r$ is not a type literal.

  \commentary{%
    This means that the invocation is an instance member invocation,
    in the sense that $r$ denotes an object,
    so it may invoke an instance member or be an error,
    but it cannot be a static member access.
    Note that $r$ also does not denote a prefix or an extension,
    and it is not an extension application,
    because they do not have a type.%
  }
\item
  The type $S$ does not have an instance member with the basename $m$,
  and $S$ is neither \DYNAMIC{} nor \code{Never}.

  \commentary{%
    \DYNAMIC{} and \code{Never} are considered to have all members.
    Also, it is an error to access a member on a receiver of type \VOID{}
    (\ref{typeVoid}),
    so extensions are never applicable to receivers of
    any of the types \DYNAMIC, \code{Never}, or \VOID.%
  }

  For the purpose of determining extension applicability,
  function types and the type \code{Function}
  are considered to have a member named \CALL.

  \commentary{%
    Hence, extensions are never applicable to functions
    when the basename of the member is \CALL.
    %
    Instance members declared by the built-in class \code{Object}
    exist on all types,
    so no extension is ever applicable for members with such names.%
  }
\item
  Consider an extension application $a$ of the form \code{$E$($v$)},
  where $v$ is a fresh variable with static type $S$.
  It is required that an occurrence of $a$
  in the scope which is the current scope for $e$
  is not a compile-time error.

  \commentary{%
    In other words, $S$ must match the \ON{} type of $E$.
    With type inference, inferred actual type arguments may be added,
    yielding \code{$E$<\List{S}{1}{k}>($v$)},
    which is then required to not be an error.
    If this inference step fails it is not an error,
    it just means that $E$ is not applicable to $e$.%
  }
\item
  The extension $E$ declares an instance member with basename $m$.
\end{itemize}

\commentary{%
  With type inference:
  The context type of the invocation does not affect
  whether the extension is applicable,
  and neither the context type nor the method invocation affects
  the type inference of $r$,
  but if the extension method itself is generic,
  the context type may affect the member invocation.%
}


\subsubsection{Specificity of an Extension}
\LMLabel{extensionSpecificity}

\LMHash{}%
\BlindDefineSymbol{E_j, k}%
When \List{E}{1}{k}, $k > 1$, are extensions
which are accessible and applicable to a member invocation $e$
(\ref{memberInvocations}),
we define the notion of
\IndexCustom{specificity}{extension!specificity},
which is a partial order on \List{E}{1}{k}.

\commentary{%
  Specificity is used to determine which extension method to execute
  in the situation where more than one choice is possible.%
}

\LMHash{}%
\BlindDefineSymbol{e, r, m}%
Let $e$ be a member invocation with receiver $r$
and correspsonding member name $m$,
\BlindDefineSymbol{E_1, E_2}%
and let $E_1$ and $E_2$ denote two distinct
accessible and applicable extensions for $e$.
\BlindDefineSymbol{T_j, S_j}%
Let $T_j$ be the instantiated \ON{} type of $e$ with respect to $E_j$,
and $S_j$ be the instantiation-to-bound \ON{} type of $e$ with respect to $E_j$,
for $j \in 1 .. 2$
(\ref{explicitExtensionInvocations}).
Then $E_1$ is more specific than $E_2$ with respect to $e$
if at least one of the following conditions is satisfied:

\begin{itemize}
\item
  $E_1$ is not declared in a system library,
  but $E_2$ is declared in a system library.
\item
  $E_1$ and $E_2$ are both declared in a system library,
  or neither of them is declared in a system library, and

  \begin{itemize}
  \item \SubtypeNE{T_1}{T_2}, but not \SubtypeNE{T_2}{T_1}, or
  \item \SubtypeNE{T_1}{T_2}, \SubtypeNE{T_2}{T_1}, and
    \SubtypeNE{S_1}{S_2}, but not \SubtypeNE{S_2}{S_1}.
  \end{itemize}

  \commentary{%
    In other words, the instantiated \ON{} type determines the specificity,
    and the instantiation-to-bound \ON{} type is used as a tie breaker
    in the case where subtyping does not distinguish between the former.%
  }
\end{itemize}

\commentary{%
  The following examples illustrate implicit extension resolution
  when multiple applicable extensions are available.%
}

\begin{dartCode}
\EXTENSION{} ExtendIterable<T> \ON{} Iterable<T> \{
  \VOID{} myForEach(void \FUNCTION(T) f) \{
    \FOR{} (\VAR{} x \IN{} \THIS) f(x);
  \}
\}
\EXTENSION{} ExtendList<T> \ON{} List<T> \{
  \VOID{} myForEach(\VOID{} \FUNCTION(T) f) \{
    \FOR{} (int i = 0; i < length; i++) f(\THIS[i]);
  \}
\}
\\
\VOID{} main() \{
  List<int> x = [1];
  x.myForEach(print);
\}
\end{dartCode}

\commentary{%
  Here both of the extensions apply,
  but \code{ExtendList} is more specific than \code{ExtendIterable} because
  \SubtypeNE{\code{List<int>}}{\code{Iterable<int>}}.%
}

\begin{dartCode}
\EXTENSION{} BestCom<T \EXTENDS{} num> \ON{} Iterable<T> \{ T best() \{...\}\}
\EXTENSION{} BestList<T> \ON{} List<T> \{ T best() \{...\}\}
\EXTENSION{} BestSpec \ON{} List<num> \{ num best() \{...\}\}
\\
\VOID{} main() \{
  List<int> x = ...;
  \VAR{} v = x.best();
  List<num> y = ...;
  \VAR{} w = y.best();
\}
\end{dartCode}

\commentary{%
  Here all three extensions apply to both invocations.
  For \code{x.best()}, \code{BestList} is most specific,
  because \code{List<int>} is a proper subtype of both
  \code{Iterable<int>} and \code{List<num>}.
  Hence, the type of \code{x.best()} is \code{int}.

  For \code{y.best()}, \code{BestSpec} is most specific.
  The instantiated \ON{} types that are compared are
  \code{Iterable<num>} for \code{BestCom} and
  \code{List<num>} for the two other extensions.
  Using the instantiation-to-bound \ON{} types as a tie breaker,
  we find that \code{List<Object>} is less precise than \code{List<num>},
  so \code{BestSpec} is selected.
  Hence, the type of \code{y.best()} is \code{num}.%
}

\rationale{%
  In general, the definition of specificity aims to select
  the extension which has more precise type information available.
  This does not necessarily yield the most precise type of the result
  (for instance, \code{BestSpec.best} could have returned \code{Object}),
  but it is also important that the rule is simple.

  In practice, we expect unintended extension member name conflicts to be rare.
  If the same author is providing more specialized versions of
  an extension for subtypes,
  the choice of an extension which has the most precise types available
  is likely to be a rather unsurprising and useful behavior.%
}


\subsection{Static analysis of Members of an Extension}
\LMLabel{staticAnalysisOfMembersOfAnExtension}

\LMHash{}%
Static analysis of the member declarations in an extension $E$
relies on the scopes of the extension
(\ref{extensions})
and follows the normal rules except for the following:

\LMHash{}%
When static analysis is performed on the body of an instance member
of an extension $E$ with \ON{} type $T_{on}$,
the static type of \THIS{} is $T_{on}$.

\LMHash{}%
A compile-time error occurs if the body of an extension member
contains \SUPER.

\commentary{%
  A lexical lookup in an extension $E$ may yield
  a declaration of an instance method declared in $E$.
  As specified elsewhere
  (\ref{lexicalLookup}),
  this implies that extension instance members
  will shadow class instance members
  when called from another instance member inside the same extension
  using an unqualified function invocation
  (that is, invoking it as \code{m()} and not \code{\THIS.m()},
  \ref{unqualifiedInvocation}).
  %
  This is the only situation where implicit invocation of
  an extension member with basename \id{}
  can succeed even if the interface of the receiver has
  a member with basename \id.
  %
  On the other hand, it is consistent with the general property of Dart that
  lexically enclosing declarations shadow other declarations, e.g.,
  an inherited declaration can be shadowed by a global declaration.
  Here is an example:%
}

\begin{dartCode}
\EXTENSION{} MyUnaryNumber \ON{} List<Object> \{
  bool get isEven => length.isEven;
  bool get isOdd => !isEven;
  static bool isListEven(List<Object> list) => list.isEven;
  List<Object> get first => [];
  List<Object> get smallest => first;
\}
\end{dartCode}

\commentary{%
  With \code{list.isEven},
  \code{isEven} resolves to the declaration in \code{MyUnaryNumber},
  given that \code{List} does not have a member with basename \code{isEven},
  and unless there are any other extensions creating a conflict.

  The use of \code{length} in the declaration of \code{isEven}
  is not defined in the current lexical scope,
  so it is treated as \code{\THIS.length},
  because the interface of the \ON{} type \code{List<Object>} has
  a \code{length} getter.

  The use of \code{isEven} in \code{isOdd} resolves lexically to
  the \code{isEven} getter above it,
  so it is treated as \code{MyUnaryNumber(this).isEven},
  even if there are other extensions in scope
  which define an \code{isEven} on \code{List<Object>}.

  The use of \code{first} in \code{smallest} resolves lexically to
  the \code{first} getter above it,
  even though there is a member with the same basename in
  the interface of \THIS.
  The getter \code{first} cannot be called
  in an implicit invocation from anywhere outside of \code{MyUnaryNumber}.
  This is the exceptional case mentioned above,
  where a member of an extension shadows
  a regular instance member on \THIS.
  In practice, extensions will very rarely introduce members
  with the same basename as a member of its \ON{} type's interface.

  An unqualified identifier \code{id} which is not in scope
  is treated as \code{\THIS.id} inside instance members as usual
  (\ref{lexicalLookup}).
  If \code{id} is not declared by the static type of \THIS{}
  (the \ON{} type)
  then it may be an error,
  or it may be resolved using a different extension.%
}


\subsection{Extension Method Closurization}
\LMLabel{extensionMethodClosurization}

\LMHash{}%
An extension instance method is subject to closurization
in a similar manner as class instance methods
(\ref{superGetterAccessAndMethodClosurization}).

\LMHash{}%
\BlindDefineSymbol{a, E, S_j, e_1}%
Let $a$ be an extension application
(\ref{explicitExtensionInvocations})
of the form \code{$E$<\List{S}{1}{m}>($e_1$)}.
\BlindDefineSymbol{Y_j, m}%
Let \List{Y}{1}{m} be the formal type parameters
of the extension $E$.
%
\BlindDefineSymbol{e, \id}%
An expression $e$ of the form \code{$a$.\id}
where \id{} is an identifier is then known as an
\IndexCustom{extension property extraction}{%
  extension!property extraction}.
It is a compile-time error unless $E$ declares an instance member named \id.
If said instance member is a method then
$e$ has the static type $[S_1/Y_1, \ldots, S_m/Y_m]F$,
where $F$ is the function type of said method declaration.

\commentary{%
  If \id{} is a getter then $e$ is a getter invocation,
  which is specified elsewhere
  (\ref{explicitExtensionInvocations}).%
}

\LMHash{}%
If \id{} is a method then $e$ is known as an
\IndexCustom{instance method closurization}{%
  extension!instance method closurization}
of \id{} on $a$,
and evaluation of $e$
\commentary{(which is \code{$E$<\List{S}{1}{m}>($e_1$).\id})}
proceeds as follows:

\LMHash{}%
Evaluate $e_1$ to an object $o$.
Let $u$ be a fresh final variable bound to $o$.
Then $e$ evaluates to a function object which is equivalent to:

\begin{itemize}
\item
\begin{normativeDartCode}
<\TypeParameters{X}{B'}{s}>
($\PairList{T}{p}{1}{n},\ $\{$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$\}) =>
\quad$E$<\List{S}{1}{m}>($u$)
\quad.\id<\List{X}{1}{s}>($\List{p}{1}{n},\ p_{n+1}$: $p_{n+1}, \ldots,\ p_{n+k}$: $p_{n+k}$);
\end{normativeDartCode}
where \id{} declares type parameters
\TypeParametersStd,
required parameters \List{p}{1}{n},
and named parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k},
using \code{null} for parameters whose default value is not specified.
\item
\begin{normativeDartCode}
<\TypeParameters{X}{B'}{s}>
($\PairList{T}{p}{1}{n},\ $[$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$]) =>
\quad$E$<\List{S}{1}{m}>($u$).\id<\List{X}{1}{s}>(\List{p}{1}{n+k});
\end{normativeDartCode}
where \id{} declares type parameters
\TypeParametersStd,
required parameters \List{p}{1}{n},
and optional positional parameters
\List{p}{n+1}{n+k} with defaults \List{d}{1}{k},
using \code{null} for parameters whose default value is not specified.
\end{itemize}

\LMHash{}%
In the function literals above,
$B'_j = [S_1/Y_1, \ldots, S_m/Y_m]B_j, j \in 1 .. s$,
and $T_j = [S_1/Y_1, \ldots, S_m/Y_m]T'_j, j \in 1 .. n+k$,
where $T'_j$ is the type of the corresponding parameter in
the declaration of \id.
Capture of type variables in \List{S}{1}{m} must be avoided,
so $X_j$ must be renamed if \List{S}{1}{m} contains any occurrences of $X_j$,
for all $j \in 1 .. s$.

\commentary{%
  In other words, the closurization is the value of
  a function literal whose signature is the same as that of \id,
  except that the actual type arguments are substituted for
  the formal type parameters of $E$,
  and then it simply forwards the invocation
  to \id{} with the captured object $u$ as the receiver.%
}

\commentary{%
  Two extension instance method closurizations are never equal
  unless they are identical.
  Note that this differs from closurizations of class instance methods,
  which are equal when they tear off the same method of the same receiver.%
}

\rationale{%
  The reason for this difference is that even if $o_1$ and $o_2$
  are instance method closurizations of the same extension $E$
  applied to the same receiver $o$,
  they may have different actual type arguments passed to $E$,
  because those type arguments are determined by the call site
  (and with inference: by the static type of the expression yielding $o$),
  and not just by the properties of $o$ and the torn-off method.%
}

\commentary{%
  Note that an instance method closurization on an extension is not
  a constant expression,
  even in the case where the receiver is a constant expression.
  This is because it creates a new function object each time it is evaluated.%
}

\LMHash{}%
Extension method closurization can occur for an implicit invocation
of an extension instance member.

\commentary{%
  This is a consequence of the fact that the implicit invocation is
  treated as the corresponding explicit invocation
  (\ref{implicitExtensionInvocations}).
  For instance,
  \code{$e$.\id} may be implicitly transformed into
  \code{$E$<$T_1, T_2$>($e$).\id},
  which is then handled as specified above.%
}

\LMHash{}%
Extension method closurizations are subject to generic function instantiation
(\ref{genericFunctionInstantiation}).
\commentary{For example:}

\begin{dartCode}
\EXTENSION{} \ON{} int \{
  Set<T> asSet<T \EXTENDS{} num>() => \{if (\THIS{} \IS T) \THIS{} \AS{} T\};
\}
\\
\VOID{} main() \{
  Set<double> Function() f = 1.asSet;
  print(f()); // \comment{Prints '\{\}'.}
\}
\end{dartCode}

\commentary{%
  In this example \code{\{\}} is printed,
  because the function object obtained by extension method closurization
  was subject to a generic function instantiation
  which gave \code{T} the value \code{double},
  which makes `\code{\THIS\,\,\IS\,\,T}' evaluate to false.%
}


\subsection{The \CALL{} Member of an Extension}
\LMLabel{theCallMemberOfAnExtension}

\LMHash{}%
An extension can provide a \CALL{} method which is invoked implicitly,
similarly to a function expression invocation
(\ref{functionExpressionInvocation}).

\commentary{%
  E.g., \code{$e$()} is treated as \code{$e$.call()}
  when the static type of $e$ is a non-function that has a method named \CALL.
  Here is an example where the \CALL{} method comes from an extension:%
}

\begin{dartCode}
\EXTENSION{} $E$ \ON{} int \{
  Iterable<int> call(int to) =>
      Iterable<int>.generate(to - this + 1, (i) => this + i);
\}
\\
\VOID{} main() \{
  \FOR{} (\VAR{} i \IN{} 1(3)) print(i); // \comment{Prints 1, 2, 3.}
  \FOR{} (\VAR{} i \IN{} $E$(4)(5)) print(i); // \comment{Prints 4, 5.}
\}
\end{dartCode}

\rationale{%
  This may look somewhat surprising,
  though similar to an approach using \code{\OPERATOR []}:
  \code{\FOR{} (\VAR{} i \IN{} 1[3])\,\,\{\,...\,\}}.
  We expect developers to use this power responsibly.%
}

\LMHash{}%
\BlindDefineSymbol{a, i}%
Let $a$ be an extension application
(\ref{explicitExtensionInvocations}),
and $i$ an expression of the form

\noindent
\code{$a$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}

\noindent
\commentary{(where the type argument list is omitted when $r$ is zero)}.
$i$ is then treated as
(\ref{notation})

\noindent
\code{$a$.\CALL<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}.

\commentary{%
  In other words, an invocation of an extension application
  is immediately treated as an invocation of an extension method named \CALL.%
}

\LMHash{}%
\BlindDefineSymbol{e, S, i}%
Let $e$ be an expression with static type $S$
which is not a property extraction expression
(\ref{propertyExtraction}),
and let $i$ be an expression of the form

\noindent
\code{$e$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}

\noindent
\commentary{(where the type argument list is again omitted when $r$ is zero)}.
If $S$ is \DYNAMIC, \FUNCTION, or a function type,
or the interface of $S$ has a method named \CALL,
$i$ is specified elsewhere
(\ref{functionExpressionInvocation}).
Otherwise, if $S$ has a non-method instance member with basename \CALL{}
then $i$ is a compile-time error.
Otherwise, $i$ is treated as the expression $i'$ which is

\noindent
\code{$e$.\CALL<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)}.

\commentary{%
  Note that $i'$ can be an implicit invocation of
  an extension method named \CALL,
  and it can be an error.
  In the latter case, error messages should be worded in terms of $i$,
  not $i'$.%
}

\LMHash{}%
It is a compile-time error unless $i'$ is an implicit invocation of
an extension instance method named \CALL.

\commentary{%
  In particular, $i'$ cannot be an invocation of an extension getter
  whose return type is a function type, \FUNCTION, or \DYNAMIC.%
}

\commentary{%
  Note that there is no support for an implicit property extraction
  which tears off an extension method named \CALL.
  For instance, assuming the extension $E$ declared in the previous example:%
}

\begin{dartCode}
Iterable<int> \FUNCTION(int) from2 = 2; // \comment{Error.}
\end{dartCode}

\rationale{%
  The implicit property extraction could be allowed,
  but it would come at a readability cost.
  A type like \code{int} is well known as being non-callable,
  and an implicit \code{.call} tear-off would have no visible syntax.
  In an implicit \CALL{} invocation, the arguments are visible to a reader,
  but for an implicit tear-off of a \CALL{} function,
  there is no visible syntax at all.%
}

\commentary{%
  If desired, the property extraction can be expressed explicitly
  using \code{2.\CALL}.%
}


\section{Enums}
\LMLabel{enums}

\LMHash{}%
An \Index{enumerated type}, or \Index{enum}, is used to represent
a fixed number of constant values.

\begin{grammar}
<enumType> ::= \ENUM{} <identifier>
  \gnewline{} `{' <enumEntry> (`,' <enumEntry>)* (`,')? `}'

<enumEntry> ::= <metadata> <identifier>
\end{grammar}

\LMHash{}%
The declaration of an enum of the form
\code{$m$ \ENUM{} $E$ \{$m_0\,\,\id_0, \ldots,\ m_{n-1}\,\,\id_{n-1}$\}}
has the same effect as a class declaration

\begin{normativeDartCode}
$m$ \CLASS{} $E$ \{
\ \ \FINAL{} int index;
\ \ \CONST{} $E$(\THIS.index);
\ \ $m_0$ \STATIC{} \CONST{} $E$ $\id_0$ = \CONST{} $E$(0);
\ \ $\ldots$
\ \ $m_{n-1}$ \STATIC{} \CONST{} $E$ $\id_{n-1}$ = const $E$(n - 1);
\ \ \STATIC{} \CONST{} List<$E$> values = const <$E$>[\id$_0, \ldots, $ \id$_{n-1}$];
\ \ String toString() => \{ 0: `$E$.\id$_0$', $\ldots$, n-1: `$E$.\id$_{n-1}$'\}[index]
\}
\end{normativeDartCode}

\commentary{%
  It is also a compile-time error to subclass, mix-in or implement an enum
  or to explicitly instantiate an enum.
  These restrictions are given in normative form
  in sections \ref{superclasses}, \ref{superinterfaces}, \ref{mixinApplication}
  and \ref{instanceCreation} as appropriate.%
}


\section{Generics}
\LMLabel{generics}

\LMHash{}%
A declaration of a class (\ref{classes}),
mixin (\ref{mixins}),
extension (\ref{extensions}),
type alias (\ref{typedef}),
or function (\ref{functions}) $G$ may be \Index{generic},
that is, $G$ may have formal type parameters declared.

\LMHash{}%
When an entity in this specification is described as generic,
and the special case is considered where the number of type arguments is zero,
the type argument list should be omitted.

\commentary{%
  This allows non-generic cases to be included implicitly as special cases.
  For example,
  an invocation of a non-generic function arises as the special case
  where the function takes zero type arguments,
  and zero type arguments are passed.
  In this situation some operations are also omitted (have no effect), e.g.,
  operations where formal type parameters are replaced by
  actual type arguments.%
}

\LMHash{}%
A \IndexCustom{generic class declaration}{class declaration!generic}
introduces a generic class into the library scope of the current library.
A \IndexCustom{generic class}{class!generic}
is a mapping that accepts a list of actual type arguments
and maps them to a class.
Consider a generic class declaration $G$ named $C$
with formal type parameter declarations
$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$,
and a parameterized type $T$ of the form \code{$C$<$T_1, \ldots,\ T_l$>}.

\LMHash{}%
It is a compile-time error if $m \not= l$.
It is a compile-time error if $T$ is not well-bounded
(\ref{superBoundedTypes}).

\LMHash{}%
Otherwise, said parameterized type \code{$C$<$T_1, \ldots,\ T_m$>} denotes
an application of the generic class declared by $G$ to the type arguments
$T_1, \ldots, T_m$.
This yields a class $C'$ whose members are equivalent to those of
a class declaration which is obtained from the declaration $G$ by replacing
each occurrence of $X_j$ by $T_j$.

\commentary{%
  Other properties of $C'$ such as the subtype relationships
  are specified elsewhere
  (\ref{subtypes}).%
}

\commentary{%
  Generic type aliases are specified elsewhere
  (\ref{typedef}).%
}

\LMHash{}%
A \IndexCustom{generic type}{type!generic} is a type which is introduced by
a generic class declaration or a generic type alias,
or it is the type \code{FutureOr}.

\LMHash{}%
A \IndexCustom{generic function declaration}{function declaration!generic}
introduces a generic function (\ref{formalParameters}) into the current scope.

\LMHash{}%
Consider a function invocation expression of the form
\code{f<$T_1, \ldots,\ T_l$>(\ldots)},
where the static type of \code{f} is a generic function type
with formal type parameters
$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$.
It is a compile-time error if $m \not= l$.
It is a compile-time error if there exists a $j$
such that $T_j$ is not a subtype of $[T_1/X_1, \ldots, T_m/X_m]B_j$.

\commentary{%
  That is, if the number of type arguments is wrong,
  or if the $j$th actual type argument is not a subtype of
  the corresponding bound,
  where each formal type parameter has been replaced by
  the corresponding actual type argument.%
}

\begin{grammar}
<typeParameter> ::= <metadata> <identifier> (\EXTENDS{} <typeNotVoid>)?

<typeParameters> ::= `<' <typeParameter> (`,' <typeParameter>)* `>'
\end{grammar}

\LMHash{}%
A type parameter $T$ may be suffixed with an \EXTENDS{} clause
that specifies the \Index{upper bound} for $T$.
If no \EXTENDS{} clause is present, the upper bound is \code{Object}.
It is a compile-time error if a type parameter is a supertype of its upper bound
when that upper bound is itself a type variable.

\commentary{%
  This prevents circular declarations like
  \code{X \EXTENDS{} X}
  and
  \code{X \EXTENDS{} Y, Y \EXTENDS{} X}.%
}

\LMHash{}%
Type parameters are declared in the type parameter scope of a class or function.
The type parameters of a generic $G$ are in scope in
the bounds of all of the type parameters of $G$.
The type parameters of a generic class declaration $G$ are also in scope in
the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exist)
and in the body of $G$.

\commentary{%
  However, a type parameter of a generic class
  is considered to be a malformed type
  when referenced by a static member
  (\ref{staticTypes}).
  The scopes associated with the type parameters of a generic function
  are described in (\ref{formalParameters}).%
}

\rationale{%
  The restriction on static members is necessary since
  a type variable has no meaning in the context of a static member,
  because statics are shared among
  all generic instantiations of a generic class.
  However, a type variable may be referenced from an instance initializer,
  even though \THIS{} is not available.%
}

\commentary{%
  Because type parameters are in scope in their bounds,
  we support F-bounded quantification.
  This enables typechecking code such as:%
}

\begin{dartCode}
\CLASS{} Ordered<T> \{
  operator >(T x);
\}

\CLASS{} Sorter<T \EXTENDS{} Ordered<T\gtgt{} \{
   sort(List<T> l) \{... l[n] < l[n+1] ...\}
\}

\end{dartCode}

\commentary{%
  Even where type parameters are in scope
  there are numerous restrictions at this time:

  \begin{itemize}
  \item[$\bullet$]
    A type parameter cannot be used to name a constructor in
    an instance creation expression (\ref{instanceCreation}).
  \item[$\bullet$]
    A type parameter cannot be used as a superclass or superinterface
    (\ref{superclasses}, \ref{superinterfaces}, \ref{interfaceSuperinterfaces}).
  \item[$\bullet$]
    A type parameter cannot be used as a generic type.
  \end{itemize}

  The normative versions of these are given
  in the appropriate sections of this specification.
  Some of these restrictions may be lifted in the future.%
}


\subsection{Variance}
\LMLabel{variance}

\LMHash{}%
We say that a type $S$ \Index{occurs covariantly} in a type $T$ if{}f
$S$ occurs in a covariant position in $T$,
but not in a contravariant position,
and not in an invariant position.

\LMHash{}%
We say that a type $S$ \Index{occurs contravariantly} in a type $T$ if{}f
$S$ occurs in a contravariant position in $T$,
but not in a covariant position,
and not in an invariant position.

\LMHash{}%
We say that a type $S$ \Index{occurs invariantly} in a type $T$ if{}f
$S$ occurs in an invariant position in $T$,
or $S$ occurs in a covariant position as well as a contravariant position.

\LMHash{}%
We say that a type $S$ occurs in a \Index{covariant position} in a type $T$
if{}f one of the following conditions is true:

\begin{itemize}
\item $T$ is $S$

\item $T$ is of the form \code{$G$<$S_1,\ \ldots,\ S_n$>}
  where $G$ denotes a generic class
  and $S$ occurs in a covariant position in $S_j$ for some $j \in 1 .. n$.

\item $T$ is of the form
  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots$>($S_1\ x_1, \ldots$)}
  where the type parameter list may be omitted,
  and $S$ occurs in a covariant position in $S_0$.

\item $T$ is of the form

  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots$>}

  \code{\quad($S_1\ x_1, \ldots,\ S_k\ x_k,
    $ [$S_{k+1}\ x_{k+1} = d_{k+1}, \ldots,\ S_n\ x_n = d_n$])}

  \noindent
  or of the form

  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots$>}

  \code{\quad($S_1\ x_1, \ldots,\ S_k\ x_k,
    $ \{$S_{k+1}\ x_{k+1} = d_{k+1}, \ldots,\ S_n\ x_n = d_n$\})}

  \noindent
  where the type parameter list and each default value may be omitted,
  and $S$ occurs in a contravariant position in $S_j$
  for some $j \in 1 .. n$.

\item $T$ is of the form \code{$G$<$S_1, \ldots,\ S_n$>}
  where $G$ denotes a generic type alias such that
  $j \in 1 .. n$,
  the formal type parameter corresponding to $S_j$ is covariant,
  and $S$ occurs in a covariant position in $S_j$.

\item $T$ is of the form \code{$G$<$S_1, \ldots,\ S_n$>}
  where $G$ denotes a generic type alias such that
  $j \in 1 .. n$,
  the formal type parameter corresponding to $S_j$ is contravariant,
  and $S$ occurs in a contravariant position in $S_j$.
\end{itemize}

\LMHash{}%
We say that a type $S$ occurs in a \Index{contravariant position} in a type $T$
if{}f one of the following conditions is true:

\begin{itemize}
\item $T$ is of the form \code{$G$<$S_1,\ \ldots,\ S_n$>}
  where $G$ denotes a generic class
  and $S$ occurs in a contravariant position in $S_j$
  for some $j \in 1 .. n$.

\item $T$ is of the form
  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots$>($S_1\ x_1, \ldots$)}
  where the type parameter list may be omitted,
  and $S$ occurs in a contravariant position in $S_0$.

\item $T$ is of the form

  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots$>}

  \code{\quad($S_1\ x_1, \ldots,\ S_k\ x_k,
    $ [$S_{k+1}\ x_{k+1} = d_{k+1}, \ldots,\ S_n\ x_n = d_n$])}

  \noindent
  or of the form

  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots$>}

  \code{\quad($S_1\ x_1, \ldots,\ S_k\ x_k,
    $ \{$S_{k+1}\ x_{k+1} = d_{k+1}, \ldots,\ S_n\ x_n = d_n$\})}

  \noindent
  where the type parameter list and each default value may be omitted,
  and $S$ occurs in a covariant position in $S_j$
  for some $j \in 1 .. n$.

\item $T$ is of the form \code{$G$<$S_1, \ldots,\ S_n$>}
  where $G$ denotes a generic type alias such that
  $j \in 1 .. n$,
  the formal type parameter corresponding to $S_j$ is covariant,
  and $S$ occurs in a contravariant position in $S_j$.

\item $T$ is of the form \code{$G$<$S_1, \ldots,\ S_n$>}
  where $G$ denotes a generic type alias such that
  $j \in 1 .. n$,
  the formal type parameter corresponding to $S_j$ is contravariant,
  and $S$ occurs in a covariant position in $S_j$.
\end{itemize}

\LMHash{}%
We say that a type $S$ occurs in an \Index{invariant position} in a type $T$
if{}f one of the following conditions is true:

\begin{itemize}
\item $T$ is of the form \code{$G$<$S_1,\ \ldots,\ S_n$>}
  where $G$ denotes a generic class or a generic type alias,
  and $S$ occurs in an invariant position in $S_j$ for some $j \in 1 .. n$.

\item $T$ is of the form

  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$>}

  \code{\quad($S_1\ x_1, \ldots,\ S_k\ x_k,
    $ [$S_{k+1}\ x_{k+1} = d_{k+1}, \ldots,\ S_n\ x_n = d_n$])}

  \noindent
  or of the form

  \code{$S_0$ \FUNCTION<$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$>}

  \code{\quad($S_1\ x_1, \ldots,\ S_k\ x_k,
    $ \{$S_{k+1}\ x_{k+1} = d_{k+1}, \ldots,\ S_n\ x_n = d_n$\})}

  \noindent
  where the type parameter list and each default value may be omitted,
  and $S$ occurs in an invariant position in $S_j$
  for some $j \in 0 .. n$,
  or $S$ occurs in $B_i$
  for some $i \in 1 .. m$.

\item $T$ is of the form \code{$G$<$S_1, \ldots,\ S_n$>}
  where $G$ denotes a generic type alias,
  $j \in 1 .. n$,
  the formal type parameter corresponding to $S_j$ is invariant,
  and $S$ occurs in $S_j$.
\end{itemize}

\LMHash{}%
Consider a generic type alias declaration $G$
with formal type parameter declarations
$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$,
and right hand side $T$.
Let $j \in 1 .. m$.
%
We say that
\IndexCustom{the formal type parameter $X_j$ is invariant}{%
  type parameter!invariant}
if{}f $X_j$ occurs invariantly in $T$, $X_j$
\IndexCustom{is covariant}{type parameter!covariant}
if{}f $X_j$ occurs covariantly in $T$, and $X_j$
\IndexCustom{is contravariant}{type parameter!contravariant}
if{}f $X_j$ occurs contravariantly in $T$.

\rationale{%
  Variance gives a characterization of the way a type varies
  as the value of a subterm varies, e.g., a type variable:
  Assume that $T$ is a type where a type variable $X$ occurs,
  and $L$ and $U$ are types such that $L$ is a subtype of $U$.
  If $X$ occurs covariantly in $T$
  then $[L/X]T$ is a subtype of $[U/X]T$.
  Similarly, if $X$ occurs contravariantly in $T$
  then $[U/X]T$ is a subtype of $[L/X]T$.
  If $X$ occurs invariantly
  then $[L/X]T$ and $[U/X]T$ are not guaranteed
  to be subtypes of each other in any direction.
  In short: with covariance, the type covaries;
  with contravariance, the type contravaries;
  with invariance, all bets are off.%
}


\subsection{Super-Bounded Types}
\LMLabel{superBoundedTypes}

\LMHash{}%
This section describes how
the declared upper bounds of formal type parameters are enforced,
including some cases where a limited form of violation is allowed.

\LMHash{}%
A \Index{top type} is a type $T$ such that \code{Object} is a subtype of $T$.
\commentary{%
  For instance, \code{Object}, \DYNAMIC, and \VOID{} are top types,
  and so are \code{FutureOr<\VOID>} and \code{FutureOr<FutureOr<\DYNAMIC>{}>}.%
}

% We define the property of being regular-bounded for all types,
% being super-bounded for parameterized types, and being well-bounded
% for all types. We require that all types are well-bounded, which
% covers every subterm of a type that is itself a type, and then we
% require that types must be regular-bounded when used in certain
% situations.

\LMHash{}%
Every type which is not a parameterized type is \Index{regular-bounded}.

\commentary{%
  In particular, every non-generic class and every function type
  is a regular-bounded type.%
}

\LMHash{}%
Let $T$ be a parameterized type of the form
\code{$G$<$S_1, \ldots,\ S_n$>}
where $G$ denotes a generic class or a generic type alias.
Let
\code{$X_1\ \EXTENDS\ B_1, \ldots,\ X_n\ \EXTENDS\ B_n$}
be the formal type parameter declarations of $G$.
$T$ is \Index{regular-bounded} if{}f
$S_j$ is a subtype of
$[S_1/X_1, \ldots,\ S_n/X_n]B_j$,
for all $j \in 1 .. n$.

\commentary{%
  This means that regular-bounded types are those types
  that do not violate their type parameter bounds.%
}

\LMHash{}%
Let $T$ be a parameterized type of the form
\code{$G$<$S_1, \ldots,\ S_n$>}
where $G$ denotes a generic class or a generic type alias.
$T$ is \Index{super-bounded} if{}f the following conditions are both true:

\begin{itemize}
\item
  $T$ is not regular-bounded.
\item
  Let $T'$ be the result of replacing every occurrence in $T$
  of a top type in a covariant position by \code{Null},
  and every occurrence in $T$
  of \code{Null} in a contravariant position by \code{Object}.
  It is then required that $T'$ is regular-bounded.
  %
  Moreover, if $G$ denotes a generic type alias with body $U$,
  it is required that every type that occurs as a subterm of
  $[S_1/X_1, \ldots,\ S_n/X_n]U$
  is well-bounded (defined below).
\end{itemize}

\commentary{%
  In short, at least one type argument violates its bound, but the type is
  regular-bounded after replacing all occurrences of an extreme type by an
  opposite extreme type, depending on their variance.%
}

\LMHash{}%
A type $T$ is \Index{well-bounded} if{}f
it is either regular-bounded or super-bounded.

\LMHash{}%
Any use of a type $T$ which is not well-bounded is a compile-time error.

\LMHash{}%
It is a compile-time error if a parameterized type $T$ is super-bounded
when it is used in any of the following ways:

\begin{itemize}
\item $T$ is an immediate subterm of a new expression
  (\ref{new})
  or a constant object expression
  (\ref{const}).
\item $T$ is an immediate subterm of a redirecting factory constructor
  signature
 (\ref{redirectingFactoryConstructors}).
\item $T$ is an immediate subterm of an \EXTENDS{} clause of a class
  (\ref{superclasses}),
  or it occurs as an element in the type list of an \IMPLEMENTS{} clause
  %% TODO(eernst): Come extension types, add ref. Maybe mixin class?
  (\ref{superinterfaces}, \ref{enums}, \ref{mixins}),
  or a \WITH{} clause
  (\ref{classes}, \ref{enums}),
  or it occurs as an element in the type list of an \ON{} clause of a mixin
  (\ref{mixins}).
\end{itemize}

\commentary{%
  It is \emph{not} an error if a super-bounded type occurs
  as an immediate subterm of an \EXTENDS{} clause
  that specifies the bound of a type variable
  (\ref{generics}).%
}

\commentary{%
  Types of members from super-bounded class types are computed using the same
  rules as types of members from other types. Types of function applications
  involving super-bounded types are computed using the same rules as types of
  function applications involving other types. Here is an example:%
}

\begin{dartCode}
\CLASS{} A<X \EXTENDS{} num> \{
  X x;
\}
\\
A<Object> a;
\end{dartCode}

\commentary{%
  With this, \code{a.x} has static type \code{Object},
  even though the upper bound on the type variable \code{X} is \code{num}.%
}

\rationale{%
  Super-bounded types enable the expression of informative common supertypes
  of some sets of types whose common supertypes
  would otherwise be much less informative.%
}

\commentary{%
  For example, consider the following class:%
}

\begin{dartCode}
\CLASS{} C<X \EXTENDS{} C<X>$\!$> \{
  X next;
\}
\end{dartCode}

\commentary{%
  Without super-bounded types,
  there is no type $T$ which makes \code{C<$T$>} a common supertype of
  all types of the form \code{C<$S$>}
  (noting that all types must be regular-bounded
  when we do not have the notion of super-bounded types).
  So if we wish to allow a variable to hold any instance ``of type \code{C}''
  then that variable must use \code{Object} or another top type
  as its type annotation,
  which means that a member like \code{next} is not known to exist
  (which is what we mean by saying that the type is `less informative').%
}

\rationale{%
  We could introduce a notion of recursive (infinite) types, and express
  the least upper bound of all types of the form \code{C<$S$>} as
  some syntax whose meaning could be approximated by
  \code{C<C<C<C<$\ldots$>$\!$>$\!$>$\!$>}.
  %
  However, we expect that any such concept in Dart
  would incur a significant cost
  on developers and implementations
  in terms of added complexity and subtlety,
  so we have chosen not to do that.
  Super-bounded types are finite,
  but they offer a useful developer-controlled approximation
  to such infinite types.%
}

\commentary{%
  For example,
  \code{C<Object>} and
  \code{C<C<C<\VOID>{}>{}>}
  are types that a developer may choose to use as a type annotation.
  This choice serves as a commitment to
  a finite level of unfolding of the infinite type,
  and it allows for a certain amount of control
  at the point where the unfolding ends:
  %
  If \code{c} has type \code{C<C<\DYNAMIC>{}>}
  then \code{c.next.next} has type \DYNAMIC{}
  and \code{c.next.next.whatever} has no compile-time error,
  but if \code{c} has type \code{C<C<\VOID>{}>} then already
  \code{Object x = c.next.next;} is a compile-time error.
  It is thus possible for developers to get a more or less strict treatment
  of expressions whose type proceeds beyond the given finite unfolding.%
}


\subsection{Instantiation to Bound}
\LMLabel{instantiationToBound}

\LMHash{}%
This section describes how to compute type arguments
that are omitted from a type,
or from an invocation of a generic function.

\commentary{%
  %% TODO(eernst): When we add a specification of type inference, we will adjust
  %% the specification of i2b such that it allows for taking initial values for
  %% the actual type arguments (that is, $U_{j,0}$ is given "from the caller"
  %% for some $j$; probably "the caller" will always be type inference), and
  %% all other parts of the algorithm remain unchanged.
  %% I think it will be more confusing than helpful to start writing this now,
  %% and it will be a small adjustment when we add a spec of type inference. So
  %% at this point we just specify i2b as a stand-alone algorithm.
  Note that type inference is assumed to have taken place already
  (\ref{overview}),
  so type arguments are not considered to be omitted if they are inferred.
  This means that instantiation to bound is a backup mechanism,
  which will be used when no information is available for inference.%
}

\LMHash{}%
Consider the situation where a term $t$ of the form \synt{typeName}
denotes a generic type declaration,
and it is used as a type or as an expression in the enclosing program.
\commentary{%
  This implies that type arguments are accepted, but not provided.%
}
We use the phrase
\Index{raw type} respectively \Index{raw type expression}
to identify such terms.
In the following we only mention raw types,
but everything said about raw types
applies to raw type expressions in the obvious manner.

\commentary{%
  For instance, with the declaration \code{Type listType() => List;},
  evaluation of the raw type expression \code{List} in the body yields
  an instance of class \code{Type} reifying \code{List<dynamic>},
  because \code{List} is subject to instantiation to bound.
  Note that \code{List<dynamic>} is not syntactically an expression,
  but it is still possible to get access to
  a \code{Type} instance reifying \code{List<dynamic>}
  without instantiation to bound,
  because it can be the value of a type variable.%
}

\rationale{%
  We can unambiguously define raw types to denote
  the result of applying the generic type
  to a list of implicitly provided actual type arguments,
  and instantiation to bound is a mechanism which does just that.
  This is because Dart does not, and will not, support higher-kinded types;
  for example, the value of a type variable $X$ will be a type,
  it cannot be the generic class \code{List} as such,
  and it cannot be applied to type arguments, e.g., \code{$X$<int>}.%
}

\rationale{%
  In the typical case where only covariance is encountered,
  instantiation to bound will yield a \emph{supertype} of
  all the regular-bounded types that can be expressed.
  This allows developers to consider a raw type as a type
  which is used to specify that
  ``the actual type arguments do not matter''$\!$.%
}
\commentary{%
  For example, assuming the declaration
  \code{\CLASS{} C<X extends num> \{\ldots\}},
  instantiation to bound on \code{C} yields \code{C<num>},
  and this means that \code{C x;} can be used to declare a variable \code{x}
  whose value can be a \code{C<$T$>} for \emph{all possible} values of $T$.%
}

\rationale{%
  Conversely, consider the situation where
  a generic type alias denotes a function type,
  and it has one type parameter which is contravariant.
  Instantiation to bound on that type alias will then yield a \emph{subtype} of
  all the regular-bounded types that can be expressed
  by varying that type argument.
  This allows developers to consider such a type alias used as a raw type
  as a function type which allows the function to be passed to clients
  ``where it does not matter which values
  for the type argument the client expects''$\!$.%
}
\commentary{%
  E.g., with
  \code{\TYPEDEF{} F<X> = \FUNCTION(X);}
  instantiation to bound on \code{F} yields \code{F<dynamic>},
  and this means that \code{F f;} can be used to declare a variable \code{f}
  whose value will be a function that can be passed to clients expecting
  an \code{F<$T$>} for \emph{all possible} values of $T$.%
}


\subsubsection{Auxiliary Concepts for Instantiation to Bound}
\LMLabel{auxiliaryConceptsForInstantiationToBound}

\LMHash{}%
Before we specify instantiation to bound
we need to define two auxiliary concepts.
Let $T$ be a raw type.
A type $S$ then
\IndexCustom{raw-depends on}{raw-depends on!type}
$T$ if one or more of the following conditions hold:

\begin{itemize}
\item
  $S$ is of the form \synt{typeName}, and $S$ is $T$.
  \commentary{%
    Note that this case is not applicable
    if $S$ is a subterm of a term of the form
    \syntax{$S$ <typeArguments>},
    that is,
    if $S$ receives any type arguments.
    Also note that $S$ cannot be a type variable,
    because then `$S$ is $T$' cannot hold.
    See the discussion below and the reference to~\ref{subtypeRules}
    for more details about why this is so.%
  }
\item
  $S$ is of the form \syntax{<typeName> <typeArguments>},
  and one of the type arguments raw-depends on $T$.
\item
  $S$ is of the form \syntax{<typeName> <typeArguments>?}\ where
  \synt{typeName} denotes a type alias $F$,
  and the body of $F$ raw-depends on $T$.
\item
  $S$ is of the form
  \syntax{<type>? \FUNCTION{} <typeParameters>? <parameterTypeList>} and
  \syntax{<type>?}\ raw-depends on $T$,
  or a bound in \syntax{<typeParameters>?}\ raw-depends on $T$,
  or a type in \synt{parameterTypeList} raw-depends on $T$.
\end{itemize}

\commentary{%
  Meta-variables
  (\ref{metaVariables})
  like $S$ and $T$ are understood to denote types,
  and they are considered to be equal (as in `$S$ is $T$')
  in the same sense as in the section about subtype rules
  (\ref{subtypeRules}).
  %
  In particular,
  even though two identical pieces of syntax may denote two distinct types,
  and two different pieces of syntax may denote the same type,
  the property of interest here is whether they denote the same type
  and not whether they are spelled identically.

  The intuition behind the situation where a type raw-depends on another type is
  that we need to compute any missing type arguments for the latter
  in order to be able to tell what the former means.

  In the rule about type aliases, $F$ may or may not be generic,
  and type arguments may or may not be present.
  However, there is no need to consider the result of substituting
  actual type arguments for formal type parameters in the body of $F$
  (or even the correctness of passing those type arguments to $F$),
  because we only need to inspect
  all types of the form \synt{typeName} in its body,
  and they are not affected by such a substitution.
  In other words, raw-dependency is a relation
  which is simple and cheap to compute.%
}

\LMHash{}%
Let $G$ be a generic class or a generic type alias
with $k$ formal type parameter declarations
containing formal type parameters \List{X}{1}{k} and bounds \List{B}{1}{k}.
For any $j \in 1 .. k$,
we say that the formal type parameter $X_j$ has a \Index{simple bound}
when one of the following requirements is satisfied:

\begin{itemize}
\item $B_j$ is omitted.

\item $B_j$ is included, but does not contain any of \List{X}{1}{k}.
  If $B_j$ raw-depends on a raw type $T$
  then every type parameter of $T$ must have a simple bound.
\end{itemize}

\LMHash{}%
The notion of a simple bound must be interpreted inductively rather than
coinductively, i.e., if a bound $B_j$ of a generic class or
generic type alias $G$ is reached during an investigation of whether
$B_j$ is a simple bound, the answer is no.

\commentary{%
  For example, with
  \code{\CLASS{} C<X \EXTENDS{} C> \{\}},
  the type parameter \code{X} does not have a simple bound:
  A raw \code{C} is used as a bound for \code{X},
  so \code{C} must have simple bounds,
  but one of the bounds of \code{C} is the bound of \code{X},
  and that bound is \code{C}, so \code{C} must have simple bounds:
  That was a cycle, so the answer is ``no'',
  \code{C} does not have simple bounds.%
}

\LMHash{}%
Let $G$ be a generic class or a generic type alias.
We say that $G$
\IndexCustom{has simple bounds}{type!generic, has simple bounds}
if{}f every type parameter of $G$ has simple bounds.

\commentary{%
  We can now specify in which sense instantiation to bound requires
  the involved types to be "simple enough".
  We impose the following constraint on all type parameter bounds,
  because all type parameters may be subject to instantiation to bound.%
}

\LMHash{}%
It is a compile-time error
if a formal type parameter bound $B$ contains a raw type $T$,
unless $T$ has simple bounds.

\commentary{%
  So type arguments on bounds can only be omitted
  if they themselves have simple bounds.
  In particular,
  \code{\CLASS{} C<X \EXTENDS{} C> \{\}}
  is a compile-time error,
  because the bound \code{C} is raw,
  and the formal type parameter \code{X}
  that corresponds to the omitted type argument
  does not have a simple bound.%
}

\LMHash{}%
Let $T$ be a type of the form \synt{typeName}
which denotes a generic class or a generic type alias
\commentary{(so $T$ is raw)}.
Then $T$ is equivalent to the parameterized type which is
the result obtained by applying instantiation to bound to $T$.
It is a compile-time error if the instantiation to bound fails.

\commentary{%
  This rule is applicable for all occurrences of raw types,
  e.g., when it occurs as a type annotation of a variable or a parameter,
  as a return type of a function,
  as a type which is tested in a type test,
  as the type in an \synt{onPart},
  etc.%
}


\subsubsection{The Instantiation to Bound Algorithm}
\LMLabel{theInstantiationToBoundAlgorithm}

\LMHash{}%
We now specify how the
\Index{instantiation to bound}
algorithm proceeds.
Let $T$ be a raw type.
Let \List{X}{1}{k} be the formal type parameters in the declaration of $G$,
and let \List{B}{1}{k} be their bounds.
For each $i \in 1 .. k$,
let $S_i$ denote the result of instantiation to bound on $B_i$;
in the case where the $i$th bound is omitted, let $S_i$ be \DYNAMIC.

\commentary{%
  If $B_i$ for some $i$ is raw (in general: if it raw-depends on some type $U$)
  then all its (respectively $U$'s) omitted type arguments have simple bounds.
  This limits the complexity of instantiation to bound for $B_i$,
  and in particular it cannot involve a dependency cycle
  where we need the result from instantiation to bound for $G$
  in order to compute the instantiation to bound for $G$.%
}

\LMHash{}%
Let $U_{i,0}$ be $S_i$, for all $i \in 1 .. k$.
\commentary{%
  This is the "current value" of the bound for type variable $i$, at step 0;
  in general we will consider the current step, $m$, and use data for that step,
  e.g., the bound $U_{i,m}$, to compute the data for step $m + 1$.%
}

{ %% Scope for definitions of relations used during i2b

\def\Depends{\ensuremath{\rightarrow_m}}
\def\TransitivelyDepends{\ensuremath{\rightarrow^{+}_m}}

\LMHash{}%
Let \Depends{} be a relation among the type variables
\List{X}{1}{k} such that
$X_p \Depends X_q$ iff $X_q$ occurs in $U_{p,m}$.
\commentary{%
  So each type variable is related to, that is, depends on,
  every type variable in its bound, which might include itself.%
}
Let \TransitivelyDepends{} be the transitive
\commentary{(but not reflexive)}
closure of \Depends.
For each $m$, let $U_{i,m+1}$, for $i \in 1 .. k$,
be determined by the following iterative process, where $V_m$ denotes
\code{$G$<$U_{1,m},\ \ldots,\ U_{k,m}$>}:

\begin{itemize}
\item[1.]
  If there exists a $j \in 1 .. k$ such that
  $X_j \TransitivelyDepends X_j$
  \commentary{(that is, if the dependency graph has a cycle)}
  let \List{M}{1}{p} be the strongly connected components (SCCs)
  with respect to \Depends.
  \commentary{%
    That is, the maximal subsets of \List{X}{1}{k}
    where every pair of variables in each subset
    are related in both directions by \TransitivelyDepends;
    note that the SCCs are pairwise disjoint;
    also, they are uniquely defined up to reordering,
    and the order does not matter for this algorithm.%
  }
  Let $M$ be the union of \List{M}{1}{p}
  \commentary{(that is, all variables that participate in a dependency cycle)}.
  Let $i \in 1 .. k$.
  If $X_i$ does not belong to $M$ then $U_{i,m+1}$ is $U_{i,m}$.
  Otherwise there exists a $q$ such that $X_i \in M_q$;
  $U_{i,m+1}$ is then obtained from $U_{i,m}$
  by substituting \DYNAMIC{} for every occurrence of a variable in $M_q$
  that is in a position in $V_m$ which is not contravariant,
  and substituting \code{Null} for every occurrence of a variable in $M_q$
  which is in a contravariant position in $V_m$.

\item[2.]
  Otherwise
  \commentary{(when there are no dependency cycles)},
  let $j$ be the lowest number such that $X_j$ occurs in $U_{p,m}$ for some $p$
  and $X_j \not\rightarrow_m X_q$ for all $q$ in $1 .. k$
  \commentary{%
    (that is, the bound of $X_j$ does not contain any type variables,
    but $X_j$ occurs in the bound of some other type variable)%
  }.
  Then, for all $i \in 1 .. k$,
  $U_{i,m+1}$ is obtained from $U_{i,m}$
  by substituting $U_{j,m}$ for every occurrence of $X_j$
  that is in a position in $V_m$ which is not contravariant,
  and substituting \code{Null} for every occurrence of $X_j$
  which is in a contravariant position in $V_m$.

\item[3.]
  Otherwise
  \commentary{(when there are no dependencies at all)},
  terminate with the result \code{<$U_{1,m},\ \ldots,\ U_{k,m}$>}.
\end{itemize}

\commentary{%
  This process will always terminate, because the total number of
  occurrences of type variables from $\{\,\List{X}{1}{k}\,\}$ in
  the current bounds is strictly decreasing with each step, and we terminate
  when that number reaches zero.%
}

\rationale{%
  It may seem somewhat arbitrary to treat unused and invariant parameters
  in the same way as covariant parameters,
  in particular because invariant parameters fail
  to satisfy the expectation that
  a raw type denotes a supertype of all the expressible regular-bounded types.

  We could easily have made every instantiation to bound an error
  when applied to a type where invariance occurs anywhere
  during the run of the algorithm.
  However, there are a number of cases where this choice produces a usable type,
  and we decided that it is not helpful to outlaw such cases.%
}

\begin{dartCode}
\TYPEDEF{} Inv<X> = X \FUNCTION(X);
\CLASS{} B<Y \EXTENDS{} num, Z \EXTENDS{} Inv<Y>{}> \{\}
\\
B b; // \comment{The raw B means} B<num, Inv<num>{}>.
\end{dartCode}

\commentary{%
  For example, the value of \code{b} can have dynamic type
  \code{B<int,\,int\,\FUNCTION(num)>}.
  However, the type arguments have to be chosen carefully,
  or the result will not be a subtype of \code{B}.
  For instance, \code{b} cannot have dynamic type
  \code{B<int, Inv<int>{}>},
  because \code{Inv<int>} is not a subtype of \code{Inv<num>}.%
}

\LMHash{}%
A raw type $T$ is a compile-time error if instantiation to bound on $T$
yields a type which is not well-bounded
(\ref{superBoundedTypes}).

\commentary{%
  This kind of error can occur, as demonstrated by the following example:%
}

\begin{dartCode}
\CLASS{} C<X \EXTENDS{} C<X>{}> \{\}
\TYPEDEF{} F<X \EXTENDS{} C<X>{}> = X \FUNCTION(X);
\\
F f; // \comment{Compile-time error.}
\end{dartCode}

\commentary{%
  With these declarations,
  the raw \code{F} which is used as a type annotation is a compile-time error:
  The algorithm yields \code{F<C<\DYNAMIC{}>{}>},
  and that is neither a regular-bounded nor a super-bounded type.
  %
  The resulting type can be specified explicitly as
  \code{C<\DYNAMIC{}> \FUNCTION(C<\DYNAMIC{}>)}.
  That type exists,
  we just cannot express it by passing a type argument to \code{F},
  so we make it an error rather than allowing it implicitly.%
}

\rationale{%
  The core reason why it makes sense to make such a raw type an error
  is that there is no subtype relationship
  between the relevant parameterized types.%
}
\commentary{%
  For instance, \code{F<T1>} and \code{F<T2>} are unrelated,
  even when \SubtypeNE{\code{T1}}{\code{T2}} or vice versa.
  In fact, there is no type \code{T} whatsoever
  such that a variable with declared type \code{F<T>}
  could be assigned to a variable of type
  \code{C<\DYNAMIC{}> \FUNCTION(C<\DYNAMIC{}>)}.
%
So the raw \code{F}, if permitted,
would not be ``a supertype of \code{F<T>} for all possible \code{T}'',
it would be a type which is unrelated to \code{F<T>}
for \emph{every single} \code{T} that satisfies the bound of \code{F}.
This is so useless that we made it an error.%
}

\LMHash{}%
When instantiation to bound is applied to a type, it proceeds recursively:
For a parameterized type \code{$G$<\List{T}{1}{k}>}
it is applied to \List{T}{1}{k}.
For a function type
\FunctionTypePositionalStd{T_0}

\noindent
and a function type
\FunctionTypeNamedStd{T_0}
it is applied to \List{T}{0}{n+k}.

\commentary{%
  This means that instantiation to bound has no effect on
  a type that does not contain any raw types.
  Conversely, instantiation to bound acts on types which are syntactic subterms,
  also when they are deeply nested.%
}

\LMHash{}%
\IndexCustom{Instantiation to bound on a generic function $f$}{%
  generic function!instantiation to bound}
also uses the algorithm described above,
taking the formal parameters \List{X}{1}{k} from the declaration of $f$,
with bounds \List{B}{1}{k}, and,
for each $i \in 1 .. k$,
letting $S_i$ denote the result of instantiation to bound on $B_i$,
and letting $S_i$ be \DYNAMIC{} when the $i$th bound is omitted.

\LMHash{}%
Let $f$ be a generic function declaration.
If instantiation to bound on $f$ yields
a list of type arguments \List{T}{1}{k} such that,
for some $j \in 1..k$,
$T_j$ is or contains a type which is not well-bounded,
or if \List{T}{1}{k} does not satisfy the bounds
on the formal type parameters of $f$,
then we say that
\IndexCustom{$f$ does not have default type arguments}{%
  generic function!does not have default type arguments}.


\section{Metadata}
\LMLabel{metadata}

\LMHash{}%
Dart supports metadata which is used to attach
user defined annotations to program structures.

\begin{grammar}
<metadata> ::= (`@' <metadatum>)*

<metadatum> ::= \gnewline{}
  <identifier> | <qualifiedName> | <constructorDesignation> <arguments>
\end{grammar}

\LMHash{}%
Metadata consists of a series of annotations,
each of which begin with the character \lit{@},
followed by a constant expression $e$ derivable from
\synt{metadatum}.
It is a compile-time error if $e$ is not one of the following:

\begin{itemize}
\item A reference to a constant variable.
\item A call to a constant constructor.
\end{itemize}

\commentary{%
  The expression $e$ occurs in a constant context
  (\ref{constantContexts}),
  which means that \CONST{} modifiers need not be specified explicitly.%
}

\LMHash{}%
Metadata that occurs as the first element of
the right hand side of a grammar rule
is associated with the abstract syntax tree for the non-terminal
on the left hand side of said grammar rule
\commentary{(that is, it is associated with its parent)}.
Otherwise, metadata is associated with the abstract syntax tree
of the program construct $p$ that immediately follows the metadata
in the grammar rule.

\rationale{%
  These rules are intended to ensure a minimal level of consistency
  in the association that binds each metadatum to a program construct.
  The structure of the abstract syntax tree is implementation specific,
  and it is not even guaranteed that a tool will use anything
  which is known as an abstract syntax tree.
  In that case the phrase `abstract syntax tree' should be interpreted as
  the program representation entities which are actually used.

  This implies that the fine details of the association between metadata
  and an abstract syntax tree node is also implementation specific.
  In particular, an implementation can choose to associate a given metadatum
  with more than one abstract syntax tree node.%
}

\LMHash{}%
Metadata can be retrieved at run time via a reflective call,
provided the annotated program construct $p$ is accessible via reflection.

\commentary{%
  Obviously, metadata can also be retrieved statically by
  parsing the program and evaluating the constants via a suitable interpreter.
  In fact, many if not most uses of metadata are entirely static.
  In this case the binding of each metadatum to an abstract syntax tree node
  is determined by the given static analysis tool,
  which is of course not subject to any constraints in this document.
  Surely it will still be useful to strive for consistency among all tools
  with respect to the binding from metadata to abstract syntax tree nodes.%
}

\rationale{%
  It is important that no run-time overhead be incurred by
  the introduction of metadata that is not actually used.
  Because metadata only involves constants,
  the time at which it is computed is irrelevant.
  So implementations may skip the metadata
  during ordinary parsing and execution,
  and evaluate it lazily.%
}

\commentary{%
  It is possible to associate metadata with constructs
  that may not be accessible via reflection,
  such as local variables
  (though it is conceivable that in the future,
  richer reflective libraries might provide access to these as well).
  This is not as useless as it might seem.
  As noted above, the data can be retrieved statically
  if source code is available.%
}

\LMHash{}%
Metadata can appear before a library, part header, class,
typedef, type parameter, constructor, factory, function,
parameter, or variable declaration,
and before an import, export, or part directive.

\LMHash{}%
The constant expression given in an annotation is type checked and evaluated
in the scope surrounding the declaration being annotated.


\section{Expressions}
\LMLabel{expressions}

\LMHash{}%
An \Index{expression} is a fragment of Dart code
that can be evaluated at run time.

\LMHash{}%
Every expression has an associated static type (\ref{staticTypes}) and
may have an associated static context type
%% TODO(eernst): This ref is undefined until CL 92782 is landed.
%% (\ref{contextTypes}),
which may affect the static type and evaluation of the expression.
Every object has an associated dynamic type (\ref{dynamicTypeSystem}).

%% TODO(eernst): <expression> should derive <functionExpression> as well,
%% the fact that it is currently derived from <primary> induces a genuine
%% and serious source of ambiguity, which makes it difficult to parse Dart
%% using anything other than a modified recursive descent parser.

\begin{grammar}
<expression> ::= <assignableExpression> <assignmentOperator> <expression>
  \alt <conditionalExpression>
  \alt <cascade>
  \alt <throwExpression>

<expressionWithoutCascade> ::= \gnewline{}
  <assignableExpression> <assignmentOperator> <expressionWithoutCascade>
  \alt <conditionalExpression>
  \alt <throwExpressionWithoutCascade>

<expressionList> ::= <expression> (`,' <expression>)*

<primary> ::= <thisExpression>
  \alt \SUPER{} <unconditionalAssignableSelector>
  \alt \SUPER{} <argumentPart>
  \alt <functionExpression>
  \alt <literal>
  \alt <identifier>
  \alt <newExpression>
  \alt <constObjectExpression>
  \alt <constructorInvocation>
  \alt `(' <expression> `)'

<literal> ::= <nullLiteral>
  \alt <booleanLiteral>
  \alt <numericLiteral>
  \alt <stringLiteral>
  \alt <symbolLiteral>
  \alt <listLiteral>
  \alt <setOrMapLiteral>
\end{grammar}

\LMHash{}%
An expression $e$ may always be enclosed in parentheses,
but this never has any semantic effect on $e$.

\commentary{%
  However, it may have an effect on the surrounding expression.
  For instance, given a class \code{C} with a static method
  \code{m() => 42}, \code{C.m()} returns 42,
  but \code{(C).m()} is a compile-time error.
  %
  The point is that the meaning of \code{C.m()}
  is specified in terms of several parts,
  rather than being specified in a strictly compositional manner.
  Concretely, the meaning of \code{C} and \code{(C)} as expressions is the same,
  but the meaning of \code{C.m()} is not defined in terms of
  the meaning of \code{C} as an expression,
  and it differs from the meaning of \code{(C).m()}.%
  % A strictly compositional evaluation would always evaluate every
  % subexpression using the same rules (`evaluation` is always the same thing),
  % and then it would combine the evaluation results into the result of the
  % whole expression. We won't expand on that here, and in particular we won't
  % discuss whether compositional evaluation is even meaningful in the context
  % of side-effects. But it's still useful to keep in mind that we have these
  % "highly non-compositional" elements in the semantics, such as static
  % method lookups.
}


\subsection{Expression Evaluation}
\LMLabel{expressionEvaluation}

\LMHash{}%
Evaluation of an expression either
\IndexCustom{produces an object}{expression!produces an object}
or it
\IndexCustom{throws}{expression!throws}
an exception object and an associated stack trace.
In the former case, we also say that the expression
\NoIndex{evaluates to an object}.

\LMHash{}%
If evaluation of one expression, $e$,
is defined in terms of evaluation of another expression $e_1$,
typically a subexpression of $e$,
and the evaluation of $e_1$ throws an exception and a stack trace,
the evaluation of $e$ stops at that point
and throws the same exception object and stack trace.


\subsection{Object Identity}
\LMLabel{objectIdentity}

\LMHash{}%
The predefined Dart function \code{identical()}
is defined such that \code{identical($c_1$, $c_2$)} if{}f:

\begin{itemize}
\item $c_1$ evaluates to either the null object (\ref{null})
  or an instance of \code{bool} and \code{$c_1$ == $c_2$}, OR
\item $c_1$ and $c_2$ are instances of \code{int} and \code{$c_1$ == $c_2$}, OR
\item $c_1$ and $c_2$ are constant strings and \code{$c_1$ == $c_2$}, OR
\item $c_1$ and $c_2$ are instances of \code{double}
  and one of the following holds:

  \begin{itemize}
  \item $c_1$ and $c_2$ are non-zero and \code{$c_1$ == $c_2$}.
  \item Both $c_1$ and $c_2$ are $+0.0$.
  \item Both $c_1$ and $c_2$ are $-0.0$.
  \item Both $c_1$ and $c_2$ represent a NaN value
    with the same underlying bit pattern.
  \end{itemize}
 OR
\item $c_1$ and $c_2$ are constant lists that are defined to be identical
  in the specification of literal list expressions (\ref{lists}), OR
\item $c_1$ and $c_2$ are constant maps that are defined to be identical
  in the specification of literal map expressions (\ref{maps}), OR
\item $c_1$ and $c_2$ are constant objects of the same class $C$
  and the value of each instance variable of $c_1$ is identical to
  the value of the corresponding instance variable of $c_2$. OR
\item $c_1$ and $c_2$ are the same object.
\end{itemize}

\commentary{%
  The definition of \code{identity} for doubles differs from that of equality
  in that a NaN is identical to itself,
  and that negative and positive zero are distinct.%
}

\rationale{%
  The definition of equality for doubles is dictated by the IEEE 754 standard,
  which posits that NaNs do not obey the law of reflexivity.
  Given that hardware implements these rules,
  it is necessary to support them for reasons of efficiency.

  The definition of identity is not constrained in the same way.
  Instead, it assumes that bit-identical doubles are identical.

  The rules for identity make it impossible for a Dart programmer
  to observe whether a boolean or numerical value is boxed or unboxed.%
}


\subsection{Constants}
\LMLabel{constants}

\commentary{%
  All usages of 'constant' in Dart are associated with compile time.
  A potentially constant expression is an expression that will generally yield
  a constant value when the values of certain parameters are given.
  The constant expressions is a subset of the potentially constant expressions
  that \emph{can} be evaluated at compile time.%
}

\rationale{%
  The constant expressions are restricted to expressions that
  perform only simple arithmetic operations, boolean conditions,
  and string and instance creation.
  No user-written function body is executed
  during constant expression evaluation,
  only members of the system classes
  \code{Object}, \code{bool}, \code{int}, \code{double},
  \code{String}, \code{Type}, \code{Symbol}, or \code{Null}.%
}

\LMHash{}%
The \IndexCustom{potentially constant expressions}{%
  potentially constant expression}
and \IndexCustom{constant expressions}{constant expression}
are the following:

\begin{itemize}
\item
  A literal boolean, \TRUE{} or \FALSE{} (\ref{booleans}),
  is a potentially constant and constant expression.

\item
  A literal number (\ref{numbers}) is
  a potentially constant and constant expression
  if it evaluates to an instance of type \code{int} or \code{double}.
  % A too-large integer literal does not evaluate to an object.

\item A literal string (\ref{strings}) with string interpolations
  (\ref{stringInterpolation})
  with expressions $e_1$, \ldots, $e_n$ is a potentially constant expression
  if $e_1$, \ldots, $e_n$ are potentially constant expressions.
  The literal is further a constant expression
  if $e_1$, \ldots, $e_n$ are constant expressions
  evaluating to instances of \code{int}, \code{double},
  \code{String}, \code{bool}, or \code{Null}.
  \commentary{%
    These requirements hold trivially
    if there are no interpolations in the string.%
  }
  \rationale{%
    It would be tempting to allow string interpolation where the
    interpolated value is any compile-time constant.
    However, this would require running the \code{toString()} method
    for constant objects,
    which could contain arbitrary code.%
  }

\item
  A literal symbol (\ref{symbols}) is
  a potentially constant and constant expression.

\item
  The literal \NULL{} (\ref{null}) is
  a potentially constant and constant expression.

\item
  An identifier that denotes a constant variable is
  a potentially constant and constant expression.

\item
  A qualified reference to a static constant variable
  (\ref{variables})
  that is not qualified by a deferred prefix,
  is a potentially constant and constant expression.
  \commentary{%
    For example, if class $C$ declares a constant static variable $v$,
    \code{$C$.$v$} is a constant.
    The same is true if $C$ is accessed via a prefix $p$;
    \code{$p$.$C$.$v$} is a constant unless $p$ is a deferred prefix.%
  }

\item
  A simple or qualified identifier denoting a class,
  a mixin or a type alias that is not qualified by a deferred prefix,
  is a potentially constant and constant expression.
  \commentary{%
    The constant expression always evaluates to a \code{Type} object.
    For example, if $C$ is the name of a class or type alias,
    the expression \code{$C$} is a constant,
    and if $C$ is imported with a prefix $p$, \code{$p$.$C$} is
    a constant \code{Type} instance representing the type of $C$
    unless $p$ is a deferred prefix.%
  }

\item
  Let $e$ be a simple or qualified identifier denoting
  a top-level function (\ref{functions})
  or a static method (\ref{staticMethods})
  that is not qualified by a deferred prefix.
  If $e$ is not subject to generic function instantiation
  (\ref{genericFunctionInstantiation})
  then $e$ is a potentially constant and constant expression.
  If generic function instantiation does apply to $e$
  and the provided actual type arguments are \List{T}{1}{s}
  then $e$ is a potentially constant and constant expression
  if{}f each $T_j, j \in 1 .. s$, is a constant type expression
  (\ref{constants}).

\item
  An identifier expression denoting a parameter of a constant constructor
  (\ref{constantConstructors})
  that occurs in the initializer list of the constructor,
  is a potentially constant expression.

\item
  A constant object expression (\ref{const})
  is a potentially constant and constant expression.

\item
  A constant list literal (\ref{lists})
  is a potentially constant and constant expression.

\item
  A constant set literal (\ref{sets})
  is a potentially constant and constant expression.

\item
  A constant map literal (\ref{maps})
  is a potentially constant and constant expression.

\item
  A parenthesized expression \code{($e$)} is
  a potentially constant expression
  if $e$ is a potentially constant expression.
  It is further a constant expression if $e$ is a constant expression.

\item
  An expression of the form \code{identical($e_1$, $e_2$)} is
  a potentially constant expression
  if $e_1$ and $e_2$ are potentially constant expressions
  and \code{identical} is statically bound to
  the predefined dart function \code{identical()} discussed above
  (\ref{objectIdentity}).
  It is further a constant expression
  if $e_1$ and $e_2$ are constant expressions.

\item
  An expression of the form \code{$e_1$\,!=\,$e_2$} is
  equivalent to \code{!($e_1$\,==\,$e_2$)} in every way,
  including whether it is potentially constant or constant.

\item
  An expression of the form \code{$e_1$\,==\,$e_2$} is potentially constant
  if $e_1$ and $e_2$ are both potentially constant expressions.
  It is further constant if both $e_1$ and $e_2$ are constant, and
  either $e_1$ evaluates to an instance of \code{double}
  or an instance that that has primitive equality
  (\ref{theOperatorEqualsEquals}),
  or $e_2$ evaluates to the null object
  (\ref{null}).

\item
  An expression of the form \code{!$e_1$} is potentially constant
  if $e_1$ is potentially constant.
  It is further constant if $e_1$ is a constant expression that evaluates to
  an instance of type \code{bool}.

\item
  An expression of the form \code{$e_1$\,\&\&\,$e_2$} is
  potentially constant if $e_1$ and $e_2$
  are both potentially constant expressions.
  It is further constant if $e_1$ is a constant expression and either
  \begin{enumerate}
  \item $e_1$ evaluates to \FALSE, or
  \item $e_1$ evaluates to \TRUE{} and $e_2$ is a constant expression
    that evaluates to an instance of type \code{bool}.
  \end{enumerate}

\item
  An expression of the form \code{$e_1$\,||\,$e_2$} is
  potentially constant if $e_1$ and $e_2$
  are both potentially constant expressions.
  It is further constant if $e_1$ is a constant expression and either
  \begin{enumerate}
  \item $e_1$ evaluates to \TRUE, or
  \item $e_1$ evaluates to \FALSE{} and $e_2$ is a constant expression
    that evaluates to an instance of type \code{bool}.
  \end{enumerate}

\item
  An expression of the form \code{\gtilde$e_1$} is
  a potentially constant expression
  if $e_1$ is a potentially constant expression.
  It is further a constant expression if $e_1$ is
  a constant expression that evaluates to an instance of type \code{int}
  such that \gtilde{} denotes an instance operator invocation.

\item An expression of one of the forms \code{$e_1$\,\&\,$e_2$},
  \code{$e_1$\,|\,$e_2$}, or \code{$e_1$\,\^\,$e_2$} is potentially constant
  if $e_1$ and $e_2$ are both potentially constant expressions.
  It is further constant if both $e_1$ and $e_2$ are constant expressions that
  both evaluate to instances of \code{int},
  or both to instances of \code{bool},
  such that the operator symbol
  \lit{\&}, \lit{|}, respectively \lit{\^}
  denotes an instance operator invocation.

\item An expression of one of the forms
  \code{$e_1$\,\gtgt\,$e_2$}, \code{$e_1$\,\gtgtgt\,$e_2$},
  or \code{$e_1$\,\ltlt\,$e_2$} is potentially constant
  if $e_1$ and $e_2$ are both potentially constant expressions.
  It is further constant if both $e_1$ and $e_2$ are constant expressions that
  both evaluate to an instance of \code{int},
  such that the operator symbol
  \lit{\gtgt}, \lit{\gtgtgt}, respectively \lit{\ltlt}
  denotes an instance operator invocation.

\item An expression of the form \code{$e_1$\,+\,$e_2$} is
  a potentially constant expression if $e_1$ and $e_2$
  are both potentially constant expressions.
  It is further a constant expression
  if both $e_1$ and $e_2$ are constant expressions
  and either both evaluate to an instance of \code{int} or \code{double},
  or both evaluate to an instance of \code{String},
  such that \lit{+} denotes an instance operator invocation.

\item
  An expression of the form \code{-$e_1$} is a potentially constant expression
  if $e_1$ is a potentially constant expression.
  It is further a constant expression if $e_1$ is a constant expression that
  evaluates to an instance of type \code{int} or \code{double},
  such that \lit{-} denotes an instance operator invocation.

\item An expression of the form \code{$e_1$\,-\,$e_2$}, \code{$e_1$\,*\,$e_2$},
  \code{$e_1$\,/\,$e_2$},\code{$e_1$\,\gtilde/\,$e_2$}, \code{$e_1$\,\%\,$e_2$},
  \code{$e_1$\,<\,$e_2$}, \code{$e_1$\,<=\,$e_2$}, \code{$e_1$\,>\,$e_2$}, or
  \code{$e_1$\,>=\,$e_2$}
  is potentially constant
  if $e_1$ and $e_2$ are both potentially constant expressions.
  It is further constant if both $e_1$ and $e_2$ are constant expressions that
  evaluate to instances of \code{int} or \code{double},
  such that the given operator symbol denotes
  an invocation of an instance operator.

\item An expression of the form \code{$e_1$\,?\,$e_2$\,:\,$e_3$}
  is potentially constant if $e_1$, $e_2$, and $e_3$
  are all potentially constant expressions.
  It is further constant if $e_1$ is a constant expression and either
  \begin{enumerate}
  \item $e_1$ evaluates to \TRUE{} and $e_2$ is a constant expression, or
  \item $e_1$ evaluates to \FALSE{} and $e_3$ is a constant expression.
  \end{enumerate}

\item An expression of the form \code{$e_1$\,??\,$e_2$} is potentially constant
  if $e_1$ and $e_2$ are both potentially constant expressions.
  It is further constant if $e_1$ is a constant expression and either
  \begin{enumerate}
  \item $e_1$ evaluates to an object which is not the null object, or
  \item $e_1$ evaluates to the null object, and $e_2$ is a constant expression.
  \end{enumerate}

\item An expression of the form \code{$e$.length} is potentially constant
  if $e$ is a potentially constant expression.
  It is further constant if $e$ is a constant expression that
  evaluates to an instance of \code{String},
  such that \code{length} denotes an instance getter invocation.

\item An expression of the form \code{$e$?.length} is potentially constant
  if $e$ is a potentially constant expression.
  It is further constant if $e$ is a constant expression that
  evaluates to null, or it evaluates to an instance of \code{String}
  and \code{length} denotes an instance getter invocation.

\item An expression of the form \code{$e$\,\,as\,\,$T$} is potentially constant
  if $e$ is a potentially constant expression
  and $T$ is a constant type expression,
  and it is further constant if $e$ is constant.
  \commentary{%
    It is a compile-time error to evaluate the constant expression
    if the cast operation would throw, that is,
    if $e$ evaluates to an object which is not the null object
    and not of type $T$.%
  }

\item An expression of the form \code{$e$\,\,is\,\,$T$} is potentially constant
  if $e$ is a potentially constant expression
  and $T$ is a constant type expression,
  and it is further constant if $e$ is constant.

\item
  An expression of the form \code{$e$\,\,is!\,\,$T$}
  is equivalent to \code{!($e$\,\,is\,\,$T$)} in every way,
  including whether it's potentially constant or constant.
\end{itemize}

\LMHash{}%
A
\Index{constant type expression}
is one of:

\begin{itemize}
\item
  An simple or qualified identifier
  denoting a type declaration (a type alias, class or mixin declaration)
  that is not qualified by a deferred prefix,
  optionally followed by type arguments of the form
  \code{<$T_1$,\ \ldots,\ $T_n$>}
  where $T_1$, \ldots, $T_n$ are constant type expressions.
\item
  A type of the form \code{FutureOr<$T$>}
  where $T$ is a constant type expression.
\item
  %% TODO(eernst): This does not allow for type variables introduced by
  %% the type itself. `Function<X>(X)` could be a constant type expression,
  %% but that is not covered by the current rules: `X` is a type variable,
  %% and they are never allowed.
  A function type
  \code{$R$ Function<\metavar{typeParameters}>(\metavar{argumentTypes})}
  (where $R$ and \code{<\metavar{typeParameters}>} may be omitted)
  and where $R$, \metavar{typeParameters} and \metavar{argumentTypes}
  (if present) contain only constant type expressions.
\item
  The type \VOID.
\item
  The type \DYNAMIC.
\end{itemize}

% Being potentially constant is entirely structural, not type based,
% but the program still has to satisfy strong-mode typing.

% Constant expressions (like "const Foo(42)") always evaluate to the
% same value, with at most one value per source location.
% Potentially constant expressions that are not constant only
% allow simple operations on basic types (num, String, bool, Null). These can
% be computed statically without running user code.

% A validly typed potentially constant expression can still fail when evaluated.
% If that happens in a const invociation, it's a compile-time error.

\LMHash{}%
It is a compile-time error if an expression is required to be
a constant expression,
but its evaluation would throw an exception.
It is a compile-time error if an assertion is evaluated as part of
a constant object expression evaluation,
and the assertion would throw an exception.

\LMHash{}%
It is a compile-time error if the value of a constant expression
depends on itself.

\commentary{%
  As an example, consider:%
}

\begin{dartCode}
\CLASS{} CircularConsts \{
  // \comment{Illegal program - mutually recursive compile-time constants}
  \STATIC{} \CONST{} i = j; // \comment{a compile-time constant}
  \STATIC{} \CONST{} j = i; // \comment{a compile-time constant}
\}
\end{dartCode}


\subsubsection{Further Remarks on Constants and Potential Constants}
\LMLabel{furtherCommentsOnConstantsAndPotentiallyConstants}

\rationale{%
  There is no requirement that
  every constant expression evaluate correctly.
  Only when a constant expression is required
  (e.g., to initialize a constant variable,
  or as a default value of a formal parameter,
  or as metadata)
  do we insist that a constant expression actually
  be evaluated successfully at compile time.%
}

\commentary{%
  The above is not dependent on program control-flow.
  The mere presence of a required compile-time constant
  whose evaluation would fail within a program is an error.
  This also holds recursively:
  since compound constants are composed out of constants,
  if any subpart of a constant would throw an exception when evaluated,
  that is an error.
  On the other hand, since implementations are free to compile code late,
  some compile-time errors may manifest quite late:%
}

\begin{dartCode}
\CONST{} x = 1 \gtilde/ 0;
\FINAL{} y = 1 \gtilde/ 0;
\\
\CLASS{} K \{
  m1() \{
    \VAR{} z = \FALSE;
    \IF{} (z) \{ \RETURN{} x; \}
    \ELSE{} \{ \RETURN{} 2; \}
  \}
\\
  m2() \{
    \IF{} (\TRUE{}) \{ \RETURN{} y; \}
    \ELSE{} \{ \RETURN{} 3; \}
  \}
\}
\end{dartCode}

\commentary{%
  An implementation is free to immediately issue
  a compilation error for \code{x},
  but it is not required to do so.
  It could defer errors if it does not immediately compile
  the declarations that reference \code{x}.
  For example, it could delay giving a compilation error
  about the method \code{m1} until the first invocation of \code{m1}.
  However, it could not choose to execute \code{m1},
  see that the branch that refers to \code{x} is not taken,
  and return 2 successfully.

  The situation with respect to an invocation of \code{m2} is different.
  Because \code{y} is not a compile-time constant (even though its value is),
  one need not give a compile-time error upon compiling \code{m2}.
  An implementation may run the code,
  which will cause the getter for \code{y} to be invoked.
  At that point, the initialization of \code{y} must take place,
  which requires the initializer to be compiled,
  which will cause a compilation error.%
}

\rationale{%
  The treatment of \code{\NULL} merits some discussion.
  Consider \code{\NULL{} + 2}.
  This expression always causes an error.
  We could have chosen not to treat it as a constant expression
  (and in general, not to allow \code{\NULL} as
  a subexpression of numeric or boolean constant expressions).
  There are two arguments for including it:
  First, it is constant so we \emph{can} evaluate it at compile time.
  Second, it seems more useful to give
  the error stemming from the evaluation explicitly.%
}

\rationale{%
  One might reasonably ask why
  $e_1$\,?\,\,$e_2$\,:\,$e_3$ and $e_1$\,??\,\,$e_2$
  have constant forms.
  If $e_1$ is known statically, why do we need to test it?
  The answer is that there are contexts where $e_1$ is a variable,
  e.g., in constant constructor initializers such as
  \code{\CONST{} C(foo):\ \THIS.foo = foo ??\ someDefaultValue;}%
}

\commentary{%
  The difference between
  a potentially constant expression and a constant expression
  deserves some explanation.
  The key issue is how one treats the formal parameters of a constructor.

  If a constant constructor is invoked from a constant object expression,
  the actual arguments will be required to be constant expressions.
  Therefore, if we were assured that
  constant constructors were always invoked from constant object expressions,
  we could assume that the formal parameters of a constructor were
  compile-time constants.

  However, constant constructors can also be invoked from
  ordinary instance creation expressions (\ref{new}),
  and so the above assumption is not generally valid.

  Nevertheless, the use of the formal parameters of a constant constructor
  is of considerable utility.
  The concept of potentially constant expressions is introduced to facilitate
  limited use of such formal parameters.
  Specifically, we allow the usage of
  the formal parameters of a constant constructor
  for expressions that involve built-in operators,
  but not for constant objects, lists and maps.
  For instance:%
}

\begin{dartCode}
\CLASS{} C \{
  \FINAL{} x, y, z;
  \CONST{} C(p, q): x = q, y = p + 100, z = p + q;
\}
\end{dartCode}

\commentary{%
  The assignment to \code{x} is allowed under the assumption
  that \code{q} is constant
  (even though \code{q} is not, in general a compile-time constant).
  The assignment to \code{y} is similar, but raises additional questions.
  In this case, the superexpression of \code{p} is \code{p + 100},
  and it requires that \code{p} be a numeric constant expression
  for the entire expression to be considered constant.
  The wording of the specification allows us to assume
  that \code{p} evaluates to an integer,
  for an invocation of this constructor in a constant expression.
  A similar argument holds for \code{p} and \code{q}
  in the assignment to \code{z}.

  However, the following constructors are disallowed:%
}

\begin{dartCode}
\CLASS{} D \{
  \FINAL{} w;
  \CONST{} D.makeList(p): w = \CONST{} [p]; // \comment{compile-time error}
  \CONST{} D.makeMap(p): w = \CONST{} \{"help": q\}; // \comment{compile-time error}
  \CONST{} D.makeC(p): w = \CONST{} C(p, 12); // \comment{compile-time error}
\}
\end{dartCode}

\commentary{%
  The problem is that all these run afoul of the rules for
  constant lists (\ref{lists}),
  maps (\ref{maps}),
  and objects (\ref{const}),
  all of which independently require their subexpressions to be
  constant expressions.%
}

\rationale{%
  All of the illegal constructors of \code{D} above
  could not be sensibly invoked via \NEW,
  because an expression that must be constant cannot depend on
  a formal parameter, which may or may not be constant.
  In contrast, the legal examples make sense regardless of
  whether the constructor is invoked via \CONST{} or via \NEW.

  Careful readers will of course worry about cases where
  the actual arguments to \code{C()} are constants, but are not numeric.
  This is precluded by the rules on constant constructors
  (\ref{constantConstructors}),
  combined with the rules for evaluating constant objects (\ref{const}).%
}


\subsubsection{Constant Contexts}
\LMLabel{constantContexts}

\LMHash{}%
Let $e$ be an expression; $e$ occurs in a
\Index{constant context}
if{}f one of the following applies:

% We avoid the circularity "constant context depends on constant list literal,
% etc., which depends on constant context" by mentioning the \CONST{} modifier
% explicitly here. So 'constant context' is consistently a lower-level concept
% based on syntax, and `constant X expressions' (like `constant list literal')
% are built on top of this.

\begin{itemize}
\item $e$ is an element of a list or set literal whose first token is \CONST,
  or $e$ is a key or a value of an entry
  of a map literal whose first token is \CONST.
\item $e$ occurs as \code{@$e$} in a construct derived from \synt{metadata}.
\item $e$ is an actual argument in an expression derived from
  \synt{constObjectExpression}.
\item $e$ is the initializing expression of a constant variable declaration
  (\ref{variables}).
\item $e$ is a switch case expression
  (\ref{switch}).
\item $e$ is an immediate subexpression of
  an expression $e_0$ which occurs in a constant context,
  where $e_0$ is
  %% May be added later:
  %% not a \THROW{} expression (\ref{throw}) and
  not a function literal
  (\ref{functionExpressions}).
\end{itemize}

\rationale{%
  A constant context is introduced in situations where
  an expression is required to be constant.
  This is used to allow the \CONST{} modifier to be omitted
  in cases where it does not contribute any new information.%
}


\subsection{Null}
\LMLabel{null}

\LMHash{}%
The reserved word \NULL{} evaluates to the \Index{null object}.

\begin{grammar}
<nullLiteral> ::= \NULL{}
\end{grammar}

\LMHash{}%
The null object is the sole instance of the built-in class \code{Null}.
% The following can be a consequence of the declaration of `Null`,
% but we don't spell that out, we just require that it is an error.
Attempting to instantiate \code{Null} causes a compile-time error.
It is a compile-time error for a class to extend, mix in or implement
\code{Null}.
The \code{Null} class extends the \code{Object} class
and declares no methods except those also declared by \code{Object}.

\commentary{%
  The null object has primitive equality
  (\ref{theOperatorEqualsEquals}).%
}

\LMHash{}%
The static type of \NULL{} is the \code{Null} type.


\subsection{Numbers}
\LMLabel{numbers}

\LMHash{}%
A \IndexCustom{numeric literal}{literal!numeric}
is either a decimal or hexadecimal numeral representing an integer value,
or a decimal double representation.

\begin{grammar}
<numericLiteral> ::= <NUMBER>
  \alt <HEX\_NUMBER>

<NUMBER> ::= <DIGIT>+ (`.' <DIGIT>+)? <EXPONENT>?
  \alt `.' <DIGIT>+ <EXPONENT>?

<EXPONENT> ::= (`e' | `E') (`+' | `-')? <DIGIT>+

<HEX\_NUMBER> ::= `0x' <HEX\_DIGIT>+
  \alt `0X' <HEX\_DIGIT>+

<HEX\_DIGIT> ::= `a' .. `f'
  \alt `A' .. `F'
  \alt <DIGIT>
\end{grammar}

\LMHash{}%
A numeric literal starting with `0x' or `0X'
is a \IndexCustom{hexadecimal integer literal}{literal!hexadecimal integer}.
It has the numeric integer value of the hexadecimal numeral
following `0x' (respectively `0X').

\LMHash{}%
A numeric literal that contains only decimal digits is a
\IndexCustom{decimal integer literal}{literal!decimal integer}.
It has the numeric integer value of the decimal numeral.

\LMHash{}%
An \IndexCustom{integer literal}{literal!integer}
is either a hexadecimal integer literal or a decimal integer literal.

\LMHash{}%
Let $l$ be an integer literal that is not the operand
of by a unary minus operator,
and let $T$ be the static context type of $l$.
If \code{double} is assignable to $T$ and \code{int} is not assignable to $T$,
then the static type of $l$ is \code{double};
otherwise the static type of $l$ is \code{int}.

\commentary{%
  This means that an integer literal denotes a \code{double}
  when it would satisfy the type requirement, and an \code{int} would not.
  Otherwise it is an \code{int}, even in situations where that is an error.%
}

\LMHash{}%
A numeric literal that is not an integer literal is a
\IndexCustom{double literal}{literal!double}.
\commentary{%
  A double literal always contains either a decimal point or an exponent part.%
}
The static type of a double literal is \code{double}.

\LMHash{}%
If $l$ is an integer literal with numeric value $i$ and static type \code{int},
and $l$ is not the operand of a unary minus operator,
then evaluation of $l$ proceeds as follows:

\begin{itemize}
  \item{} If $l$ is a hexadecimal integer literal,
  $2^{63} \le i < 2^{64}$ and the \code{int} class is implemented as
  signed 64-bit two's complement integers,
  then $l$ evaluates to an instance of the \code{int} class
  representing the numeric value $i - 2^{64}$,
  \item{} Otherwise $l$ evaluates to an instance of the \code{int} class
  representing the numeric value $i$.
  It is a compile-time error if the integer $i$ cannot be represented
  exactly by an instance of \code{int}.
\end{itemize}

\commentary{%
  Integers in Dart are designed to be implemented as
  64-bit two's complement integer representations.
  In practice, implementations may be limited by other considerations.
  For example, Dart compiled to JavaScript may use the JavaScript number type,
  equivalent to Dart \code{double}, to represent integers, and if so,
  integer literals with more than 53 bits of precision cannot be represented
  exactly.%
}

\LMHash{}%
A double literal evaluates to a an instance of the \code{double} class
representing a 64 bit double precision floating point number
as specified by the IEEE 754 standard.

\LMHash{}%
An integer literal with static type \code{double} and numeric value $i$
evaluates to an instance of the \code{double} class representing the value $i$.
It is a compile-time error if the value $i$
cannot be represented \emph{precisely} by an instance of \code{double}.

\commentary{%
  A 64 bit double precision floating point number
  is usually taken to represent a range of real numbers
  around the precise value denoted by the number's
  sign, mantissa and exponent.
  For integer literals evaluating to \code{double}
  values we insist that the integer literal's numeric value
  is the precise value of the \code{double} instance.%
}

\LMHash{}%
It is a compile-time error for a class to extend, mix in or implement
\code{int}.
It is a compile-time error for a class to extend, mix in or implement
\code{double}.
It is a compile-time error for any class
other than \code{int} and \code{double} to extend, mix in or implement
\code{num}.

\LMHash{}%
The instances of \code{int} and \code{double} all override
the \lit{==} operator inherited from the \code{Object} class.


\subsection{Booleans}
\LMLabel{booleans}

\LMHash{}%
The reserved words \TRUE{} and \FALSE{} evaluate to objects
\IndexCustom{true}{true, the object} and
\IndexCustom{false}{false, the object}
that represent the boolean values true and false respectively.
They are the \IndexCustom{boolean literals}{literal!boolean}.

\begin{grammar}
<booleanLiteral> ::= \TRUE{}
  \alt \FALSE{}
\end{grammar}

\LMHash{}%
Both \NoIndex{true} and \NoIndex{false} are instances of
the built-in class \code{bool},
and there are no other objects that implement \code{bool}.
It is a compile-time error for a class to
extend, mix in or implement \code{bool}.

\commentary{%
  The \TRUE{} and \FALSE{} objects have primitive equality
  (\ref{theOperatorEqualsEquals}).%
}

\LMHash{}%
Invoking the getter \code{runtimeType} on a boolean value returns
the \code{Type} object that is the value of the expression \code{bool}.
The static type of a boolean literal is \code{bool}.


\subsection{Strings}
\LMLabel{strings}

\LMHash{}%
A \Index{string} is a sequence of UTF-16 code units.

\rationale{%
  This decision was made for compatibility with web browsers and Javascript.
  Earlier versions of the specification required a string to be
  a sequence of valid Unicode code points.
  Programmers should not depend on this distinction.%
}

\begin{grammar}
<stringLiteral> ::= (<multilineString> | <singleLineString>)+
\end{grammar}

\LMHash{}%
A string can be a sequence of single line strings and multiline strings.

\begin{grammar}
<singleLineString> ::= <RAW\_SINGLE\_LINE\_STRING>
  \alt <SINGLE\_LINE\_STRING\_SQ\_BEGIN\_END>
  \alt <SINGLE\_LINE\_STRING\_SQ\_BEGIN\_MID> <expression> \gnewline{}
       (<SINGLE\_LINE\_STRING\_SQ\_MID\_MID> <expression>)* \gnewline{}
       <SINGLE\_LINE\_STRING\_SQ\_MID\_END>
  \alt <SINGLE\_LINE\_STRING\_DQ\_BEGIN\_END>
  \alt <SINGLE\_LINE\_STRING\_DQ\_BEGIN\_MID> <expression> \gnewline{}
       (<SINGLE\_LINE\_STRING\_DQ\_MID\_MID> <expression>)* \gnewline{}
       <SINGLE\_LINE\_STRING\_DQ\_MID\_END>

<RAW\_SINGLE\_LINE\_STRING> ::=
  `r' `\sq' (\gtilde(`\sq' | `\\r' | `\\n'))* `\sq'
  \alt `r' `"' (\gtilde(`"' | `\\r' | `\\n'))* `"'

<STRING\_CONTENT\_COMMON> ::= \gtilde(`\\' | `\sq' | `"' | `$' | `\\r' | `\\n')
  \alt <ESCAPE\_SEQUENCE>
  \alt `\\' \gtilde(`n' | `r' | `b' | `t' | `v' | `x' | `u' | `\\r' | `\\n')
  \alt <SIMPLE\_STRING\_INTERPOLATION>

<STRING\_CONTENT\_SQ> ::= <STRING\_CONTENT\_COMMON> | `"'

<SINGLE\_LINE\_STRING\_SQ\_BEGIN\_END> ::= \gnewline{}
  `\sq' <STRING\_CONTENT\_SQ>* `\sq'

<SINGLE\_LINE\_STRING\_SQ\_BEGIN\_MID> ::= \gnewline{}
  `\sq' <STRING\_CONTENT\_SQ>* `${'

<SINGLE\_LINE\_STRING\_SQ\_MID\_MID> ::= \gnewline{}
  `}' <STRING\_CONTENT\_SQ>* `${'

<SINGLE\_LINE\_STRING\_SQ\_MID\_END> ::= \gnewline{}
  `}' <STRING\_CONTENT\_SQ>* `\sq'

<STRING\_CONTENT\_DQ> ::= <STRING\_CONTENT\_COMMON> | `\sq'

<SINGLE\_LINE\_STRING\_DQ\_BEGIN\_END> ::= \gnewline{}
  `"' <STRING\_CONTENT\_DQ>* `"'

<SINGLE\_LINE\_STRING\_DQ\_BEGIN\_MID> ::= \gnewline{}
  `"' <STRING\_CONTENT\_DQ>* `${'

<SINGLE\_LINE\_STRING\_DQ\_MID\_MID> ::= \gnewline{}
  `}' <STRING\_CONTENT\_DQ>* `${'

<SINGLE\_LINE\_STRING\_DQ\_MID\_END> ::= \gnewline{}
  `}' <STRING\_CONTENT\_DQ>* `"'
\end{grammar}

\LMHash{}%
A single line string is delimited by
either matching single quotes or matching double quotes.

\commentary{%
  Hence, \code{'abc'} and \code{"abc"} are both legal strings,
  as are \code{'He said "To be or not to be" did he not?'} and
  \code{"He said 'To be or not to be' didn't he?"}.
  However, \code{"This'} is not a valid string, nor is \code{'this"}.%
}

\commentary{%
  The grammar ensures that a single line string cannot span more than
  one line of source code,
  unless it includes an interpolated expression that spans multiple lines.%
}

\LMHash{}%
Adjacent strings are implicitly concatenated to form a single string literal.

\commentary{%
  Here is an example:%
}

\begin{dartCode}
print("A string" "and then another"); // \comment{A stringand then another}
\end{dartCode}

\rationale{%
  Dart also supports the operator + for string concatenation.

  The + operator on Strings requires a String argument.
  It does not coerce its argument into a string.
  This helps avoid puzzlers such as%
}

\begin{dartCode}
print("A simple sum: 2 + 2 = " +
            2 + 2);
\end{dartCode}

\rationale{%
  which would print `\code{A simple sum: 2 + 2 = 22}' rather than
  `\code{A simple sum: 2 + 2 = 4}'.
  However, for efficiency reasons,
  the recommended Dart idiom is to use string interpolation.%
}

\begin{dartCode}
print("A simple sum: 2 + 2 = \$\{2+2\}");
\end{dartCode}

\rationale{%
  String interpolation works well for most cases.
  The main situation where it is not fully satisfactory
  is for string literals that are too large to fit on a line.
  Multiline strings can be useful, but in some cases,
  we want to visually align the code.
  This can be expressed by writing
  smaller strings separated by whitespace, as shown here:%
}

\begin{dartCode}
'Imagine this is a very long string that does not fit on a line. What shall we do? '
'Oh what shall we do? '
'We shall split it into pieces '
'like so'.
\end{dartCode}

\LMHash{}%
An auxiliary
\Index{string interpolation state stack}
is maintained outside the parser,
in order to ensure that string interpolations are matched up correctly.

\commentary{%
  This is necessary because the expression of a non-simple string interpolation
  may itself contain string literals
  with their own non-simple string interpolations.%
}

\LMHash{}%
For rules with names \synt{\ldots\_BEGIN\_MID},
a marker is pushed on the auxiliary stack to indicate that
a string interpolation of the given kind has started,
where the kind is \lit{\sq}, \lit{"}, \lit{\sqsqsq}, or \lit{"""}.
For rules with names \synt{\ldots\_MID\_MID},
only the rule with the kind on the top of the auxiliary stack can be used.
For rules with names \synt{\ldots\_MID\_END},
only the rule with the kind on the top of the auxiliary stack can be used,
and the marker is then popped.

\begin{grammar}
<multilineString> ::= <RAW\_MULTI\_LINE\_STRING>
  \alt <MULTI\_LINE\_STRING\_SQ\_BEGIN\_END>
  \alt <MULTI\_LINE\_STRING\_SQ\_BEGIN\_MID> <expression> \gnewline{}
       (<MULTI\_LINE\_STRING\_SQ\_MID\_MID> <expression>)* \gnewline{}
       <MULTI\_LINE\_STRING\_SQ\_MID\_END>
  \alt <MULTI\_LINE\_STRING\_DQ\_BEGIN\_END>
  \alt <MULTI\_LINE\_STRING\_DQ\_BEGIN\_MID> <expression> \gnewline{}
       (<MULTI\_LINE\_STRING\_DQ\_MID\_MID> <expression>)* \gnewline{}
       <MULTI\_LINE\_STRING\_DQ\_MID\_END>

<RAW\_MULTI\_LINE\_STRING> ::= `r' `\sqsqsq' .*? `\sqsqsq'
  \alt `r' `"""' .*? `"""'

<QUOTES\_SQ> ::= | `\sq' | `\sqsq'

<STRING\_CONTENT\_TSQ> ::= \gnewline{}
  <QUOTES\_SQ> (<STRING\_CONTENT\_COMMON> | `"' | `\\r' | `\\n')

<MULTI\_LINE\_STRING\_SQ\_BEGIN\_END> ::= \gnewline{}
  `\sqsqsq' <STRING\_CONTENT\_TSQ>* `\sqsqsq'

<MULTI\_LINE\_STRING\_SQ\_BEGIN\_MID> ::= \gnewline{}
  `\sqsqsq' <STRING\_CONTENT\_TSQ>* <QUOTES\_SQ> `${'

<MULTI\_LINE\_STRING\_SQ\_MID\_MID> ::= \gnewline{}
  `}' <STRING\_CONTENT\_TSQ>* <QUOTES\_SQ> `${'

<MULTI\_LINE\_STRING\_SQ\_MID\_END> ::= \gnewline{}
  `}' <STRING\_CONTENT\_TSQ>* `\sqsqsq'

<QUOTES\_DQ> ::= | `"' | `""'

<STRING\_CONTENT\_TDQ> ::= \gnewline{}
  <QUOTES\_DQ> (<STRING\_CONTENT\_COMMON> | `\sq' | `\\r' | `\\n')

<MULTI\_LINE\_STRING\_DQ\_BEGIN\_END> ::= \gnewline{}
  `"""' <STRING\_CONTENT\_TDQ>* `"""'

<MULTI\_LINE\_STRING\_DQ\_BEGIN\_MID> ::= \gnewline{}
  `"""' <STRING\_CONTENT\_TDQ>* <QUOTES\_DQ> `${'

<MULTI\_LINE\_STRING\_DQ\_MID\_MID> ::= \gnewline{}
  `}' <STRING\_CONTENT\_TDQ>* <QUOTES\_DQ> `${'

<MULTI\_LINE\_STRING\_DQ\_MID\_END> ::= \gnewline{}
  `}' <STRING\_CONTENT\_TDQ>* `"""'

<ESCAPE\_SEQUENCE> ::= `\\n' | `\\r' | `\\f' | `\\b' | `\\t' | `\\v'
  \alt `\\x' <HEX\_DIGIT> <HEX\_DIGIT>
  \alt `\\u' <HEX\_DIGIT> <HEX\_DIGIT> <HEX\_DIGIT> <HEX\_DIGIT>
  \alt `\\u{' <HEX\_DIGIT\_SEQUENCE> `}'

<HEX\_DIGIT\_SEQUENCE> ::= \gnewline{}
  <HEX\_DIGIT> <HEX\_DIGIT>? <HEX\_DIGIT>?
  \gnewline{} <HEX\_DIGIT>? <HEX\_DIGIT>? <HEX\_DIGIT>?
\end{grammar}

\LMHash{}%
Multiline strings are delimited by either
matching triples of single quotes or
matching triples of double quotes.
If the first line of a multiline string consists solely of
the whitespace characters defined by the production \synt{WHITESPACE}
(\ref{lexicalRules}),
possibly prefixed by \syntax{`\\'},
then that line is ignored,
including the line break at its end.

\rationale{%
  The idea is to ignore a whitespace-only first line of a multiline string,
  where whitespace is defined as tabs, spaces and the final line break.
  These can be represented directly,
  but since for most characters prefixing by backslash is
  an identity in a non-raw string,
  we allow those forms as well.%
}

\LMHash{}%
In the rule for \synt{RAW\_MULTI\_LINE\_STRING},
the two occurrences of \lit{.*?}
denote a non-greedy token recognition step:
It terminates as soon as the lookahead is the specified next token
\commentary{(that is, \lit{\sqsqsq} or \lit{"""})}.

\commentary{%
  Note that multi-line string interpolation relies on
  the auxiliary string interpolation state stack,
  just like single-line string interpolation.%
}

\LMHash{}%
Strings support escape sequences for special characters.
The escapes are:

\begin{itemize}
\item
  \syntax{`\\n'} for newline, equivalent to \syntax{`\\x0A'}.
\item
  \syntax{`\\r'} for carriage return, equivalent to \syntax{`\\x0D'}.
\item
  \syntax{`\\f'} for form feed, equivalent to \syntax{`\\x0C'}.
\item
  \syntax{`\\b'} for backspace, equivalent to \syntax{`\\x08'}.
\item
  \syntax{`\\t'} for tab, equivalent to \syntax{`\\x09'}.
\item
  \syntax{`\\v'} for vertical tab, equivalent to \syntax{`\\x0B'}.
\item
  \syntax{`\\x' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$}, equivalent to

  \syntax{`\\u{' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ `}'}.
\item
  \syntax{`\\u' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ <HEX\_DIGIT>$_3$ <HEX\_DIGIT>$_4$},
  equivalent to

  \noindent
  \syntax{`\\u{' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ <HEX\_DIGIT>$_3$ <HEX\_DIGIT>$_4$ `}'}.
\item
  \syntax{`\\u{' <HEX\_DIGIT\_SEQUENCE> `}'} is
  the Unicode code point represented by the
  \syntax{<HEX\_DIGIT\_SEQUENCE>}.
  It is a compile-time error if the value of the
  \syntax{<HEX\_DIGIT\_SEQUENCE>}
  is not a valid Unicode code point.
  \commentary{For example,}
  {\color{commentaryColor}{\syntax{`\\u{0A}'}}\color{normativeColor}}
  \commentary{is the code point U+000A.}
\item
  \lit{\$} indicating the beginning of an interpolated expression.
\item
  { % We need a definition for $k$ in order to be able to use it in \syntax.
    \def\k{$k$}
    Otherwise, \syntax{`\\\k'} indicates the character \k{} for
    any \k{} not in \syntax{$\{$`n', `r', `f', `b', `t', `v', `x', `u'$\}$}.
  }
\end{itemize}

\LMHash{}%
Any string may be prefixed with the character \lit{r},
indicating that it is a \Index{raw string},
in which case no escapes or interpolations are recognized.

\LMHash{}%
Line breaks in a multiline string are represented by
the \synt{LINE\_BREAK} production.
A line break introduces a single newline character (U+000A)
into the string value.

\LMHash{}%
It is a compile-time error if a non-raw string literal contains
a character sequence of the form \syntax{`\\x'} that is not followed by
a sequence of two hexadecimal digits.
It is a compile-time error if a non-raw string literal contains
a character sequence of the form \syntax{`\\u'} that is not followed by
either a sequence of four hexadecimal digits,
or by curly brace delimited sequence of hexadecimal digits.

\begin{grammar}
<LINE\_BREAK> ::= `\\n'
  \alt `\\r\\n'
  \alt `\\r'
\end{grammar}

\LMHash{}%
All string literals evaluate to instances of the built-in class \code{String}.
It is a compile-time error for a class to
extend, mix in or implement \code{String}.
The \code{String} class overrides the \lit{==} operator inherited from
the \code{Object} class.
The static type of a string literal is \code{String}.


\subsubsection{String Interpolation}
\LMLabel{stringInterpolation}

\LMHash{}%
It is possible to embed expressions within non-raw string literals,
such that these expressions are evaluated,
and the resulting objects are converted into strings and
concatenated with the enclosing string.
This process is known as \Index{string interpolation}.

\begin{grammar}
<stringInterpolation> ::= <SIMPLE\_STRING\_INTERPOLATION>
  \alt `${' <expression> `}'

<SIMPLE\_STRING\_INTERPOLATION> ::= \gnewline{}
  `$' (<IDENTIFIER\_NO\_DOLLAR> | <BUILT\_IN\_IDENTIFIER> | \THIS)
\end{grammar}

\commentary{%
  The reader will note that the expression inside the interpolation
  could itself include strings,
  which could again be interpolated recursively.%
}

\LMHash{}%
An unescaped \lit{\$} character in a string signifies
the beginning of an interpolated expression.
The \lit{\$} sign may be followed by either:

\begin{itemize}
\item A single identifier \id{} that does not contain the \lit{\$} character
  (but it can be a built-in identifier),
  or the reserved word \THIS.
\item An expression $e$ delimited by curly braces.
\end{itemize}

\LMHash{}%
The form \code{\$\id} is equivalent to the form \code{\$\{\id\}}.
An interpolated string, $s$, with content
`\code{$s_0$\$\{$e_1$\}$s_1\ldots{}s_{n-1}$\$\{$e_n$\}$s_{n}$}'
(where any of $s_0, \ldots, s_n$ can be empty)
is evaluated by evaluating each expression $e_i$ ($1 \le i \le n$)
into a string $r_i$ in the order they occur in the source text, as follows:

\begin{itemize}
\item Evaluate $e_i$ to an object $o_i$.
\item Invoke the \code{toString} method on $o_i$ with no arguments,
  and let $r_i$ be the returned object.
\item If $r_i$ is the null object, a dynamic error occurs.
\end{itemize}

\LMHash{}%
Finally, the result of the evaluation of $s$ is
the concatenation of the strings $s_0$, $r_1$, \ldots, $r_n$, and $s_n$.


\subsection{Symbols}
\LMLabel{symbols}

\LMHash{}%
A \IndexCustom{symbol literal}{literal!symbol}
denotes a name that would be either
a valid declaration name, a valid library name, or \VOID.

\begin{grammar}
<symbolLiteral> ::=
  `#' (<identifier> (`.' <identifier>)* | <operator> | \VOID)
\end{grammar}

\LMHash{}%
The static type of a symbol literal is \code{Symbol}.

\LMHash{}%
Let \id{} be an identifier that does not begin with an underscore
(`\code{\_}').
The symbol literal \code{\#\id}
evaluates to an instance of \code{Symbol}
representing the identifier \id.

\LMHash{}%
A symbol literal \code{\#$\id_1$.$\id_2$.$\cdots$.$\id_n$}
where \List{\id}{1}{n} are identifiers
evaluates to an instance of \code{Symbol}
representing that particular sequence of identifiers.
\commentary{%
  This kind of symbol literal denotes the name of a library declaration,
  as specified in a \synt{libraryName}.
  Library names are not subject to library privacy, even
  if some of its identifiers begin with an underscore.%
}

\LMHash{}%
A symbol literal \code{\#\metavar{op}}
where \metavar{op} is derived from \synt{operator}
evaluates to an instance of \code{Symbol}
representing that particular operator name.

\LMHash{}%
The symbol literal \code{\#void}
evaluates to an instance of \code{Symbol}
representing the reserved word \VOID.

\LMHash{}%
For the value $o$ of a symbol literal representing a source code term
as specified in the previous paragraphs, we say that $o$ is a
\IndexCustom{non-private symbol based on}{symbol!non-private, based on}
the string whose contents is the characters of that term, without whitespace.

\commentary{%
  Note that this does not apply for private symbols,
  which are discussed below.
  A private symbol is not based on any string.%
}

\LMHash{}%
If $o$ is the value of an invocation of the \code{Symbol} constructor
of the form
\code{Symbol($e$)}, \code{\NEW\,\,Symbol($e$)},
or \code{\CONST\,\,Symbol($e$)},
where $e$ is an expression
\commentary{(constant if necessary)}
that evaluates to a string $s$,
we say that $o$ is a \NoIndex{non-private symbol based on} $s$.

\commentary{%
  Note that \code{Symbol('\_foo')} is a non-private symbol,
  and it is distinct from \code{\#\_foo}, as described below.%
}

\LMHash{}%
Assume that $i \in 1,2$,
and that $o_i$ is the value of a constant expression
which is a symbol based on the string $s_i$.
If \code{$s_1$\,==\,$s_2$} then $o_1$ and $o_2$ is the same object.
\commentary{That is, symbol instances are canonicalized.}

\LMHash{}%
If $o_1$ and $o_2$ are non-private symbols
\commentary{(not necessarily constant)}
based on strings $s_1$ and $s_2$
then $o_1$ and $o_2$ are equal according to operator \lit{==}
if and only if \code{$s_1$ == $s_2$}
(\ref{equality}).

\LMHash{}%
A symbol literal \code{\#\_\id} where \code{\_\id} is an identifier
evaluates to an instance of \code{Symbol}
representing the private identifier \code{\_\id} of the enclosing library.
All occurrences of \code{\#\_\id} \emph{in the same library} evaluate to
the same object,
and no other symbol literal or \code{Symbol} constructor invocation
evaluates to the same object,
nor to a \code{Symbol} instance that is equal to that object
according to the \lit{==} operator.

\rationale{%
  One may well ask what is the motivation for introducing literal symbols?
  In some languages, symbols are canonicalized whereas strings are not.
  However literal strings are already canonicalized in Dart.
  Symbols are slightly easier to type compared to strings
  and their use can become strangely addictive,
  but this is not nearly sufficient justification for adding
  a literal form to the language.
  The primary motivation is related to the use of reflection
  and a web specific practice known as minification.

  Minification compresses identifiers consistently throughout a program
  in order to reduce download size.
  This practice poses difficulties for reflective programs
  that refer to program declarations via strings.
  A string will refer to an identifier in the source,
  but the identifier will no longer be used in the minified code,
  and reflective code using these would fail.
  Therefore, Dart reflection uses objects of type \code{Symbol}
  rather than strings.
  Instances of \code{Symbol} are guaranteed to be stable
  with respect to minification.
  Providing a literal form for symbols makes
  reflective code easier to read and write.
  The fact that symbols are easy to type and can often act as
  convenient substitutes for enums are secondary benefits.%
}


\subsection{Collection Literals}
\LMLabel{collectionLiterals}

\LMHash{}%
This section specifies several literal expressions denoting collections.
Some syntactic forms may denote more than one kind of collection,
in which case a disambiguation step is performed
in order to determine the kind
(\ref{setAndMapLiteralDisambiguation}).

\LMHash{}%
The subsections of this section are concerned with mechanisms that are
common to all kinds of collection literals
(\ref{collectionLiteralTypePromotion},
\ref{collectionLiteralElementEvaluation}),
followed by a specification of list literals
(\ref{listLiteralInference}, \ref{lists}),
followed by a specification of how to disambiguate and infer types
for sets and maps
(\ref{setAndMapLiteralDisambiguation}, \ref{setAndMapLiteralInference}),
and finally a specification of sets
(\ref{sets})
and maps
(\ref{maps}).

\begin{grammar}
<listLiteral> ::= \CONST? <typeArguments>? `[' <elements>? `]'

<setOrMapLiteral> ::= \CONST? <typeArguments>? `{' <elements>? `}'

<elements> ::= <element> (`,' <element>)* `,'?

<element> ::= <expressionElement>
  \alt <mapElement>
  \alt <spreadElement>
  \alt <ifElement>
  \alt <forElement>

<expressionElement> ::= <expression>

<mapElement> ::= <expression> `:' <expression>

<spreadElement> ::= (`...' | `...?') <expression>

<ifElement> ::= \IF{} `(' <expression> `)' <element> (\ELSE{} <element>)?

<forElement> ::= \AWAIT? \FOR{} `(' <forLoopParts> `)' <element>
\end{grammar}

\LMHash{}%
Syntactically, a \Index{collection literal} can be
a \synt{listLiteral} or a \synt{setOrMapLiteral}.
The contents of the collection is specified as a sequence of
\IndexCustom{collection literal elements}{collection literal!elements},
in short \Index{elements}.
Each element may be a declarative specification of a single entity,
such as an \synt{expressionElement} or a \synt{mapElement},
it may specify a collection which is to be included,
of the form \synt{spreadElement},
or it may be a computational element specifying
how to obtain zero or more entities,
of the form \synt{ifElement} or \synt{forElement}.

\commentary{%
  Terms derived from \synt{element},
  and the ability to build collections from them,
  is also known as
  \Index{UI-as-code}.%
}

\LMHash{}%
The \Index{leaf elements} of an element $\ell$ derived from
\synt{expressionElement} or \synt{mapElement}
is $\{\ell\}$.
The leaf elements of an element of the form
\code{\IF\,($e$)\,$\ell$} or
\code{\FOR\,(\metavar{forLoopParts})\,$\ell$}
is the leaf elements of $\ell$.
The leaf elements of an element of the form
\code{\IF\,($e$)\,$\ell_1$\,\ELSE\,$\ell_2$}
is the union of the leaf elements of $\ell_1$ and $\ell_2$.
The leaf elements of a \synt{spreadElement} is the empty set.

\commentary{%
  The leaf elements of a collection literal is always
  a set of expression elements and/or map elements.%
}

\LMHash{}%
In order to allow collection literals to occur as constant expressions,
we specify what it means for an element $\ell$
to be
\IndexCustom{constant}{collection literal element!constant}
or
\IndexCustom{potentially constant}{%
  collection literal element!potentially constant}:

\begin{itemize}
\item
  When $\ell$ is an \synt{expressionElement} of the form $e$:

  $\ell$ is a potentially constant element
  if $e$ is a potentially constant expression,
  and $\ell$ is a constant element
  if $e$ is a constant expression.
\item
  When $\ell$ is a \synt{mapElement}
  of the form `\code{$e_1$:\,$e_2$}':

  $\ell$ is a potentially constant element
  if both $e_1$ and $e_2$ are potentially constant expressions,
  and it is a constant element if they are constant expressions.
\item
  When $\ell$ is a \synt{spreadElement}
  of the form `\code{...$e$}' or `\code{...?$e$}':

  $\ell$ is a potentially constant element
  if $e$ is a potentially constant expression.

  $\ell$ is a constant element
  if $e$ is a constant expression that evaluates
  to a \code{List}, \code{Set}, or \code{Map} instance
  originally created by a list, set, or map literal.

  Moreover, $\ell$ is a constant element if it is `\code{...?$e$}',
  where $e$ is a constant expression that evaluates
  to the null object.
\item
  When $\ell$ is an \synt{ifElement}
  of the form
  \code{\IF\,\,($b$)\,\,$\ell_1$}
  or the form
  \code{\IF\,\,($b$)\,\,$\ell_1$\,\,\ELSE\,\,$\ell_2$}:

  $\ell$ is a potentially constant element
  if $b$ is a potentially constant expression,
  $\ell_1$ is potentially constant,
  and so is $\ell_2$, if present.

  $\ell$ is a constant element if $b$ is a constant expression
  and:

  \begin{itemize}
  \item
    $\ell$ is \code{\IF\,\,($b$)\,\,$\ell_1$} and
    either $b$ evaluates to \TRUE{} and $\ell_1$ is constant,
    or $b$ evaluates to \FALSE{} and $\ell_1$ is potentially constant.
  \item
    $\ell$ is \code{\IF\,\,($b$)\,\,$\ell_1$\,\,\ELSE\,\,$\ell_2$} and
    either $b$ evaluates to \TRUE,
    $\ell_1$ is constant,
    and $\ell_2$ is potentially constant;
    or $b$ evaluates to \FALSE,
    $\ell_1$ is potentially constant,
    and $\ell_2$ is constant.
  \end{itemize}
\end{itemize}

\commentary{%
  A \synt{forElement} can never occur in a constant collection literal.%
}

%% TODO(eernst): We may change this text to commentary or delete it,
%% it consists of descriptions of errors, but they are already covered
%% elsewhere.
%%
%% Compile-time errors.
%%
%% The following compile-time errors are specified in the feature
%% specification, but they are already implied by the errors specified
%% elsewhere.
%%
%% - "A non-null-aware spread element has static type \code{Null}".
%%   For a list literal: listLiteralInference makes this an error by case
%%   analysis on 'Spread element'.
%%   Set/map literal: setAndMapLiteralInference, ditto.
%%
%% - "A spread element in a list or set literal has a static type that is
%%   not \DYNAMIC{} and not a subtype of \code{Iterable<Object>}".
%%   List literal: case analysis on 'Spread element'.
%%   Set literal: case analysis on 'Spread element': only succeeds if
%%   $S$ implements `Map` (and not `Iterable`), so it has a key/value
%%   type and no element type, which is an error (\ref{sets}).
%%
%% - "A spread element in a list or set has a static type that
%%   implements \code{Iterable<$T$>} for some $T$ and
%%   $T$ is not assignable to the element type of the list."
%%   List literal: cf. 'Spread element' this implies that the spread element
%%   has element type $T$, and non-assignability is an error, \ref{lists}.
%%   Set literal: cf. 'Spread element' for sets/maps: ditto.
%%
%% - "A spread element in a map literal has a static type that is
%%   not \DYNAMIC{} and not a subtype of \code{Map<Object, Object>}".
%%   Set/map 'Spread element' case analysis then implies that it implements
%%   `Iterable` and not `Map`, in which case it has no key/value type pair,
%%   which is an error, \ref{maps}.
%%
%% - "If a map spread element's static type implements \code{Map<$K$, $V$>}
%%   for some $K$ and $V$ and $K$ is not assignable to the key type of the
%%   map or $V$ is not assignable to the value type of the map".
%%   This is an error, \ref{maps}.
%%
%% - "The variable in a \synt{forElement} \commentary{(either a for-in
%%   element or C-style)} is declared outside of the element to be final or
%%   to not have a setter".
%%   This error is specified in \ref{listLiteralInference} and
%%   \ref{setAndMapLiteralInference}.
%%
%% - "The type of the iterator expression in a synchronous for-in element
%%   may not be assigned to \code{Iterable<$T$>} for any type $T$.
%%   Otherwise, the \Index{iterable type} of the iterator is $T$".
%%   Covered by the same text as the previous error.
%%
%% - "The iterable type of the iterator in a synchronous for-in element
%%   may not be assigned to the for-in variable's type."
%%   Covered by the same text again.
%%
%% - "The type of the stream expression in an asynchronous \AWAIT{} for-in
%%   element may not be assigned to \code{Stream<$T$>} for any type $T$.
%%   Otherwise, the \Index{stream type} of the stream is $T$".
%%   Same text again (the `forElement` text includes both await for and for).
%%
%% - "The stream type of the iterator in an asynchronous \AWAIT{} for-in element
%%   may not be assigned to the for-in variable's type".
%%   Same text again.
%%
%% - "\AWAIT{} \FOR{} is used when the function immediately enclosing the
%%   collection literal is not asynchronous".
%%   Same text again.
%%
%% - "\AWAIT{} is used before a C-style \synt{forElement}.
%%   \AWAIT{} can only be used with for-in loops".
%%   Same text again.
%%
%% - "The type of the condition expression \commentary{(the second clause)}
%%   in a C-style \FOR{} element may not be assigned to \code{bool}".
%%   Same text again.


\subsubsection{Type Promotion}
\LMLabel{collectionLiteralTypePromotion}

\LMHash{}%
An \synt{ifElement} interacts with type promotion
in the same way that \IF{} statements do.
Let $\ell$ be an \synt{ifElement} of the form
\code{\IF\,\,($b$)\,\,$\ell_1$} or
\code{\IF\,\,($b$)\,\,$\ell_1$\,\,\ELSE\,\,$\ell_2$}.
If $b$ shows that a local variable $v$ has type $T$, then
the type of $v$ is known to be $T$ in $\ell_1$,
unless any of the following are true:

\begin{itemize}
\item $v$ is potentially mutated in $\ell_1$,
\item $v$ is potentially mutated within a function
  other than the one where $v$ is declared, or
\item $v$ is accessed by a function defined in $\ell_1$ and
  $v$ is potentially mutated anywhere in the scope of $v$.
\end{itemize}

%% TODO(eernst): Come nnbd, update this.
\commentary{%
  Type promotion will likely get more sophisticated in a future version of Dart.
  When that happens,
  \synt{ifElement}s will continue to match \IF{} statements
  (\ref{if}).%
}


\subsubsection{Collection Literal Element Evaluation}
\LMLabel{collectionLiteralElementEvaluation}

\LMHash{}%
The evaluation of a sequence of collection literal elements
(\ref{collectionLiterals})
yields a
\IndexCustom{collection literal object sequence}{%
  collection literal!object sequence},
also called an \NoIndex{object sequence} when no ambiguity can arise.

\LMHash{}%
We use the notation
% `\LiteralSequence` cannot be used after `@`, so we use an approximation.
\IndexCustom{\LiteralSequence{\ldots}}{[[...]]@%
  \ensuremath{[\hspace{-0.6mm}[\ldots]\hspace{-0.6mm}]}}
to denote an object sequence with explicitly listed elements,
and we use `$+$' to compute the concatenation of object sequences
\commentary{(as in $s_1 + s_2$)},
which is an operation that will succeed and has no side-effects.
Each element in the sequence is an object $o$ or a pair $o_1: o_2$.
There is no notion of an element type for an object sequence,
and hence no notion of dynamic errors arising from
a type mismatch during concatenation.

\commentary{%
  Object sequences can safely be treated as a low-level mechanism
  which may omit otherwise required actions like dynamic type checks
  because every access to an object sequence occurs
  in code created by language defined desugaring
  on statically checked constructs.
  It is left unspecified how an object sequence is implemented,
  it is only required that it contains the indicated objects or pairs
  in the given order.
  For each kind of collection,
  the sequence is used in the given order to populate the collection,
  in a manner which is specific to the kind,
  and which is specified separately
  (\ref{lists}, \ref{sets}, \ref{maps}).%

  There may be an actual data structure
  representing the object sequence at run time,
  but the object sequence could also be eliminated, e.g.,
  because each element is inserted directly into the target collection
  as soon as it has been computed.
  Note that each object sequence will exclusively contain objects,
  or it will exclusively contain pairs,
  because any attempt to create a mixed sequence would cause
  an error at compile time or at run time
  (the latter may occur for a spread element with static type \DYNAMIC{}).%
}

\LMHash{}%
Assume that a literal collection \metavar{target} is given,
and the object sequence obtained as described below will be used
to populate \metavar{target}.
Let $T_{\metavar{target}}$ denote the dynamic type of \metavar{target}.

\commentary{%
  Access to the type of \metavar{target} is needed below
  in order to raise dynamic errors at specific points during
  the evaluation of an object sequence.
  Note that the dynamic type of \metavar{target} is statically known,
  except for the binding of any type variables in its \synt{typeArguments}.
  This implies that some questions can be answered at compile-time, e.g.,
  whether or not \code{Iterable} occurs as a superinterface of
  $T_{\metavar{target}}$.
  In any case, $T_{\metavar{target}}$ is guaranteed to implement
  \code{Iterable} (when \metavar{target} is a list or a set)
  or \code{Map} (when \metavar{target} is a map),
  but never both.%
}

\LMHash{}%
Assume that a location in code and a dynamic context is given,
such that ordinary expression evaluation is possible.
\IndexCustom{Evaluation of a collection literal element sequence}{%
  collection literal element!evaluation of sequence}
at that location and in that context is specified as follows:

\LMHash{}%
Let $s_{\metavar{syntax}}$ of the form \List{\ell}{1}{k} be
a sequence of collection literal elements.
The sequence of objects $s_{\metavar{object}}$
obtained by evaluating $s_{\metavar{syntax}}$
is the concatenation of the sequences of objects
obtained by evaluating each element $\ell_j$, $j \in 1 .. k$:
$s_{\metavar{object}}=\EvaluateElement{\ell_1}+\ldots+\EvaluateElement{\ell_k}$,
where \EvaluateElement{\ell_j} denotes the object sequence yielded by
evaluation of a single collection literal element $\ell_j$.

\LMHash{}%
When a pseudo-statement of the form
\code{$s := s + \EvaluateElement{\ell}$;}
is used in normative code below,
it denotes the extension of $s$ with the object sequence
yielded by evaluation of $\ell$,
but it also denotes the specification of actions taken to produce
said object sequence,
and to produce the side effects associated with this computation,
as implied by evaluation of expressions and execution of statements
as specified below for the evaluation of \EvaluateElement{\ell}.

\LMHash{}%
When a pseudo-statement of the form
\code{$\EvaluateElement{\ell} := s$;}
occurs in normative code below,
it occurs at a point where the computation is complete
and it specifies that the value of \EvaluateElement{\ell} is $s$.
\IndexCustom{Evaluation of a collection literal element $\ell$}{%
  collection literal element!evaluation}
in the given context
to an object sequence
\IndexCustom{\EvaluateElement{\ell}}{%
  evaluateElement(l)@\emph{evaluateElement}\code{($\ell$)}}
is then specified as follows:

\LMHash{}%
\Case{Expression element}
In this case $\ell$ is an expression $e$;
$e$ is evaluated to an object $o$
and $\EvaluateElement{\ell} := \LiteralSequence{o}$.
\EndCase

\LMHash{}%
\Case{Map element}
In this case $\ell$ is pair of expressions
\code{$e_1$:$e_2$};
first $e_1$ is evaluated to an object $o_1$,
then $e_2$ is evaluated to an object $o_2$,
and $\EvaluateElement{\ell} := \LiteralSequence{o_1:o_2}$.
\EndCase

\LMHash{}%
\Case{Spread element}
The element $\ell$ is of the form `\code{...$e$}' or `\code{...?$e$}'.
Evaluate $e$ to an object $o_{\metavar{spread}}$.

\begin{enumerate}
\item
  When $\ell$ is `\code{...$e$}':
  %% TODO(eernst): Come NNBD, this error cannot occur any more: delete.
  If $o_{\metavar{spread}}$ is the null object then a dynamic error occurs.
  Otherwise evaluation proceeds with step 2.

  When $\ell$ is `\code{...?$e$}':
  If $o_{\metavar{spread}}$ is the null object then
  $\EvaluateElement{\ell} := \LiteralSequence{}$.
  Otherwise evaluation proceeds with step 2.
\item
  Let $T_{\metavar{spread}}$ be the dynamic type of $o_{\metavar{spread}}$.
  Let $S$ be the static type of $e$.
  When $S$ is not a top type
  (\ref{superBoundedTypes}),
  let $S_{\metavar{spread}}$ be $S$.
  When $S$ is a top type:
  If \metavar{target} is a list or a set then
  let $S_{\metavar{spread}}$ be \code{Iterable<\DYNAMIC>};
  otherwise
  \commentary{(where \metavar{target} is a map)},
  let $S_{\metavar{spread}}$ be \code{Map<\DYNAMIC,\,\,\DYNAMIC>}.

  \begin{itemize}
  \item
    When \metavar{target} is a list or a set
    and $T_{\metavar{spread}}$ implements
    (\ref{interfaceSuperinterfaces})
    \code{Iterable},
    the following code is executed in the context where $\ell$ occurs,
    where \code{spread}, $s$, \code{v}, and \code{value} are fresh variables,
    and \code{Value} is a fresh type variable bound to the
    actual type argument of $T_{\metavar{target}}$ at \code{Iterable}
    (\ref{interfaceSuperinterfaces}):

    \vspace{-2ex}\begin{minipage}[t]{\textwidth}
\begin{normativeDartCode}
$S_{\metavar{spread}}$ spread = $o_{\metavar{spread}}$;
\VAR{} $s$ = \LiteralSequence;
\FOR{} (\VAR{} v \IN{} spread) \{
  Value value = v;
  $s := s + \LiteralSequence{\code{value}}$;
\}
$\EvaluateElement{\ell} := s$;
\end{normativeDartCode}
    \end{minipage}

    \commentary{%
      The code makes use of a pseudo-variable $s$ denoting an object sequence.
      We do not specify the type of $s$,
      this variable is only used to indicate the required
      semantic actions taken to gather the resulting object sequence.
      In the case where the implementation does not have
      a representation of $s$ at all,
      the action may be to extend \metavar{target} immediately.
      A similar approach is used in subsequent cases.%
    }
  \item
    When \metavar{target} is a map and $T_{\metavar{spread}}$ implements
    \code{Map},
    the following code is executed in the context where $\ell$ occurs,
    where \code{spread}, $s$, \code{v}, \code{key}, and \code{value}
    are fresh variables,
    and \code{Key} and \code{Value} are fresh type variables bound to the
    first respectively second actual type argument
    of $T_{\metavar{target}}$ at \code{Map}:

    \vspace{-2ex}\begin{minipage}[t]{\textwidth}
\begin{normativeDartCode}
$S_{\metavar{spread}}$ spread = $o_{\metavar{spread}}$;
\VAR{} $s$ = \LiteralSequence;
\FOR{} (\VAR{} v \IN{} spread) \{
  Key key = v.key;
  Value value = v.value;
  $s := s + \LiteralSequence{\code{key}:\,\code{value}}$;
\}
$\EvaluateElement{\ell} := s$;
\end{normativeDartCode}
    \end{minipage}

    % Will not change with nnbd: `spread` type arguments could be \DYNAMIC.
    It is allowed for an implementation to delay the dynamic errors
    that occur if the given \code{key} does not have the type \code{Key},
    or the given \code{value} does not have the type \code{Value},
    but it cannot occur after the pair has been appended to $s$.
  \item
    Otherwise, a dynamic error occurs.

    \commentary{%
      This occurs when the target is an iterable respectively a map,
      and the spread is not, which is possible for
      a spread whose static type is \DYNAMIC.%
    }
  \end{itemize}
\end{enumerate}

\rationale{%
  This may not be the most efficient way to traverse the items in a collection,
  and implementations may of course use any other approach
  with the same observable behavior.
  However, in order to give implementations more room to optimize
  we also allow the following.%
}

\LMHash{}%
If $o_{\metavar{spread}}$ is an object whose dynamic type implements
(\ref{interfaceSuperinterfaces})
\code{List}, \code{Queue}, or \code{Set},
an implementation may choose to call \code{length} on the object.
If $o_{\metavar{spread}}$ is an object
whose dynamic type implements \code{List},
an implementation may choose to call operator \lit{[]}
in order to access elements from the list.
If it does so, it will only pass indices
that are non-negative and less than the value returned by \code{length}.

\rationale{%
  This may allow for more efficient code for
  allocating the collection and accessing its parts.
  The given classes are expected to have
  an efficient and side-effect free implementation
  of \code{length} and operator \lit{[]}.
  A Dart implementation may detect whether these options apply
  at compile time based on the static type of $e$,
  or at runtime based on the actual value.%
}
\EndCase

\LMHash{}%
\Case{If element}
When $\ell$ is an \synt{ifElement} of the form
\code{\IF\,\,($b$)\,\,$\ell_1$} or
\code{\IF\,\,($b$)\,\,$\ell_1$\,\,\ELSE\,\,$\ell_2$},
the condition $b$ is evaluated to a value $o_b$.
If $o_b$ is \TRUE{} then
$\EvaluateElement{\ell} := \EvaluateElement{\ell_1}$.
If $o_b$ is \FALSE{} and $\ell_2$ is present then
$\EvaluateElement{\ell} := \EvaluateElement{\ell_2}$,
and if $\ell_2$ is not present then
$\EvaluateElement{\ell} := \LiteralSequence{}$.
% $o_b$ can have type \DYNAMIC.
If $o_b$ is neither \TRUE{} nor \FALSE{} then a dynamic error occurs.
\EndCase

\LMHash{}%
\Case{For element}
Let $P$ be derived from \syntax{<forLoopParts>} and
let $\ell$ be a \synt{forElement} of the form
\code{\AWAIT?\,\,\FOR\,\,($P$)\,\,$\ell_1$},
where `\AWAIT?' indicates that \AWAIT{} may be present or absent.
To evaluate $\ell$,
the following code is executed in the context where $\ell$ occurs,
where \AWAIT{} is present if and only if it is present in $\ell$:

\vspace{-2ex}\begin{minipage}[t]{\textwidth}
\begin{normativeDartCode}
\VAR{} $s$ = \LiteralSequence;
\AWAIT? \FOR{} ($P$) \{
  $s := s + \EvaluateElement{\ell_1}$;
\}
$\EvaluateElement{\ell} := s$;
\end{normativeDartCode}
\end{minipage}
\EndCase


\subsubsection{List Literal Inference}
\LMLabel{listLiteralInference}

\LMHash{}%
This section specifies how a list literal \metavar{list} is traversed and an
\IndexCustom{inferred element type}{list literal!element type}
for \metavar{list} is determined.
We specify first how to infer the element type of a single element,
then how to use that result to infer
the element type of \metavar{list} as a whole.

\LMHash{}%
The context type $P$
(\ref{setAndMapLiteralDisambiguation})
for each element of \metavar{list} is
obtained from the context type of \metavar{list}.
If downwards inference constrains the type of \metavar{list}
to \code{List<$P_e$>} or \code{Iterable<$P_e$>} for some $P_e$
then $P$ is $P_e$.
Otherwise, $P$ is \FreeContext{}
(\ref{setAndMapLiteralDisambiguation}).

\LMHash{}%
Let $\ell$ be a term derived from \synt{element}.
Inference of the element type of $\ell$ with context type $P$
proceeds as follows,
where the context type for inference of an element type is always $P$,
unless anything is said to the contrary:

\LMHash{}%
\Case{Expression element}
In this case $\ell$ is an expression $e$.
The inferred element type of $\ell$ is
% The type of $e$ is not an element type, so we mention $P$.
the inferred type of $e$ in context $P$.
\EndCase

\LMHash{}%
\Case{Map element}
% We cannot really tell whether this or the error in \ref{lists} arises first
% (say, when the list literal has an explicit type argument, it is not
% guaranteed that the implementation performs type inference on it at all).
% So we _must_ specify the error in \ref{lists}, and this location should
% then be a commentary, because we already have the error elsewhere.
\commentary{%
  This cannot occur:
  it is a compile-time error
  when a leaf element of a list literal is a map element
  (\ref{lists}).%
}
\EndCase

\LMHash{}%
\Case{Spread element}
Let $e$ be the expression of $\ell$.
If $\ell$ is `\code{...$e$}',
let $S$ be the inferred type of $e$ in context \code{Iterable<$P$>}.
Otherwise
\commentary{(when $\ell$ is `\code{...?$e$}')},
%% TODO(eernst): Come NNBD, add a \ref{} to the specification of
%% 'the non-nullable type of'.
let $S$ be the non-nullable type of
%% TODO(eernst): Clarify whether inference will indeed have that context;
%% it is clear that we need to eliminate `Null` from $S$, and also that $e$
%% is allowed to have a potentially nullable type, and it seems inconvenient
%% if we use `Iterable<$P$>` as context type and fail in the case where $e$,
%% say, has type `List<$U$>?` for some $U$.
the inferred type of $e$ in context \code{Iterable<$P$>?}.

\begin{itemize}
\item
  If $S$ implements \code{Iterable},
  the inferred element type of $\ell$ is
  the type argument of $S$ at \code{Iterable}.
\item
  If $S$ is \DYNAMIC,
  the inferred element type of $\ell$ is \DYNAMIC.
\item
  If $S$ is \code{Null} and the spread operator is \lit{...?},
  the inferred element type of $\ell$ is \code{Null}.
\item
  Otherwise, a compile-time error occurs.
\end{itemize}
\vspace{-5mm}
\EndCase

\LMHash{}%
\Case{If element}
In this case $\ell$ is of the form
\code{\IF\,\,($b$)\,\,$\ell_1$} or
\code{\IF\,\,($b$)\,\,$\ell_1$\,\,\ELSE\,\,$\ell_2$}.
The condition $b$ is always inferred with a context type of \code{bool}.

Assume that `\code{\ELSE\,\,$\ell_2$}' is not present.
Then, if the inferred element type of $\ell_1$ is $S$,
the inferred element type of $\ell$ is $S$.

Otherwise, `\code{\ELSE\,\,$\ell_2$}' is present.
If the inferred element type of $\ell_1$ is $S_1$ and
the inferred element type of $\ell_2$ is $S_2$,
the inferred element type of $\ell$ is
the least upper bound of $S_1$ and $S_2$.
\EndCase

\LMHash{}%
\Case{For element}
In this case $\ell$ is of the form
\code{\AWAIT?\,\,\FOR\,\,($P$)\,\,$\ell_1$}
where $P$ is derived from \synt{forLoopParts} and
`\AWAIT?' indicates that \AWAIT{} may be present or absent.

The same compile-time errors occur for $\ell$ as
the errors that would occur with the corresponding \FOR{} statement
\code{\AWAIT?\,\,\FOR\,\,($P$)\,\,\{\}},
located in the same scope as $\ell$.
Moreover, the errors and type analysis of $\ell$ is performed
as if it occurred in the body scope of said \FOR{} statement.
\commentary{%
  For instance, if $P$ is of the form
  \code{\VAR\,\,v\,\,\IN\,\,$e_1$}
  then the variable \code{v} is in scope for $\ell$.%
}

Inference for the parts
\commentary{%
  (such as the iterable expression of a for-in,
  or the \synt{forInitializerStatement} of a for loop)%
}
is done as for the corresponding \FOR{} statement,
including \AWAIT{} if and only if the element includes \AWAIT.
Then, if the inferred element type of $\ell_1$ is $S$,
the inferred element type of $\ell$ is $S$.

\commentary{%
  In other words, inference flows upwards from the body element.%
}
\vspace{3mm}
\EndCase

\LMHash{}%
Finally, we define
\IndexCustom{type inference on a list literal}{%
  type inference!list literal}
as a whole.
Assume that \metavar{list} is derived from \synt{listLiteral}
and contains the elements \List{\ell}{1}{n},
and the context type for \metavar{list} is $P$.

\begin{itemize}
\item
  If $P$ is \FreeContext{} then
  the inferred element type for \metavar{list} is $T$,
  where $T$ is the least upper bound of
  the inferred element types of \List{\ell}{1}{n}.

\item
  %% TODO(eernst): Feature spec says $P$, but how do we know $P$ is a type?
  Otherwise,
  the inferred element type for \metavar{list} is $T$,
  where $T$ is determined by downwards inference.
\end{itemize}

\LMHash{}%
In both cases, the static type of \metavar{list} is \code{List<$T$>}.


\subsubsection{Lists}
\LMLabel{lists}

\LMHash{}%
A \IndexCustom{list literal}{literal!list}
denotes a list object, which is an integer indexed collection of objects.
The grammar rule for \synt{listLiteral} is specified elsewhere
(\ref{collectionLiterals}).

\LMHash{}%
When a given list literal $e$ has no type arguments,
the type argument $T$ is selected as specified elsewhere
(\ref{listLiteralInference}),
and $e$ is henceforth treated as
(\ref{notation})
\code{<$T$>$e$}.

\commentary{%
  The static type of a list literal of the form \code{<$T$>$e$}
  is \code{List<$T$>}
  (\ref{listLiteralInference}).%
}

\LMHash{}%
Let $e$ be a list literal of the form
\code{<$T$>[\List{\ell}{1}{m}]}.
It is a compile-time error if a leaf element of $e$ is a
\synt{mapElement}.
It is a compile-time error if, for some $j \in 1 .. m$,
$\ell_j$ does not have an element type,
or the element type of $\ell_j$ may not be assigned to $T$.

\LMHash{}%
A list may contain zero or more objects.
The number of objects in a list is its size.
A list has an associated set of indices.
An empty list has an empty set of indices.
A non-empty list has the index set $\{0, \ldots, n - 1\}$
where $n$ is the size of the list.
It is a dynamic error to attempt to access a list
using an index that is not a member of its set of indices.

\rationale{%
  The system libraries define many members for the type \code{List},
  but we specify only the minimal set of requirements
  which are used by the language itself.%
}

\LMHash{}%
If a list literal $e$ begins with the reserved word \CONST{}
or $e$ occurs in a constant context
(\ref{constantContexts}),
it is a
\IndexCustom{constant list literal}{literal!list!constant},
which is a constant expression
(\ref{constants})
and therefore evaluated at compile time.
Otherwise, it is a
\IndexCustom{run-time list literal}{literal!list!run-time}
and it is evaluated at run time.
Only run-time list literals can be mutated
after they are created.
% This error can occur because being constant is a dynamic property.
Attempting to mutate a constant list literal will result in a dynamic error.

\commentary{%
  % The following is true either directly or indirectly: There is a \CONST{}
  % modifier on the list literal, or the list literal as a whole occurs
  % in a constant context.
  Note that the collection literal elements of a constant list literal
  occur in a constant context
  (\ref{constantContexts}),
  which means that \CONST{} modifiers need not be specified explicitly.%
}

\LMHash{}%
It is a compile-time error
if an element of a constant list literal is not constant.
It is a compile-time error if the type argument of a constant list literal
\commentary{(no matter whether it is explicit or inferred)}
is not a constant type expression
(\ref{constants}).

\rationale{%
  The binding of a formal type parameter of an enclosing class or function
  is not known at compile time,
  so we cannot use such type parameters inside constant expressions.%
}

\LMHash{}%
The value of a constant list literal
\code{\CONST?\,\,<$T$>[\List{\ell}{1}{m}]}
is an object $o$ whose class implements the built-in class
\code{List<$t$>}
where $t$ is the actual value of $T$
(\ref{actualTypes}),
and whose contents is the object sequence \List{o}{1}{n} obtained by
evaluation of \List{\ell}{1}{m}
(\ref{collectionLiteralElementEvaluation}).
The $i$th object of $o$ (at index $i - 1$) is then $o_i$.

\LMHash{}%
Let \code{\CONST?\,\,<$T_1$>[$\ell_{11}, \ldots, \ell_{1m_1}$]}
and \code{\CONST?\,\,<$T_2$>[$\ell_{21}, \ldots, \ell_{2m_2}$]}
be two constant list literals.
Let $o_1$ with contents $o_{11}, \ldots, o_{1n}$ and actual type argument $t_1$
respectively
$o_2$ with contents $o_{21}, \ldots, o_{2n}$ and actual type argument $t_2$
be the result of evaluating them.
Then \code{identical($o_1$, $o_2$)} evaluates to \TRUE{} if{}f
\code{$t_1$ == $t_2$} and \code{identical($o_{1i}$, $o_{2i}$)}
evaluates to \TRUE{} for all $i \in 1 .. n$.

\commentary{%
  In other words, constant list literals are canonicalized.
  There is no need to consider canonicalization
  for other instances of type \code{List},
  because such instances cannot be
  the result of evaluating a constant expression.%
}

\LMHash{}%
A run-time list literal
\code{<$T$>[\List{\ell}{1}{m}]}
is evaluated as follows:

\begin{itemize}
\item
  The elements \List{\ell}{1}{m} are evaluated
  (\ref{collectionLiteralElementEvaluation}),
  to an object sequence \LiteralSequence{\List{o}{1}{n}}.
\item
  A fresh instance (\ref{generativeConstructors}) $o$, of size $n$,
  whose class implements the built-in class \code{List<$t$>}
  is allocated,
  where $t$ is the actual value of $T$
  (\ref{actualTypes}).
\item
  The operator \lit{[]=} is invoked on $o$ with
  first argument $i$ and second argument
  $o_{i+1}, 0 \le i < n$.
\item
  The result of the evaluation is $o$.
\end{itemize}

\LMHash{}%
The objects created by list literals do not override
the \lit{==} operator inherited from the \code{Object} class.

\commentary{%
  Note that this document does not specify an order
  in which the elements are set.
  This allows for parallel assignments into the list
  if an implementation so desires.
  The order can only be observed as follows (and may not be relied upon):
  if element $i$ is not a subtype of the element type of the list,
  a dynamic type error will occur when $a[i]$ is assigned $o_{i-1}$.%
}


\subsubsection{Set and Map Literal Disambiguation}
\LMLabel{setAndMapLiteralDisambiguation}

\LMHash{}%
Some terms like \code{\{\}} and \code{\{\,...\id\,\}} are ambiguous:
they may be either a set literal or a map literal.
This ambiguity is eliminated in two steps.
The first step uses only the syntax and context type,
%% TODO(eernst): Enable this reference when 'context type' gets defined.
%% (\ref{contextType})
and is described in this section.
The second step uses expression types and is described next
(\ref{setAndMapLiteralInference}).

\LMHash{}%
Let $e$ be a \synt{setOrMapLiteral}
with leaf elements $\cal L$ and context type $C$.
If $C$ is \FreeContext{} then let $S$ be undefined.
%% TODO(eernst): Define `greatest closure' of a context type
%% when we define `context type'.
Otherwise let $S$ be the greatest closure of \futureOrBase{C}
(\ref{typeFutureOr}).

%% TODO(eernst): Delete when `context type', `greatest closure' are defined.
\commentary{%
  A future version of this document will specify context types.
  The basic intuition is that a
  \Index{context type}
  is the type declared for a
  receiving entity such as
  a formal parameter $p$ or a declared variable $v$.
  That type will be the context type for
  an actual argument passed to $p$,
  respectively an initializing expression for $v$.
  In some situations the context has no constraints,
  e.g., when a variable is declared with \VAR{} rather than a type annotation.
  This gives rise to an
  \IndexCustom{unconstrained context type}{context type!unconstrained},
  \IndexCustom{\rm\FreeContext}{[]@\FreeContext},
  which may also occur in a composite term, e.g., \code{List<\FreeContext>}.
  %% TODO(eernst): Clarify why we do not just use i2b, rather than
  %% introducing the notion of a greatest (and least) closure.
  The greatest closure of a context type $C$ is
  approximately the least common supertype of all types
  obtainable by replacing \FreeContext{} by a type.%
}

\LMHash{}%
The disambiguation step of this section is
the first applicable entry in the following list:

\begin{itemize}
\item When $e$ has type arguments \List{T}{1}{k}, $k > 0$:
  If $k = 1$ then $e$ is a set literal with static type
  \code{Set<$T_1$>}.
  If $k = 2$ then $e$ is a map literal with static type
  \code{Map<$T_1$,\,\,$T_2$>}.
  Otherwise a compile-time error occurs.
\item
  When $S$ implements
  (\ref{interfaceSuperinterfaces})
  \code{Iterable} but not \code{Map},
  $e$ is a set literal.
  When $S$ implements \code{Map} but not \code{Iterable},
  $e$ is a map literal.
\item
  When ${\cal L} \not= \emptyset$
  \commentary{(that is, $e$ has leaf elements)}:
  If $\cal L$ contains a \synt{mapElement}
  as well as an \synt{expressionElement},
  a compile-time error occurs.
  Otherwise, if $\cal L$ contains an \synt{expressionElement},
  $e$ is a set literal.
  Otherwise $\cal L$ contains a \synt{mapElement}, and $e$ is a map literal.
\item
  When $e$ is of the form \code{\{\}} and $S$ is undefined,
  $e$ is a map literal.
  \rationale{%
    There is no deeper reason for this choice,
    but the fact that \code{\{\}} is a map by default
    was useful when set literals were introduced,
    because it would be a breaking change to make it a set.%
  }
\item
  Otherwise, $e$ is still ambiguous.
  \commentary{%
    In this case $e$ is non-empty, but contains only spreads
    wrapped zero or more times in \synt{ifElement}s or \synt{forElement}s.
    Disambiguation will then occur during inference
    (\ref{setAndMapLiteralInference}).%
  }
\end{itemize}

\commentary{%
  When this step does not determine a static type,
  it will be determined by type inference
  (\ref{setAndMapLiteralInference}).%
}

\LMHash{}%
If this process successfully disambiguates the literal
then we say that $e$ is
\IndexCustom{unambiguously a set}{set!unambiguously}
or
\IndexCustom{unambiguously a map}{map!unambiguously},
as appropriate.


\subsubsection{Set and Map Literal Inference}
\LMLabel{setAndMapLiteralInference}

\LMHash{}%
This section specifies how a \synt{setOrMapLiteral} $e$ is traversed
and an associated
\IndexCustom{inferred element type}{set or map literal!element type}
and/or an associated
\IndexCustom{inferred key and value type pair}{%
  set or map literal!key and value type pair}
is determined.

\commentary{%
  If $e$ has an element type then it may be a set,
  and if it has a key and value type pair then it may be a map.
  %
  However, if the literal $e$ contains a spread element of type \DYNAMIC,
  that element cannot be used to determine whether $e$ is a set or a map.
  The ambiguity is represented as having \emph{both}
  an element type and a key and value type pair.

  It is an error if the ambiguity is not resolved by some other elements,
  but if it is resolved then the dynamic spread element is required
  to evaluate to a suitable instance
  (implementing \code{Iterable} when $e$ is a set,
  and implementing \code{Map} when $e$ is a map),
  which means that it is a dynamic error if there is a mismatch.
  In other situations it is a compile-time error to have both
  an element type and a key and value type pair,
  because $e$ must be both a set and a map.
  Here is an example:%
}

\begin{dartCode}
\DYNAMIC{} x = <int, int>\{\};
Iterable l = [];
Map m = \{\};
\\
\VOID{} main() \{
  \VAR v1 = \{...x\};       // \comment{Compile-time error: ambiguous}
  \VAR v2 = \{...x, ...l\}; // \comment{A set, dynamic error when `x` is evaluated}
  \VAR v3 = \{...x, ...m\}; // \comment{A map, no dynamic errors}
  \VAR v4 = \{...l, ...m\}; // \comment{Compile-time error: must be set and map}
\}
\end{dartCode}

\LMHash{}%
Let \metavar{collection} be a collection literal
derived from \synt{setOrMapLiteral}.
The inferred type of an \synt{element} is an element type $T$,
a pair of a key and value type $(K, V)$, or both.
It is computed relative to a context type $P$
(\ref{setAndMapLiteralDisambiguation}),
which is determined as follows:

\begin{itemize}
\item
  If \metavar{collection} is unambiguously a set
  (\ref{setAndMapLiteralDisambiguation})
  then $P$ is \code{Set<$P_e$>},
  %% TODO(eernst): Add reference when we specify inference.
  where $P_e$ is determined by downwards inference,
  and may be \FreeContext{}
  %% TODO(eernst): Correct this reference when we specify context types.
  (\ref{setAndMapLiteralDisambiguation})
  if downwards inference does not constrain it.

  %% TODO(eernst): Remove this when we specify inference.
  \commentary{%
    A future version of this document will specify inference,
    the notion of downwards inference,
    and constraining.
    The brief intuition is that inference selects values for
    type parameters in generic constructs
    where no type arguments have been provided,
    aiming at a type which matches a given context type;
    downwards inference does this by passing information
    from a given expression into its subexpressions,
    and upwards inference propagates information in the opposite direction.
    Constraints are expressed in terms of context types;
    being unconstrained means having \FreeContext{} as the context type.
    Having a context type that \emph{contains}
    one or more occurrences of \FreeContext{}
    provides a partial constraint on the inferred type.%
  }
\item
  If \metavar{collection} is unambiguously a map
  then $P$ is \code{Map<$P_k$,\,\,$P_v$>}
  where $P_k$ and $P_v$ are determined by downwards inference,
  and may be \FreeContext{}
  if the downwards context does not constrain one or both.
\item
  Otherwise, \metavar{collection} is ambiguous,
  and the downwards context for the elements of \metavar{collection}
  is \FreeContext.
\end{itemize}

\LMHash{}%
We say that a collection literal element
\IndexCustom{can be a set}{collection literal element!can be a set}
if it has an element type;
it
\IndexCustom{can be a map}{collection literal element!can be a map}
if it has a key and value type pair;
it
\IndexCustom{must be a set}{collection literal element!must be a set}
if it can be a set and has and no key and value type pair;
and it
\IndexCustom{must be a map}{collection literal element!must be a map}
if can be a map and has no element type.

\LMHash{}%
Let $\ell$ be a term derived from \synt{element}.
\IndexCustom{Inference of the type of}{%
  type inference!collection literal element}
$\ell$ with context type $P$ then proceeds
as follows:

\LMHash{}%
\Case{Expression element}
In this case $\ell$ is an expression $e$.
%
If $P$ is \FreeContext,
the inferred element type of $\ell$ is
the inferred type of $e$ in context \FreeContext.
%
If $P$ is \code{Set<$P_e$>},
the inferred element type of $\ell$ is
the inferred type of $e$ in context $P_e$.
\EndCase

\LMHash{}%
\Case{Map element}
In this case $\ell$ is a pair of expressions \code{$e_k$:\,$e_v$}.
%
If $P$ is \FreeContext,
the inferred key and value type pair of $\ell$ is $(K, V)$,
where $K$ and $V$ is
the inferred type of $e_k$ respectively $e_v$,
in context \FreeContext.
%
If $P$ is \code{Map<$P_k$,\,\,$P_v$>},
the inferred key and value type pair of $\ell$ is $(K, V)$,
where $K$ is
the inferred type of $e_k$ in context $P_k$, and
the $V$ is
the inferred type of $e_v$ in context $P_v$.
\EndCase

\LMHash{}%
\Case{Spread element}
In this case $\ell$ is of the form
`\code{...$e$}' or `\code{...?$e$}'.
If $P$ is \FreeContext{} then let $S$ be
the inferred type of $e$ in context \FreeContext.
Then:

\begin{itemize}
\item
  If $S$ implements \code{Iterable},
  the inferred element type of $\ell$ is
  the type argument of $S$ at \code{Iterable}.

  \commentary{%
    This is the result of constraint matching for $X$
    using the constraint $S\,\,<:\,\,\code{Iterable<$X$>}$.
    Note that when $S$ implements a class like \code{Map} or \code{Iterable},
    it cannot be a subtype of \code{Null}
    (\ref{interfaceSuperinterfaces}).%
  }
\item
  If $S$ implements \code{Map},
  the inferred key and value type pair of $\ell$ is $(K, V)$,
  where $K$ is the first and $V$ the second type argument
  of $S$ at \code{Map}.

  \commentary{%
    This is the result of constraint matching for $X$ and $Y$ using
    the constraint $S\,\,<:\,\,\code{Map<$X$,\,\,$Y$>}$.%

    Note that this case and the previous case
    can match on the same element simultaneously
    when $S$ implements both \code{Iterable} and \code{Map}.
    The same situation arises several times below.
    In such cases we rely on other elements to disambiguate.%
  }
\item
  If $S$ is \DYNAMIC{} then
  the inferred element type of $\ell$ is \DYNAMIC,
  and the inferred key and value type pair of $\ell$ is
  $(\DYNAMIC, \DYNAMIC)$.

  \commentary{%
    We produce both an element type and a key and value type pair here,
    and rely on other elements to disambiguate.%
  }
\item
  If $S$ is \code{Null} and the spread operator is \lit{...?} then
  the inferred element type of $\ell$ is \code{Null},
  and the inferred key and value type pair $(\code{Null}, \code{Null})$.
\item
  Otherwise, a compile-time error occurs.
\end{itemize}

\noindent
%% TODO(eernst): Clarify why we shouldn't be able to use a context type of
%% `Iterable<$P_e$>` in the same way: infer $e$ in context `Iterable<$P_e$>`
%% as well.
Otherwise, if $P$ is \code{Set<$P_e$>} then let $S$ be
the inferred type of $e$ in context \code{Iterable<$P_e$>}, and then:

\begin{itemize}
\item
  If $S$ implements \code{Iterable},
  the inferred element type of $\ell$ is
  the type argument of $S$ at \code{Iterable}.
  \commentary{%
    This is the result of constraint matching for $X$ using
    the constraint $S <: \code{Iterable<$X$>}$.%
  }
\item
  If $S$ is \DYNAMIC,
  the inferred element type of $\ell$ is \DYNAMIC.
\item
  If $S$ is \code{Null} and the spread operator is \lit{...?},
  the inferred element type of $\ell$ is \code{Null}.
\item
  Otherwise, a compile-time error occurs.
\end{itemize}

\noindent
Otherwise, if $P$ is \code{Map<$P_k$,\,\,$P_v$>} then let $S$ be
the inferred type of $e$ in context $P$, and then:

\begin{itemize}
\item
  If $S$ implements \code{Map},
  the inferred key and value type pair of $\ell$ is $(K, V)$,
  where $K$ is the first and $V$ the second type argument of
  $S$ at \code{Map}.
  \commentary{%
    This is the result of constraint matching for $X$ and $Y$ using
    the constraint \code{$S$ <: Map<$X$,\,\,$Y$>}.%
  }
\item
  If $S$ is \DYNAMIC,
  the inferred key and value type pair of $\ell$ is

  \noindent
  $(\DYNAMIC, \DYNAMIC)$.
\item
  If $S$ is \code{Null} and the spread operator is \lit{...?},
  the inferred key and value type pair $(\code{Null}, \code{Null})$.
\item
  Otherwise, a compile-time error occurs.
\end{itemize}
\vspace{-5mm}
\EndCase

\LMHash{}%
\Case{If element}
In this case $\ell$ is of the form
\code{\IF\,\,($b$)\,\,$\ell_1$} or
\code{\IF\,\,($b$)\,\,$\ell_1$\,\,\ELSE\,\,$\ell_2$}.
The condition $b$ is always inferred with a context type of \code{bool}.

Assume that `\code{\ELSE\,\,$\ell_2$}' is not present. Then:

\begin{itemize}
\item
  If the inferred element type of $\ell_1$ is $S$,
  the inferred element type of $\ell$ is $S$.
\item
  If the inferred key and value type pair of $\ell_1$ is $(K, V)$,
  the inferred key and value type pair of $\ell$ is $(K, V)$.
\end{itemize}

Otherwise, `\code{\ELSE\,\,$\ell_2$}' is present.
It is a compile error if $\ell_1$ must be a set and $\ell_2$ must be a map,
or vice versa.

\commentary{%
  This means that one cannot spread a map on one branch and a set on the other.
  Since \DYNAMIC{} provides both an element type and a key and value type pair,
  a \DYNAMIC{} spread in either branch does not cause the error to occur.%
}

Then:

\begin{itemize}
\item
  If the inferred element type of $\ell_1$ is $S_1$ and
  the inferred element type of $\ell_2$ is $S_2$,
  the inferred element type of $\ell$ is
  the least upper bound of $S_1$ and $S_2$.
\item
  If the inferred key and value type pair of $e_1$ is
  $(K_1, V_1)$
  and the inferred key and value type pair of $e_2$ is
  $(K_2, V_2)$,
  the inferred key and value type pair of $\ell$ is
  $(K, V)$,
  where $K$ is the least upper bound of $K_1$ and $K_2$, and
  and $V$ is the least upper bound of $V_1$ and $V_2$.
\end{itemize}
\vspace{-5mm}
\EndCase

\LMHash{}%
\Case{For element}
In this case $\ell$ is of the form
\code{\AWAIT?\,\,\FOR\,\,($P$)\,\,$\ell_1$}
where $P$ is derived from \synt{forLoopParts} and
`\AWAIT?' indicates that \AWAIT{} may be present or absent.

The same compile-time errors occur for $\ell$ as
the errors that would occur with the corresponding \FOR{} statement
\code{\AWAIT?\,\,\FOR\,\,($P$)\,\,\{\}},
located in the same scope as $\ell$.
Moreover, the errors and type analysis of $\ell$ is performed
as if it occurred in the body scope of said \FOR{} statement.

\commentary{%
  For instance, if $P$ is of the form
  \code{\VAR\,\,v\,\,\IN\,\,$e_1$}
  then the variable \code{v} is in scope for $\ell$.%
}

Inference for the parts
\commentary{%
  (such as the iterable expression of a for-in,
  or the \synt{forInitializerStatement} of a for loop)%
}
is done as for the corresponding \FOR{} statement,
including \AWAIT{} if and only if the element includes \AWAIT.

\begin{itemize}
\item
  If the inferred element type of $\ell_1$ is $S$ then
  the inferred element type of $\ell$ is $S$.
\item
  If the inferred key and value type pair of $e_1$ is $(K, V)$,
  the inferred key and value type pair of $\ell$ is $(K, V)$.
\end{itemize}

\commentary{%
  In other words, inference flows upwards from the body element.%
}
\vspace{3mm}
\EndCase

\LMHash{}%
Finally, we define
\IndexCustom{type inference on a set or map literal}{%
  type inference!set or map literal}
as a whole.
Assume that \metavar{collection} is derived from \synt{setOrMapLiteral},
and the context type for \metavar{collection} is $P$.

\begin{itemize}
\item
  If \metavar{collection} is unambiguously a set:

  \begin{itemize}
  \item
    If $P$ is \FreeContext{} then
    the static type of \metavar{collection} is \code{Set<$T$>}
    where $T$ is the least upper bound of
    the inferred element types of the elements.
  \item
    %% TODO(eernst): Feature spec says $P$, but how do we know $P$ is a type?
    Otherwise, the static type of \metavar{collection} is $T$
    where $T$ is determined by downwards inference.

    \commentary{%
      Note that the inference will never produce a key and value type pair
      with the given context type.%
    }
  \end{itemize}

  The static type of \metavar{collection} is then \code{Set<$T$>}.
\item
  If \metavar{collection} is unambiguously a map
  where $P$ is \code{Map<$P_k$,\,\,$P_v$>} or $P$ is \FreeContext{}
  and the inferred key and value type pairs are
  \KeyValueTypeList{K}{V}{1}{n}:

  If $P_k$ is \FreeContext{} or $P$ is \FreeContext,
  the static key type of \metavar{collection} is $K$
  where $K$ is the least upper bound of \List{K}{1}{n}.
  Otherwise the static key type of \metavar{collection} is $K$
  where $K$ is determined by downwards inference.

  If $P_v$ is \FreeContext{} or $P$ is \FreeContext,
  the static value type of \metavar{collection} is $V$
  where $V$ is the least upper bound of \List{V}{1}{n}.
  Otherwise the static value type of \metavar{collection} is $V$
  where $V$ is determined by downwards inference.

  \commentary{%
    Note that inference will never produce a element type here
    given this downwards context.%
  }

  The static type of \metavar{collection} is then \code{Map<$K$,\,\,$V$>}.
\item
  Otherwise, \metavar{collection} is still ambiguous,
  the downwards context for the elements of \metavar{collection}
  is \FreeContext,
  and the disambiguation is done using
  the immediate elements of \metavar{collection} as follows:

  \begin{itemize}
  \item
    If all elements can be a set,
    and at least one element must be a set,
    then \metavar{collection} is a set literal with
    static type \code{Set<$T$>} where $T$ is
    the least upper bound of the element types of the elements.
  \item
    If all elements can be a map,
    and at least one element must be a map, then $e$ is
    a map literal with static type \code{Map<$K$,\,\,$V$>} where $K$ is
    the least upper bound of the key types of the elements and $V$ is
    the least upper bound of the value types.
  \item
    Otherwise, a compile-time error occurs.
    \commentary{In this case the literal cannot be disambiguated.}
  \end{itemize}
\end{itemize}

\commentary{%
  This last error can occur if the literal \emph{must} be both a set and a map.
  Here is an example:%
}

\begin{dartCode}
\VAR{} iterable = [1, 2];
\VAR{} map = \{1: 2\};
\VAR{} ambiguous = \{...iterable, ...map\}; // \comment{Compile-time error}
\end{dartCode}

\noindent
\commentary{%
  Or, if there is nothing indicates that it is \emph{either} a set or a map:%
}

\begin{dartCode}
\DYNAMIC{} dyn;
\VAR{} ambiguous = \{...dyn\}; // \comment{Compile-time error}
\end{dartCode}


\subsubsection{Sets}
\LMLabel{sets}

\LMHash{}%
A \IndexCustom{set literal}{literal!set} denotes a set object.
The grammar rule for \synt{setOrMapLiteral} which covers
set literals as well as map literals occurs elsewhere
(\ref{collectionLiterals}).
A set literal consists of zero or more collection literal elements
(\ref{collectionLiterals}).
A term derived from \synt{setOrMapLiteral}
may be a set literal or a map literal,
and it is determined via a disambiguation step
whether it is a set literal or a map literal
(\ref{setAndMapLiteralDisambiguation}, \ref{setAndMapLiteralInference}).

\LMHash{}%
When a given set literal $e$ has no type arguments,
the type argument $T$ is selected as specified elsewhere
(\ref{setAndMapLiteralInference}),
and $e$ is henceforth treated as
(\ref{notation})
\code{<$T$>$e$}.

\commentary{%
  The static type of a set literal of the form \code{<$T$>$e$}
  is \code{Set<$T$>}
  (\ref{setAndMapLiteralInference}).%
}

\LMHash{}%
Let $e$ be a set literal of the form
\code{<$T$>\{\List{\ell}{1}{m}\}}.
It is a compile-time error if a leaf element of $e$ is a
\synt{mapElement}.
It is a compile-time error if, for some $j \in 1 .. m$,
$\ell_j$ does not have an element type,
or the element type of $\ell_j$ may not be assigned to $T$.

\LMHash{}%
A set may contain zero or more objects.
Sets have a method which can be used to insert objects;
this will incur a dynamic error if the set is not modifiable.
Otherwise, when inserting an object $o_{\metavar{new}}$ into a set $s$,
if an object $o_{\metavar{old}}$ exists in $s$ such that
\code{$o_{\metavar{old}}$ == $o_{\metavar{new}}$} evaluates to \TRUE{}
then the insertion makes no changes to $s$;
if no such object exists,
$o_{\metavar{new}}$ is added to $s$;
in both cases the insertion completes successfully.

\LMHash{}%
A set is ordered: iteration over the elements of a set
occurs in the order the elements were added to the set.

\commentary{%
  The system libraries define many members for the type \code{Set},
  but we specify only the minimal set of requirements
  which are used by the language itself.%

  Note that an implementation may require
  consistent definitions of several members
  of a class implementing \code{Set} in order to work correctly.
  For instance, there may be a getter \code{hashCode} which is required
  to have a behavior which is in some sense consistent with operator \lit{==}.
  Such constraints are documented in the system libraries.%
}

\LMHash{}%
If a set literal $e$ begins with the reserved word \CONST{}
or $e$ occurs in a constant context
(\ref{constantContexts}),
it is a
\IndexCustom{constant set literal}{literal!set!constant}
which is a constant expression
(\ref{constants})
and therefore evaluated at compile time.
Otherwise, it is a
\IndexCustom{run-time set literal}{literal!set!run-time}
and it is evaluated at run time.
Only run-time set literals can be mutated after they are created.
% This error can occur because being constant is a dynamic property, here.
Attempting to mutate a constant set literal will result in a dynamic error.

\commentary{%
  % The following is true either directly or indirectly: There is a \CONST{}
  % modifier on the literal set, or we use the "immediate subexpression" rule
  % about constant contexts.
  Note that the element expressions of a constant set literal
  occur in a constant context
  (\ref{constantContexts}),
  which means that \CONST{} modifiers need not be specified explicitly.%
}

\LMHash{}%
It is a compile-time error if
a collection literal element in a constant set literal
is not a constant expression.
It is a compile-time error if
an element in a constant set literal
does not have primitive equality
(\ref{theOperatorEqualsEquals}).
It is a compile-time error if two elements of a constant set literal are equal
according to their \lit{==} operator
(\ref{equality}).
It is a compile-time error if the type argument of a constant set literal
\commentary{(no matter whether it is explicit or inferred)}
is not a constant type expression
(\ref{constants}).

\rationale{%
  The binding of a formal type parameter of an enclosing class or function
  is not known at compile time,
  so we cannot use such type parameters inside constant expressions.%
}

\LMHash{}%
The value of a constant set literal
\code{\CONST?\,\,<$T$>\{\List{\ell}{1}{m}\}}
is an object $o$ whose class implements the built-in class
\code{Set<$t$>}
where $t$ is the actual value of $T$
(\ref{actualTypes}),
and whose contents is the set of objects in
the object sequence \List{o}{1}{n} obtained by
evaluation of \List{\ell}{1}{m}
(\ref{collectionLiteralElementEvaluation}).
The elements of $o$ occur in the same order as
the objects in said object sequence
\commentary{(which can be observed by iteration)}.

\LMHash{}%
Let \code{\CONST?\,\,<$T_1$>\{\,$\ell_{11}, \ldots, \ell_{1m_1}$\,\}}
and \code{\CONST?\,\,<$T_2$>\{\,$\ell_{21}, \ldots, \ell_{2m_2}$\,\}}
be two constant set literals.
Let $o_1$ with contents $o_{11}, \ldots, o_{1n}$ and actual type argument $t_1$
respectively
$o_2$ with contents $o_{21}, \ldots, o_{2n}$ and actual type argument $t_2$
be the result of evaluating them.
Then \code{identical($o_1$, $o_2$)} evaluates to \TRUE{} if{}f
%% TODO(eernst): Refer to nnbd notion of 'same type'.
\code{$t_1$ == $t_2$} and \code{identical($o_{1i}$, $o_{2i}$)}
evaluates to \TRUE{} for all $i \in 1 .. n$.

\commentary{%
  In other words, constant set literals are canonicalized if they have
  the same type argument and the same values in the same order.
  Two constant set literals are never identical
  if they have a different number of elements.
  There is no need to consider canonicalization
  for other instances of type \code{Set},
  because such instances cannot be
  the result of evaluating a constant expression.%
}

\LMHash{}%
A run-time set literal \code{<$T$>\{\List{\ell}{1}{n}\}}
is evaluated as follows:

\begin{itemize}
\item
  The elements \List{\ell}{1}{m} are evaluated
  (\ref{collectionLiteralElementEvaluation}),
  to an object sequence \LiteralSequence{\List{o}{1}{n}}.
\item
  A fresh object (\ref{generativeConstructors}) $o$
  implementing the built-in class \code{Set<$t$>} is created,
  where $t$ is the actual value of $T$
  (\ref{actualTypes}).
\item
  For each object $o_j$ in \List{o}{1}{n}, in order,
  $o_j$ is inserted into $o$.
  \commentary{%
    Note that this leaves $o$ unchanged when $o$ already contains
    and object $o$ which is equal to $o_j$ according to operator \lit{==}.%
  }
\item
  The result of the evaluation is $o$.
\end{itemize}

\LMHash{}%
The objects created by set literals do not override
the \lit{==} operator inherited from the \code{Object} class.


\subsubsection{Maps}
\LMLabel{maps}

\LMHash{}%
A \IndexCustom{map literal}{literal!map} denotes a map object,
which is a mapping from keys to values.
The grammar rule for \synt{setOrMapLiteral} which covers both
map literals and set literals occurs elsewhere
(\ref{collectionLiterals}).
A map literal consists of zero or more collection literal elements
(\ref{collectionLiterals}).
A term derived from \synt{setOrMapLiteral}
may be a set literal or a map literal,
and it is determined via a disambiguation step
whether it is a set literal or a map literal
(\ref{setAndMapLiteralDisambiguation}, \ref{setAndMapLiteralInference}).

\LMHash{}%
When a given map literal $e$ has no type arguments,
the type arguments $K$ and $V$ are selected as specified elsewhere
(\ref{setAndMapLiteralInference}),
and $e$ is henceforth treated as
(\ref{notation})
\code{<$K$,\,$V$>$e$}.

\commentary{%
  The static type of a map literal of the form \code{<$K$,\,$V$>$e$}
  is \code{Map<$K$,\,$V$>}
  (\ref{setAndMapLiteralInference}).%
}

\LMHash{}%
Let $e$ be a map literal of the form
\code{<$K$,\,$V$>\{\List{\ell}{1}{m}\}}.
It is a compile-time error if a leaf element of $e$ is an
\synt{expressionElement}.
It is a compile-time error if, for some $j \in 1 .. m$,
$\ell_j$ does not have a key and value type pair;
or the key and value type pair of $\ell_j$ is $(K_j, V_j)$,
and $K_j$ may not be assigned to $K$ or
$V_j$ may not be assigned to $V$.

\LMHash{}%
A map object consists of zero or more map entries.
Each entry has a \Index{key} and a \Index{value},
and we say that the map
\IndexCustom{binds}{map!binds} or
\IndexCustom{maps}{map!maps}
the key to the value.
A key and value pair is
added to a map using operator \lit{[]=},
and the value for a given key is retrieved from a map using operator \lit{[]}.
The keys of a map are treated similarly to a set
(\ref{sets}):
When binding a key $k_{\metavar{new}}$ to a value $v$ in a map $m$
\commentary{(as in \code{$m$[$k_{\metavar{new}}$]\,=\,$v$})},
if $m$ already has a key $k_{\metavar{old}}$ such that
\code{$k_{\metavar{old}}$ == $k_{\metavar{new}}$} evaluates to \TRUE,
$m$ will bind $k_{\metavar{old}}$ to $v$;
otherwise
\commentary{(when no such key $k_{\metavar{old}}$ exists)},
a binding from $k_{\metavar{new}}$ to $v$ is added to $m$.

\LMHash{}%
A map is ordered: iteration over the keys, values, or key/value pairs
occurs in the order in which the keys were added to the set.

\commentary{%
  The system libraries support many operations on an instance
  whose type implements \code{Map},
  but we specify only the minimal set of requirements
  which are used by the language itself.

  Note that an implementation may require
  consistent definitions of several members
  of a class implementing \code{Map} in order to work correctly.
  For instance, there may be a getter \code{hashCode} which is required
  to have a behavior which is in some sense consistent with operator \lit{==}.
  Such constraints are documented in the system libraries.%
}

\LMHash{}%
If a map literal $e$ begins with the reserved word \CONST,
or if $e$ occurs in a constant context
(\ref{constantContexts}),
it is a
\IndexCustom{constant map literal}{literal!map!constant}
which is a constant expression
(\ref{constants})
and therefore evaluated at compile time.
Otherwise, it is a
\IndexCustom{run-time map literal}{literal!map!run-time}
and it is evaluated at run time.
Only run-time map literals can be mutated after they are created.
% This error can occur because being constant is a dynamic property, here.
Attempting to mutate a constant map literal will result in a dynamic error.

\commentary{%
  % The following is true either directly or indirectly: There is a \CONST{}
  % modifier on the literal map, or we use the "immediate subexpression" rule
  % about constant contexts.
  Note that the key and value expressions of a constant map literal
  occur in a constant context
  (\ref{constantContexts}),
  which means that \CONST{} modifiers need not be specified explicitly.%
}

\LMHash{}%
It is a compile-time error
if a collection literal element in a constant map literal is not constant.
It is a compile-time error if
a key in a constant map literal
does not have primitive equality
(\ref{theOperatorEqualsEquals}).
It is a compile-time error if two keys of a constant map literal are equal
according to their \lit{==} operator
(\ref{equality}).
It is a compile-time error if a type argument of a constant map literal
\commentary{(no matter whether it is explicit or inferred)}
is not a constant type expression
(\ref{constants}).

\rationale{%
  The binding of a formal type parameter of an enclosing class or function
  is not known at compile time,
  so we cannot use such type parameters inside constant expressions.%
}

\LMHash{}%
The value of a constant map literal
\code{\CONST?\,\,<$T_1$,\,$T_2$>\{\List{\ell}{1}{m}\}}
is an object $o$ whose class implements the built-in class
\code{Map<$t_1$,\,\,$t_2$>},
where $t_1$ and $t_2$ is the actual value of $T_1$ respectively $T_2$
(\ref{actualTypes}).
The key and value pairs of $o$ is
the pairs of the object sequence \KeyValueList{k}{v}{1}{n} obtained by
evaluation of \List{\ell}{1}{m}
(\ref{collectionLiteralElementEvaluation}),
in that order.

\LMHash{}%
Let \code{\CONST?\,\,<$U_1$,\,$V_1$>\{\List{\ell}{1}{m_1}\}}
and \code{\CONST?\,\,<$U_2$,\,$V_2$>\{\List{\ell}{1}{m_2}\}}
be two constant map literals.
Let $o_1$ with contents \KeyValueList{k_1}{v_1}{1}{n}
and actual type arguments $u_1$, $v_1$
respectively
$o_2$ with contents \KeyValueList{k_2}{v_2}{1}{n}
and actual type argument $u_2$, $v_2$
be the result of evaluating them.
Then \code{identical($o_1$, $o_2$)} evaluates to \TRUE{} if{}f
\code{$u_1$ == $u_2$}, \code{$v_1$ == $v_2$},
\code{identical($k_{1i}$, $k_{2i}$)}, and
\code{identical($v_{1i}$, $v_{2i}$)}
for all $i \in 1 .. n$.

\commentary{%
  In other words, constant map literals are canonicalized.
  There is no need to consider canonicalization
  for other instances of type \code{Map},
  because such instances cannot be
  the result of evaluating a constant expression.%
}

\LMHash{}%
A run-time map literal
\code{<$T_1, T_2$>\{\List{\ell}{1}{m}\}}
is evaluated as follows:

\begin{itemize}
\item
  The elements \List{\ell}{1}{m} are evaluated
  (\ref{collectionLiteralElementEvaluation}),
  to an object sequence \LiteralSequence{\KeyValueList{k}{v}{1}{n}}.
\item
  A fresh instance (\ref{generativeConstructors}) $o$
  whose class implements the built-in class \code{Map<$t_1$,\,\,$t_2$>}
  is allocated,
  where $t_1$ and $t_2$ are the actual values of $T_1$ respectively $T_2$
  (\ref{actualTypes}).
\item
  The operator \lit{[]=} is invoked on $o$
  with first argument $k_i$ and second argument $v_i$,
  for each $i \in 1 .. n$, in that order.
\item
  The result of the evaluation is $o$.
\end{itemize}

\LMHash{}%
The objects created by map literals do not override
the \lit{==} operator inherited from the \code{Object} class.


\subsection{Throw}
\LMLabel{throw}

\LMHash{}%
The \Index{throw expression} is used to throw an exception.

\begin{grammar}
<throwExpression> ::= \THROW{} <expression>

<throwExpressionWithoutCascade> ::= \THROW{} <expressionWithoutCascade>
\end{grammar}

\LMHash{}%
Evaluation of a throw expression of the form
\code{\THROW{} $e$;}
proceeds as follows:

\LMHash{}%
The expression $e$ is evaluated to an object $v$
(\ref{expressionEvaluation}).

\commentary{%
  There is no requirement that the expression $e$ must evaluate to
  any special kind of object.%
}

\LMHash{}%
If $v$ is the null object (\ref{null}), then a \code{NullThrownError} is thrown.
Otherwise let $t$ be a stack trace corresponding to the current execution state,
and the \THROW{} statement throws with $v$ as exception object
and $t$ as stack trace (\ref{expressionEvaluation}).

\LMHash{}%
If $v$ is an instance of class \code{Error} or a subclass thereof,
and it is the first time that \code{Error} object is thrown,
the stack trace $t$ is stored on $v$ so that it will be returned
by the \code{stackTrace} getter inherited from \code{Error}.

\commentary{%
  If the same \code{Error} object is thrown more than once,
  its \code{stackTrace} getter will return the stack trace from
  the \emph{first} time it was thrown.%
}

\LMHash{}%
The static type of a throw expression is $\bot$.


\subsection{Function Expressions}
\LMLabel{functionExpressions}

\LMHash{}%
A \IndexCustom{function literal}{literal!function}
is an anonymous declaration and an expression
that encapsulates an executable unit of code.

%% TODO(eernst): This is highly ambiguous because <primary> derives
%% <functionExpression>. Dart.g derives <functionExpression> from
%% <expression> but only allows the block in <functionPrimary>, which
%% is derived from <primary>. It has <functionExpressionWithoutCascade>
%% as well, allowing for an `=>` function literal in a cascade assignment.
%% However, we need to assess the breakage very carefully before adopting
%% that approach, because it prevents function literals from being parsed
%% as conditionalExpression, ifNullExpression, ... postfixExpression.
\begin{grammar}
<functionExpression> ::= <formalParameterPart> <functionExpressionBody>

<functionExpressionBody> ::= \ASYNC? `=>' <expression>
  \alt (\ASYNC{} `*'? | \SYNC{} `*')? <block>
\end{grammar}

\LMHash{}%
The grammar does not allow a function literal to declare a return type,
but it is possible for a function literal to have a
\IndexCustom{declared return type}{literal!function!declared return type},
because it can be obtained by means of type inference.
Such a return type is included
when we refer to the declared return type of a function.

\commentary{%
  Type inference will be specified in a future version of this document.
  Currently we consider type inference to be a phase that has completed,
  and this document specifies the meaning of Dart programs
  where inferred types have already been added.%
}

\LMHash{}%
We say that a type $T$
\IndexCustom{derives a future type}{type!derives a future type}
$F$ in the following cases, using the first applicable case:

%% TODO(eernst): Note that `X extends X?` can create an infinite loop.
%% We will probably make that kind of bound an error.
\begin{itemize}
\item
  %% TODO(eernst): Come mixin classes and extension types: add them.
  If $T$ is a type which is introduced by
  a class, mixin, or enum declaration,
  and if $T$ or a direct or indirect superinterface
  (\ref{interfaceSuperinterfaces})
  of $T$ is \code{Future<$U$>} for some $U$,
  then $T$ derives the future type \code{Future<$U$>}.
\item
  If $T$ is the type \code{FutureOr<$U$>} for some $U$,
  then $T$ derives the future type \code{FutureOr<$U$>}.
\item
  If $T$ is \code{$S$?} for some $S$, and
  $S$ derives the future type $F$,
  then $T$ derives the future type \code{$F$?}.
\item
  If $T$ is a type variable with bound $B$, and
  $B$ derives the future type $F$,
  then $T$ derives the future type $F$.
\item
  \commentary{%
    There is no rule for the case where $T$ is of the form \code{$X$\,\&\,$S$}
    because this will never occur
    (this concept is only used in \flattenName, which is defined below).%
  }
\end{itemize}

\LMHash{}%
When none of these cases are applicable,
we say that $T$ does not derive a future type.

\commentary{%
  Note that if $T$ derives a future type $F$ then \SubtypeNE{T}{F},
  and $F$ is always of the form \code{$G$<...>} or \code{$G$<...>?},
  where $G$ is \code{Future} or \code{FutureOr}. The proof is
  by induction on the structure of $T$:

  \begin{itemize}
  \item
    %% TODO(eernst): Come mixin classes and extension types: add them.
    If $T$ is a type which is introduced by
    a class, mixin, or enum declaration,
    and if $T$ or a direct or indirect superinterface
    (\ref{interfaceSuperinterfaces})
    of $T$ is \code{Future<$U$>} for some $U$, then, letting
    \code{$G =$ Future} and \code{$F = G$<$U$>}, $T <: F$.
  \item
    If $T$ is the type \code{FutureOr<$U$>} for some $U$, then by reflexivity,
    \code{$T <:$ FutureOr<$U$>}. Letting \code{$G =$ FutureOr} and
    \code{$F = G$<$U$>}, it follows that $T <: F$.
  \item
    If $T$ is \code{$S$?} for some $S$, and
    $S$ derives the future type $F'$,
    then by the induction hypothesis, \code{$S <: F'$},
    where $F'$ is of the form
    \code{$G'$<$U$>} or \code{$G'$<$U$>?} and $G'$ is \code{Future} or
    \code{FutureOr}. Therefore, \code{$S$? $<: F'$?}, and by substitution,
    \code{$T <: F'$?}. Since \code{$T$?? $= T$?} for all $T$, it follows that
    \code{$T <: G'$<$U$>?}. So, letting $G = G'$ and \code{$F = G$<$U$>?},
    it follows that $T <: F$.
  \item
    If $T$ is a type variable with bound $B$, and
    $B$ derives the future type $F$,
    then by the induction hypothesis, \code{$B <: F'$},
    where $F'$ is of the form
    \code{$G'$<$U$>} or \code{$G'$<$U$>?} and $G'$ is \code{Future} or
    \code{FutureOr}. Also, since $B$ is the bound of $T$, $T <: B$, so by
    transitivity, $T <: F'$. Therefore, letting $G = G'$ and $F = F'$, it
    follows that $T <: F$.
  \end{itemize}

  Also note that 'derives' in this context refers to the computation
  where a type $T$ is given, the supertypes of $T$ are searched,
  and a type $F$ of one of those forms is selected.
  There is no connection to the notion of a 'derived class' meaning 'subclass'
  that some programming language communities use.%
}

\LMHash{}%
We define the auxiliary function
\IndexCustom{\flatten{T}}{flatten(t)@\emph{flatten}$(T)$}
as follows, using the first applicable case:

\begin{itemize}
\item If $T$ is \code{$X$\,\&\,$S$}
  for some type variable $X$ and type $S$ then

  \begin{itemize}
  \item if $S$ derives a future type $U$
    then \DefEquals{\flatten{T}}{\code{\flatten{U}}}.
  \item otherwise,
    \DefEquals{\flatten{T}}{\code{\flatten{X}}}.
  \end{itemize}

\item If $T$ derives a future type \code{Future<$S$>}
  or \code{FutureOr<$S$>}
  then \DefEquals{\flatten{T}}{S}.

\item If $T$ derives a future type \code{Future<$S$>?}\ or
  \code{FutureOr<$S$>?}\ then \DefEquals{\flatten{T}}{\code{$S$?}}.

\item Otherwise, \DefEquals{\flatten{T}}{T}.
\end{itemize}

\rationale{%
  This definition guarantees that for any type $T$,
  \code{$T <:$ FutureOr<$\flatten{T}$>}. The proof is by induction on the
  structure of $T$:

  \begin{itemize}
  \item If $T$ is \code{$X$\,\&\,$S$} then

    \begin{itemize}
    \item if $S$ derives a future type $U$,
      then \code{$T <: S$} and \code{$S <: U$}, so \code{$T <: U$}.
      By the induction hypothesis, \code{$U <:$ FutureOr<$\flatten{U}$>}.
      Since \code{$\flatten{T} = \flatten{U}$} in this case, it follows that
      \code{$U <:$ FutureOr<$\flatten{T}$>}, and so
      \code{$T <:$ FutureOr<$\flatten{T}$>}.
    \item otherwise, \code{$T <: X$}.
      By the induction hypothesis, \code{$X <:$ FutureOr<$\flatten{X}$>}.
      Since \code{$\flatten{T} = \flatten{X}$} in this case, it follows that
      \code{$U <:$ FutureOr<$\flatten{T}$>}, and so
      \code{$T <:$ FutureOr<$\flatten{T}$>}.
    \end{itemize}

  \item If $T$ derives a future type \code{Future<$S$>}
    or \code{FutureOr<$S$>}, then, since \code{Future<$S$> $<:$ FutureOr<$S$>},
    it follows that \code{$T <:$ FutureOr<$S$>}. Since \code{$\flatten{T} = S$}
    in this case, it follows that \code{$T <:$ FutureOr<$\flatten{T}$>}.

  \item If $T$ derives a future type \code{Future<$S$>?} or
    \code{FutureOr<$S$>?}, then, since \code{Future<$S$>? $<:$ FutureOr<$S$>?},
    it follows that \code{$T <:$ FutureOr<$S$>?}.
    \code{FutureOr<$S$>? $<:$ FutureOr<$S$?>} for any type $S$
    (this can be shown using the union type subtype rules and from
    \code{Future<$S$> $<:$ Future<$S$?>} by covariance), so by transivitity,
    \code{$T <:$ FutureOr<$S$?>}. Since \code{$\flatten{T} = S$?} in this case,
    it follows that \code{$T <:$ FutureOr<$\flatten{T}$>}.

  \item Otherwise, \code{$\flatten{T} = T$}, so
    \code{FutureOr<$\flatten{T}$> $=$ FutureOr<$T$>}. Since
    \code{$T <:$ FutureOr<$T$>}, it follows that
    \code{$T <:$ FutureOr<$\flatten{T}$>}.
  \end{itemize}
}

\LMHash{}%
\Case{Positional, arrow}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$]) => $e$}

\noindent
is
\FunctionTypePositionalStd{T_0},

\noindent
%% TODO[inference]: The static type of the function literal may be inferred.
where $T_0$ is the static type of $e$.
\EndCase

\LMHash{}%
\Case{Positional, arrow, future}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n,$ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$]) \ASYNC{} => $e$}

\noindent
is
\FunctionTypePositionalStdCr{\code{Future<\flatten{T_0}>}},

\noindent
where $T_0$ is the static type of $e$.
\EndCase

\LMHash{}%
\Case{Named, arrow}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ \{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}) => $e$}

\noindent
is
\FunctionTypeNamedStd{T_0},

\noindent
where $T_0$ is the static type of $e$.
\EndCase

\LMHash{}%
\Case{Named, arrow, future}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ \{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}) \ASYNC{} => $e$}

\noindent
is
\FunctionTypeNamedStdCr{\code{Future<\flatten{T_0}>}},

\noindent
where $T_0$ is the static type of $e$.
\EndCase

\LMHash{}%
\Case{Positional, block}
The static type of a function literal of the form

\noindent
\code{<\TypeParameters{X}{B}{S}>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k}= d_k$]) \{ $s$ \}}

\noindent
is
\FunctionTypePositionalStdCr{\DYNAMIC}
\EndCase

\LMHash{}%
\Case{Positional, block, future}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$]) \ASYNC{} \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypePositionalStdCr{\code{Future}}.
\EndCase

\LMHash{}%
\Case{Positional, block, stream}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k}= d_k$]) \ASYNC*{} \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypePositionalStdCr{\code{Stream}}.
\EndCase

\LMHash{}%
\Case{Positional, block, iterable}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k}= d_k$]) \SYNC*{} \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypePositionalStdCr{\code{Iterable}}.
\EndCase

\LMHash{}%
\Case{Named, block}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ [$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k}= d_k$]) \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypePositionalStdCr{\DYNAMIC}.
\EndCase

\LMHash{}%
\Case{Named, block, future}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ \{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}) \ASYNC{} \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypeNamedStdCr{\code{Future}}.
\EndCase

\LMHash{}%
\Case{Named, block, stream}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ \{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}) \ASYNC*{} \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypeNamedStdCr{\code{Stream}}.
\EndCase

\LMHash{}%
\Case{Named, block, iterable}
The static type of a function literal of the form

\noindent
\code{<\TypeParametersStd>}

\noindent
\code{($T_1\ a_1, \ldots,\ T_n\ a_n, $ \{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\}) \SYNC*{} \{ $s$ \}}

\noindent
is
%% TODO(eernst): Adjust to take type inference into account.
\FunctionTypeNamedStdCr{\code{Iterable}}.
\EndCase

\LMHash{}%
In all of the above cases,
the type argument lists are omitted when $m=0$,
and whenever $T_i$ is not specified, $i \in 1 .. n+k$,
it is considered to have been specified as \DYNAMIC.

\LMHash{}%
Evaluation of a function literal yields a function object $o$.

\commentary{%
  The run-time type of $o$ is specified based on
  the static type $T$ of the function literal
  and the binding of type variables occurring in $T$
  at the occasion where the evaluation occurred
  (\ref{typeOfAFunction}).%
}


\subsection{This}
\LMLabel{this}

\LMHash{}%
The reserved word \THIS{} denotes
the target of the current instance member invocation.

\begin{grammar}
<thisExpression> ::= \THIS{}
\end{grammar}

\LMHash{}%
The static type of \THIS{} is the interface of the
immediately enclosing class, enum, or mixin, if any.
The static type of \THIS{} is
the \ON{} type of the enclosing extension, if any
(\ref{extensions}).

\commentary{%
  If none of those declarations exist,
  an occurrence of \THIS{} is a compile-time error
  (\ref{classes}).%
}

\LMHash{}%
It is a compile-time error if \THIS{} appears, implicitly or explicitly,
in a top-level function or variable initializer, in a factory constructor,
or in a static method or variable initializer,
or in the initializing expression of a non-late instance variable.


\subsection{Instance Creation}
\LMLabel{instanceCreation}

\LMHash{}%
Instance creation expressions generally produce instances
and invoke constructors to initialize them.

\commentary{%
  The exception is that
  a factory constructor invocation works like a regular function call.
  It may of course evaluate an instance creation expression and thus
  produce a fresh instance,
  but no fresh instances are created as a direct consequence of
  the factory constructor invocation.%
}

\LMHash{}%
It is a compile-time error if
the type $T$ in an instance creation expression of one of the forms

\noindent
\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
\code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}

\noindent
is an enumerated type (\ref{enums}).


\subsubsection{New}
\LMLabel{new}

\LMHash{}%
The \Index{new expression} invokes a constructor (\ref{constructors}).

\begin{grammar}
<newExpression> ::= \NEW{} <constructorDesignation> <arguments>
\end{grammar}

\LMHash{}%
Let $e$ be a new expression of the form

\noindent
\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
or the form

\noindent
\code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\LMHash{}%
It is a compile-time error if $T$ is not
a class or a parameterized type accessible in the current scope,
or if $T$ is a parameterized type which is not a class.
\commentary{%
  For instance, \code{\NEW{} F<int>()} is an error if \code{F} is a type alias
  that does not denote a class.%
}

\LMHash{}%
If $T$ is a parameterized type (\ref{parameterizedTypes})
\code{$S$<$U_1, \ldots,\ U_m$>},
let $R$ be the generic class $S$,
and let
\code{$X_1\ \EXTENDS\ B_1, \ldots,\ X_p\ \EXTENDS\ B_p$}
be the formal type parameters of $S$.
If $T$ is not a parameterized type, let $R$ be $T$.

\begin{itemize}
\item
  If $e$ is of the form
  \code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
  it is a compile-time error if \code{$R$.\id} is not the name of
  a constructor declared by $R$, or \id{} is not accessible.
\item
  If $e$ is of the form
  \code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
  it is a compile-time error if $R$ is not the name of
  a constructor declared by $R$.
\end{itemize}

\LMHash{}%
Let $q$ be the above-mentioned constructor named \code{$R$.\id} or $R$.

\LMHash{}%
It is a compile-time error if $R$ is abstract
and $q$ is not a factory constructor.
It is a compile-time error if $R$ is a non-generic class
and $T$ is a parameterized type.
%% We assume that inference has taken place, so actual type arguments
%% are always given explicitly.
It is a compile-time error if $R$ is a generic class
and $T$ is not a parameterized type.
It is a compile-time error if $R$ is a generic class,
$T$ is a parameterized type, and $m \not= p$.
\commentary{That is, the number of type arguments is incorrect.}
It is a compile-time error if $R$ is a generic class,
$T$ is a parameterized type,
and $T$ is not regular-bounded
(\ref{superBoundedTypes}).

\LMHash{}%
If $q$ is a redirecting factory constructor,
it is a compile-time error if $q$ in some number of
redirecting factory redirections redirects to itself.
\commentary{%
  It is possible and allowed for a redirecting factory $q'$
  to enter an infinite loop, e.g.,
  because $q'$ redirects to a non-redirecting factory constructor
  $q''$ whose body uses $q'$ in an instance creation expression.
  Only loops that consist exclusively of redirecting factory redirections
  are detected at compile time.%
}

\LMHash{}%
Let $S_i$ be the static type of
the formal parameter of the constructor \code{$R$.\id} (respectively $R$)
corresponding to the actual argument $a_i$, $i \in 1 .. n+k$.
It is a compile-time error if the static type of
$a_i, i \in 1 .. n + k$
is not assignable to $[U_1/X_1, \ldots, U_m/X_m]S_i$.
\commentary{%
  The non-generic case is covered with $m = 0$.%
}

\LMHash{}%
The static type of $e$ is $T$.

\LMHash{}%
Evaluation of $e$ proceeds as follows:

\LMHash{}%
First, the argument part

\noindent
\code{<$U_1, \ldots,\ U_m$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}

\noindent
is evaluated, yielding the evaluated actual argument part

\noindent
\code{<$u_1, \ldots,\ u_m$>($o_1, \ldots,\ o_n,\ x_{n+1}$: $o_{n+1},\ \ldots,\ x_{n+k}$: $o_{n+k}$)}.

\noindent
\commentary{Note that the non-generic case is covered by letting $m = 0$.}
% This error can occur due to an implicit cast.
If for any
$j \in 1 .. n + k$
the run-time type of $o_j$ is not a subtype of
$[u_1/X_1, \ldots, u_m/X_m]S_j$,
a dynamic type error occurs.

\LMHash{}%
\Case{Non-loaded deferred constructors}
% This error can occur because being-loaded is a dynamic property.
If $T$ is a deferred type with prefix $p$,
then if $p$ has not been successfully loaded,
a dynamic error occurs.
\EndCase

\LMHash{}%
\Case{Generative constructors}
When $q$ is a generative constructor
(\ref{generativeConstructors})
evaluation proceeds to allocate a fresh instance
(\ref{generativeConstructors}), $i$, of class $T$.
% We provide the type arguments as part of the class of the instance
% because $T$ includes the type arguments; but we also provide them
% as a binding accessible to the constructor: Otherwise we couldn't
% access the type parameters in the initializing expressions of the
% initializer list where there is no access to \THIS.
Then $q$ is executed to initialize $i$ with respect to
the bindings that resulted from the evaluation of the argument list, and,
if $R$ is a generic class,
with its type parameters bound to $u_1, \ldots, u_m$.

\LMHash{}%
If execution of $q$ completes normally (\ref{statementCompletion}),
$e$ evaluates to $i$.
Otherwise execution of $q$ throws an exception object $x$ and stack trace $t$,
and then evaluation of $e$ also throws exception object $x$ and stack trace $t$
(\ref{expressionEvaluation}).
\EndCase

\LMHash{}%
\Case{Redirecting factory constructors}
When $q$ is a redirecting factory constructor
(\ref{factories})
of the form \code{\CONST? $T$($p_1, \ldots,\ p_{n+k}$) = $c$;} or
of the form \code{\CONST? $T$.\id($p_1, \ldots,\ p_{n+k}$) = $c$;}
where \code{\CONST?} indicates that \CONST{} may be present or absent,
the remaining evaluation of $e$ is equivalent to
evaluating
\code{\NEW{} $c$($v_1, \ldots,\ v_n,\ x_{n+1}$: $v_{n+1}, \ldots,\ x_{n+k}$: $v_{n+k}$)}
in an environment where
$v_j$ is a fresh variable bound to $o_j$ for $j \in 1 .. n + k$, and
$X_j$ is bound to $u_j$ for $j \in 1 .. m$.
\commentary{%
  We need access to the type variables because $c$ may contain them.%
}
\EndCase

\LMHash{}%
\Case{Non-redirecting factory constructors}
When $q$ is a non-redirecting factory constructor,
the body of $q$ is executed with respect to
the bindings that resulted from the evaluation of the argument list,
and with the type parameters, if any, of $q$ bound to
the actual type arguments $u_1, \ldots, u_m$.
If this execution returns an object
(\ref{statementCompletion})
then $e$ evaluates to the returned object.
Otherwise, if the execution completes normally or returns with no object,
then $e$ evaluates to the null object (\ref{null}).
Otherwise the execution throws an exception $x$ and stack trace $t$,
and then evaluation of $e$ also throws $x$ and $t$
(\ref{expressionEvaluation}).

\rationale{%
  A factory constructor can be declared in an abstract class and used safely,
  as it will either produce a valid instance or throw.%
}
\EndCase


\subsubsection{Const}
\LMLabel{const}

\LMHash{}%
A \Index{constant object expression} invokes a constant constructor
(\ref{constantConstructors}).

\begin{grammar}
<constObjectExpression> ::= \CONST{} <constructorDesignation> <arguments>
\end{grammar}

\LMHash{}%
Let $e$ be a constant object expression of the form

\noindent
\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
or the form

\noindent
\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\LMHash{}%
It is a compile-time error if $T$ is not
a class or a parameterized type accessible in the current scope,
or if $T$ is a parameterized type which is not a class.
It is a compile-time error if $T$ is a deferred type
(\ref{staticTypes}).
\commentary{In particular, $T$ must not be a type variable.}

\LMHash{}%
It is a compile-time error if $a_i$ is not a constant expression
for some $i \in 1 .. n + k$.

\LMHash{}%
If $T$ is a parameterized type (\ref{parameterizedTypes})
\code{$S$<$U_1, \ldots,\ U_m$>},
let $R$ be the generic class $S$,
and let
\code{$X_1\ \EXTENDS\ B_1, \ldots,\ X_p\ \EXTENDS\ B_p$}
be the formal type parameters of $S$.
If $T$ is not a parameterized type, let $R$ be $T$.

\LMHash{}%
If $T$ is a parameterized type,
it is a compile-time error if $U_j$ is not a constant type expression for any
$j \in 1 .. m$.

\begin{itemize}
\item
  If $e$ is of the form
  \code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
  it is a compile-time error if \code{$R$.\id} is not the name of
  a constant constructor declared by $R$, or \id{} is not accessible.
\item
  If $e$ is of the form
  \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
  it is a compile-time error if $R$ is not the name of
  a constant constructor declared by $R$.
\end{itemize}

\LMHash{}%
Let $q$ be the above-mentioned constant constructor named \code{$R$.\id} or $R$.

%% TODO(eernst): These errors are the same as with `new`. Can we avoid
%% stating them twice? We'd need to refer to an awkwardly shaped portion
%% of text in the previous subsection, or just loosely say "exactly the
%% same errors"..
\LMHash{}%
It is a compile-time error if $R$ is abstract
and $q$ is not a factory constructor.
It is a compile-time error if $R$ is a non-generic class
and $T$ is a parameterized type.
%% We assume that inference has taken place, so actual type arguments
%% are always given explicitly.
It is a compile-time error if $R$ is a generic class
and $T$ is not a parameterized type.
It is a compile-time error if $R$ is a generic class,
$T$ is a parameterized type, and $m \not= p$.
\commentary{That is, the number of type arguments is incorrect.}
It is a compile-time error if $R$ is a generic class,
$T$ is a parameterized type,
and $T$ is not regular-bounded
(\ref{superBoundedTypes}).

\LMHash{}%
Let $S_i$ be the static type of
the formal parameter of the constructor \code{$R$.\id} (respectively $R$)
corresponding to the actual argument $a_i$, $i \in 1 .. n+k$.
It is a compile-time error if the static type of
$a_i, i \in 1 .. n + k$
is not assignable to $[U_1/X_1, \ldots, U_m/X_m]S_i$.
\commentary{The non-generic case is covered with $m = 0$.}

\LMHash{}%
The static type of $e$ is $T$.

\LMHash{}%
Evaluation of $e$ proceeds as follows:

\LMHash{}%
If $e$ is of the form
\code{\CONST{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
let $i$ be the value of the expression $e'$:

\noindent
\code{\NEW{} $T$.\id($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\commentary{%
  Let $o$ be the result of an evaluation of $e'$,
  at some point in time of some execution of the program
  in the library $L$ where $e$ occurs.
  The result of an evaluation of $e'$ in $L$
  at some other time and/or in some other execution will
  yield a result $o'$, such that $o'$ would be replaced by $o$
  by canonicalization as described below.
  This means that the value is well-defined.%
}

\LMHash{}%
If $e$ is of the form
\code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
let $i$ be the value of
\code{\NEW{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.
\commentary{Which is well-defined for the same reason.}

\begin{itemize}
\item If during execution of the program,
  a constant object expression has already evaluated to
  an instance $j$ of class $R$ with type arguments $U_i, 1 \le i \le m$, then:

  \begin{itemize}
  \item For each instance variable $f$ of $i$,
    let $v_{if}$ be the value of the instance variable $f$ in $i$, and
    let $v_{jf}$ be the value of the instance variable $f$ in $j$.
    If \code{identical($v_{if}$, $v_{jf}$)}
    for all instance variables $f$ in $i$
    then the value of $e$ is $j$,
    otherwise the value of $e$ is $i$.
  \end{itemize}
\item Otherwise the value of $e$ is $i$.
\end{itemize}

\commentary{%
  In other words, constant objects are canonicalized.
  In order to determine if an object is actually new, one has to compute it;
  then it can be compared to any cached instances.
  If an equivalent object exists in the cache,
  we throw away the newly created object and use the cached one.
  Objects are equivalent if
  they have identical type arguments and identical instance variables.
  Since the constructor cannot induce any side effects,
  the execution of the constructor is unobservable.
  The constructor need only be executed once per call site, at compile time.%
}

\LMHash{}%
It is a compile-time error if evaluation of a constant object
results in an uncaught exception being thrown.

\commentary{%
  To see how such situations might arise, consider the following examples:%
}

%% TODO(eernst): Delete some \CONST{} when integrating implicit-creation.md
\begin{dartCode}
\CLASS{} A \{
  \FINAL{} x;
  \CONST{} A(p): x = p * 10;
\}
\\
\CLASS{} IntPair \{
  \CONST{} IntPair(\THIS.x, \THIS.y);
  \FINAL{} int x;
  \FINAL{} int y;
  \OPERATOR *(v) => \NEW{} IntPair(x*v, y*v);
\}
\\
\CONST a1 = \CONST{} A(true); // \comment{compile-time error}
\CONST a2 = \CONST{} A(5); // \comment{legal}
\CONST a3 = \CONST{} A(\CONST{} IntPair(1,2)); // \comment{compile-time error}
\end{dartCode}

\commentary{%
  Due to the rules governing constant constructors,
  evaluating the constructor \code{A()}
  with the argument \code{"x"} or the argument \code{\CONST{} IntPair(1, 2)}
  would cause it to throw an exception, resulting in a compile-time error.
  In the latter case, the error is caused by the fact that
  \code{\OPERATOR{} *} can only be used with a few ``well-known'' types,
  which is required in order to avoid running arbitrary code during
  the evaluation of constant expressions.%
}


\subsection{Spawning an Isolate}
\LMLabel{spawningAnIsolate}

\LMHash{}%
Spawning an isolate is accomplished via what is syntactically
an ordinary method call,
invoking one of the static methods \code{spawnUri} or \code{spawn} defined in
the \code{Isolate} class in the library \code{dart:isolate}.
However, such calls have the semantic effect of creating
a new isolate with its own memory and thread of control.

\LMHash{}%
An isolate's memory is finite, as is the space available to
its thread's call stack.
% This error can occur because memory usage is a dynamic property.
It is possible for a running isolate to exhaust its memory or stack,
resulting in a dynamic error that cannot be effectively caught,
which will force the isolate to be suspended.

\commentary{%
  As discussed in section \ref{errorsAndWarnings},
  the handling of a suspended isolate is the responsibility of the runtime.%
}


\subsection{Function Invocation}
\LMLabel{functionInvocation}

\LMHash{}%
Function invocation occurs in the following cases:
when a function expression (\ref{functionExpressions})
is invoked (\ref{functionExpressionInvocation}),
when a method (\ref{methodInvocation}),
getter (\ref{topLevelGetterInvocation}, \ref{propertyExtraction})
or setter (\ref{assignment})
is invoked,
or when a constructor is invoked
(either via instance creation (\ref{instanceCreation}),
constructor redirection (\ref{redirectingGenerativeConstructors}),
or super initialization).
The various kinds of function invocation differ as to
how the function to be invoked, $f$, is determined,
as well as whether \THIS{} (\ref{this}) is bound.
Once $f$ has been determined,
formal type parameters of $f$ are bound to
the corresponding actual type arguments,
and the formal parameters of $f$ are bound to corresponding actual arguments.
When the body of $f$ is executed it will be executed
with the aforementioned bindings.

\LMHash{}%
Executing a body of the form \code{=> $e$} is equivalent to executing
a body of the form \code{\{ return $e$; \}}.
Execution a body of the form \code{\ASYNC{} => $e$} is equivalent to executing
a body of the form \code{\ASYNC{} \{ return $e$; \}}.

\LMHash{}%
If $f$ is synchronous and is not a generator (\ref{functions}) then
execution of the body of $f$ begins immediately.
If the execution of the body of $f$ returns an object $v$
(\ref{statementCompletion}),
the invocation evaluates to $v$.
If the execution completes normally or it returns without an object,
the invocation evaluates to the null object (\ref{null}).
If the execution throws an exception object and stack trace,
the invocation throws the same exception object and stack trace
(\ref{expressionEvaluation}).

\commentary{%
  A complete function body can never break or continue
  (\ref{statementCompletion})
  because a \BREAK{} or \CONTINUE{} statement must always occur inside
  the statement that is the target of the \BREAK{} or \CONTINUE.
  This means that a function body can only
  either complete normally, throw, or return.
  Completing normally or returning without an object is treated
  the same as returning with the null object (\ref{null}),
  so the result of executing a function body can always be used as
  the result of evaluating an expression,
  either by evaluating to an object, or by the evaluation throwing.%
}

\LMHash{}%
If $f$ is marked \code{\SYNC*} (\ref{functions}),
then a fresh instance (\ref{generativeConstructors}) $i$
implementing \code{Iterable<$U$>} is immediately returned,
where $U$ is the actual type
(\ref{actualTypes})
corresponding to the element type of $f$
(\ref{functions}).

\commentary{%
  A Dart implementation will need to provide
  a specific implementation of \code{Iterable}
  that will be returned by \code{\SYNC*} methods.
  A typical strategy would be to produce an instance of
  a subclass of class \code{IterableBase} defined in \code{dart:core}.
  The only method that needs to be added
  by the Dart implementation in that case is \code{iterator}.%
}

\LMHash{}%
The iterable implementation must comply with
the contract of \code{Iterable} and should not
take any steps identified as exceptionally efficient in that contract.

\commentary{%
  The contract explicitly mentions a number of situations
  where certain iterables could be more efficient than normal.
  For example, by precomputing their length.
  Normal iterables must iterate over their elements to determine their length.
  This is certainly true in the case of a synchronous generator,
  where each element is computed by a function.
  It would not be acceptable to pre-compute the results of the generator
  and cache them, for example.%
}

\LMHash{}%
When iteration over the iterable is started, by getting
an iterator $j$ from the iterable and calling \code{moveNext()},
execution of the body of $f$ will begin.
When execution of the body of $f$ completes (\ref{statementCompletion}),

\begin{itemize}
\item If it returns without an object or it completes normally
  (\ref{statementCompletion}),
  $j$ is positioned after its last element,
  so that its current value is the null object
  (\ref{null})
  and the current call to \code{moveNext()} on $j$ returns false,
  as must all further calls.
\item If it throws an exception object $e$ and stack trace $t$
  then the current value of $j$ is the null object
  (\ref{null})
  and the current call to \code{moveNext()} throws $e$ and $t$ as well.
  Further calls to \code{moveNext()} must return false.
\end{itemize}

\LMHash{}%
Each iterator starts a separate computation.
If the \code{\SYNC*} function is impure,
the sequence of objects yielded by each iterator may differ.

\commentary{%
  One can derive more than one iterator from a given iterable.
  Note that operations on the iterable itself can create distinct iterators.
  An example would be \code{length}.
  It is conceivable that different iterators might yield
  sequences of different length.
  The same care needs to be taken when writing \code{\SYNC*} functions as when
  writing an \code{Iterator} class.
  In particular, it should handle multiple simultaneous iterators gracefully.
  If the iterator depends on external state that might change,
  it should check that the state is still valid after every yield
  (and maybe throw a \code{ConcurrentModificationError} if it isn't).%
}

\LMHash{}%
Each iterator runs with its own shallow copies of all local variables;
in particular, each iterator has the same initial arguments,
even if their bindings are modified by the function.
\commentary{%
  Two executions of an iterator interact only via state outside the function.%
}
% The alternative would be to cache the results of an iterator in the iterable,
% and check the cache at each \YIELD. This would have strange issues as well.
% The yielded value might differ from the expression in the yield. And it is a
% potential memory leak as the cache is kept alive by any iterator.

\LMHash{}%
If $f$ is marked \ASYNC{} (\ref{functions}),
then a fresh instance (\ref{generativeConstructors}) $o$
is associated with the invocation,
where the dynamic type of $o$ implements \code{Future<T>},
where $T$ is the actual type
(\ref{actualTypes})
corresponding to the future value type of $f$.
Then the body of $f$ is executed until it either suspends or completes,
at which point $o$ is returned.
\commentary{%
  The body of $f$ may suspend during the evaluation of an \AWAIT{} expression
  or execution of an asynchronous \FOR{} loop.%
}
The future $o$ is completed when execution of the body of $f$ completes
(\ref{statementCompletion}).
If execution of the body returns an object, $o$ is completed with that object.
If it completes normally or returns without an object,
$o$ is completed with the null object (\ref{null}),
and if it throws an exception $e$ and stack trace $t$,
$o$ is completed with the error $e$ and stack trace $t$.
If execution of the body throws before the body suspends the first time,
completion of $o$ happens at some future time after the invocation has returned.
\rationale{%
  The caller needs time to set up error handling for the returned future,
  so the future is not completed with an error
  \emph{before} it has been returned.%
}

\LMHash{}%
If $f$ is marked \code{\ASYNC*} (\ref{functions}),
then a fresh instance (\ref{generativeConstructors}) $s$
implementing \code{Stream<$U$>} is immediately returned,
where $U$ is the actual type
(\ref{actualTypes})
corresponding to the element type of $f$
(\ref{functions}).
When $s$ is listened to, execution of the body of $f$ will begin.
When execution of the body of $f$ completes:

\begin{itemize}
\item If it completes normally or returns without an object
  (\ref{statementCompletion}),
  then if $s$ has been canceled
  then its cancellation future is completed with the null object (\ref{null}).
\item If it throws an exception object $e$ and stack trace $t$:

  \begin{itemize}
  \item If $s$ has been canceled then its cancellation future is completed
    with error $e$ and stack trace $t$.
  \item otherwise the error $e$ and stack trace $t$ are emitted by $s$.
  \end{itemize}
\item $s$ is closed.
\end{itemize}

\commentary{%
  The body of an asynchronous generator function
  cannot break, continue or return with an object
  (\ref{statementCompletion}).
  The first two are only allowed in contexts that
  will handle the break or continue,
  and return statements with an expression are not allowed
  in generator functions.%
}

\rationale{%
  When an asynchronous generator's stream has been canceled,
  cleanup will occur in the \FINALLY{} clauses (\ref{try}) inside the generator.
  We choose to direct any exceptions that occur at this time
  to the cancellation future rather than have them be lost.%
}


\subsubsection{Actual Argument Lists}
\LMLabel{actualArgumentLists}

\LMHash{}%
Actual argument lists have the following syntax:

\begin{grammar}
<arguments> ::= `(' (<argumentList> `,'?)? `)'

<argumentList> ::= <namedArgument> (`,' <namedArgument>)*
  \alt <expressionList> (`,' <namedArgument>)*

<namedArgument> ::= <label> <expression>
\end{grammar}

\LMHash{}%
Argument lists allow an optional trailing comma after the last argument
(\syntax{`,'?}).
An argument list with such a trailing comma is equivalent in all ways to
the same parameter list without the trailing comma.
All argument lists in this specification are shown without a trailing comma,
but the rules and semantics apply equally to
the corresponding argument list with a trailing comma.

\LMHash{}%
Let $L$ be an argument list of the form
\code{($e_1 \ldots,\ e_m,\ y_{m+1}$: $e_{m+1} \ldots,\ y_{m+p}$: $e_{m+p}$)}
and assume that the static type of $e_i$ is $S_i$, $i \in 1 .. m+p$.
The \Index{static argument list type} of $L$ is then
\code{($S_1 \ldots,\ S_m,\ S_{m+1}\ y_{m+1} \ldots,\ S_{m+p}\ y_{m+p}$)}.

\LMHash{}%
Let $\argumentList{S}$ be the static argument list type

\noindent
\code{($S_1 \ldots,\ S_m,\ S_{m+1}\ y_{m+1} \ldots,\ S_{m+p}\ y_{m+p}$)}

\noindent
and let $\parameterList{P}$ be the formal parameter list

\noindent
\code{($T_1\ x_1 \ldots,\ T_n\ x_n,\ $[$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$])}

\noindent
where each parameter may be marked \COVARIANT{}
\commentary{(not shown, but allowed)}.

\LMHash{}%
We say that $\argumentList{S}$ is
a \Index{subtype match} for $\parameterList{P}$
if{}f $p = 0$, $n \leq m \leq n+k$, and $S_i$ is
a subtype of $T_i$ for all $i \in 1 .. m$.
We say that $\argumentList{S}$ is
an \Index{assignable match} for $\parameterList{P}$
if{}f $p = 0$, $n \leq m \leq n+k$, and $S_i$ is
assignable to $T_i$ for all $i \in 1 .. m$.

\LMHash{}%
Let $\argumentList{S}$ be the static argument list type

\noindent
\code{($S_1 \ldots,\ S_m,\ S_{m+1}\ y_{m+1} \ldots,\ S_{m+p}\ y_{m+p}$)}

\noindent
and let $\parameterList{P}$ be the formal parameter list

\noindent
\code{($T_1\ x_1 \ldots,\ T_n\ x_n,\ $\{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\})}

\noindent
where each parameter may be marked \COVARIANT{}
\commentary{(not shown, but allowed)}.

\LMHash{}%
We say that $\argumentList{S}$ is
a \Index{subtype match} for $\parameterList{P}$
if{}f $m = n$,
$\{y_{m+1}\ldots,\ y_{m+p}\} \subseteq \{x_{n+1}\ldots,\ x_{n+k}\}$,
$S_i$ is a subtype of $T_i$ for all $i \in 1 .. m$,
and $S_i$ is a subtype of $T_j$ whenever $y_i = x_j$ and
$j \in n + 1 .. n + k$, for all
$i \in m + 1 .. m + p$.
We say that $\argumentList{S}$
is an \Index{assignable match} for $\parameterList{P}$
if{}f $m = n$,
$\{y_{m+1}\ldots,\ y_{m+p}\} \subseteq \{x_{n+1}\ldots,\ x_{n+k}\}$,
$S_i$ is assignable to $T_i$ for all $i \in 1 .. m$,
and $S_i$ is assignable to $T_j$ whenever $y_i = x_j$ and
$j \in n + 1 .. n + k$, for all
$i \in m + 1 .. m + p$.

\commentary{%
  In short, an actual argument list is a match for a formal parameter list
  whenever the former can safely be passed to the latter.%
}


\subsubsection{Actual Argument List Evaluation}
\LMLabel{actualArguments}

\LMHash{}%
Function invocation involves evaluation of
the list of actual arguments to the function,
and binding of the results to the function's formal parameters.

\LMHash{}%
When parsing an argument list, an ambiguity may arise because
the same source code could be one generic function invocation,
and it could be two or more relational expressions and/or shift expressions.
In this situation, the expression is always parsed
as a generic function invocation.

% Should we specify the precise disambiguation rule here?:
%   We have seen `a`, `<`, a matching `>`, and `(`, where
%   `a` is tricky because we can have things like `new Foo().m<...>(...`,
%   `x..y(...).m<...>(...`, etc, basically everything that can precede
%   argumentPart in the grammar.

\commentary{%
  An example is \code{f(a<B, C>($d$))},
  which may be an invocation of \code{f} passing
  two actual arguments of type \code{bool}, or
  an invocation of \code{f} passing the result returned by
  an invocation of the generic function \code{a}.
  Note that the ambiguity can be eliminated by omitting
  the parentheses around the expression $d$,
  or adding parentheses around one of the relational expressions.%
}

\rationale{%
  When the intention is to pass
  several relational or shift expressions as actual arguments
  and there is an ambiguity, the source code can easily be adjusted
  to a form which is unambiguous.
  Also, we expect that it will be more common to have
  generic function invocations as actual arguments
  than having relational or shift expressions that happen to match up
  and have parentheses at the end, such that the ambiguity arises.%
}

\LMHash{}%
Evaluation of an actual argument part of the form

\noindent
\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}
proceeds as follows:

\LMHash{}%
The type arguments $A_1, \ldots, A_r$ are evaluated
in the order they appear in the program,
producing types $t_1, \ldots, t_r$.
The arguments $a_1, \ldots, a_{m+l}$ are evaluated
in the order they appear in the program,
producing objects $o_1, \ldots, o_{m+l}$.

\commentary{%
  Simply stated, an argument part consisting of $s$ type arguments,
  $m$ positional arguments, and $l$ named arguments is
  evaluated from left to right.
  Note that the type argument list is omitted when $r = 0$
  (\ref{generics}).%
}


\subsubsection{Binding Actuals to Formals}
\LMLabel{bindingActualsToFormals}

\commentary{%
  In the following, the non-generic case is covered implicitly:
  When the number of actual type arguments is zero
  the entire type argument list \code{<\ldots{}>} is omitted,
  and similarly for empty type parameter lists (\ref{generics}).%
}

\LMHash{}%
Consider an invocation $i$ of a function $f$ with
an actual argument part of the form
\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}.

\commentary{%
  Note that $f$ denotes a function in a semantic sense,
  rather than a syntactic construct.
  A reference to this section is used in other sections
  when the static analysis of an invocation is specified,
  and the static type of $f$ has been determined.
  The function itself may have been obtained from a function declaration,
  from an instance bound to \THIS{} and an instance method declaration,
  or as a function object obtained by evaluation of an expression.
  Because of that, we cannot indicate here which syntactic construct
  corresponds to $f$.
  %
  A reference to this section is also used in other sections
  when actual arguments are to be bound to the corresponding formal parameters,
  and $f$ is about to be invoked, to specify the dynamic semantics.%
}

\commentary{%
  We do not call $f$ a `function object' here, because we do not wish to imply
  that every function invocation must involve a separate evaluation
  of an expression that yields a function object,
  followed by an invocation of that function object.
  For instance, an implementation should be allowed to compile the invocation
  of a top-level function as a series of steps whereby a stack frame is
  created, followed by a low-level jump to the generated code for the body.
  So, in this section,
  the word `function' is more low-level than `function object',
  but `function' still denotes a semantic entity
  which is associated with a function declaration,
  even though there may not be a corresponding entity in the heap at run time.%
}

\LMHash{}%
% We cannot pass the same named parameter twice.
It is a compile-time error if $q_j = q_k$ for any $j \ne k$.

\LMHash{}%
For a given type $T_0$, we introduce the notion of a
\IndexCustom{$T_0$ bounded type}{type!T0 bounded}:
$T_0$ itself is $T_0$ bounded;
if $B$ is $T_0$ bounded and
$X$ is a type variable with bound $B$
then $X$ is $T_0$ bounded;
finally, if $B$ is $T_0$ bounded and
$X$ is a type variable
then $X \& B$ is $T_0$ bounded.
In particular, a
\IndexCustom{\DYNAMIC{} bounded type}{type!dynamic bounded}
is either \DYNAMIC{} itself
or a type variable whose bound is \DYNAMIC{} bounded,
or an intersection whose second operand is \DYNAMIC{} bounded.
Similarly for a
\IndexCustom{\FUNCTION{} bounded type}{type!function bounded}.

\LMHash{}%
A
\IndexCustom{function-type bounded type}{type!function-type bounded}
is a type $T$ which is $T_0$ bounded where $T_0$ is a function type
(\ref{functionTypes}).
A function-type bounded type $T$ has an
\Index{associated function type}
which is the unique function type $T_0$ such that $T$ is $T_0$ bounded.

\LMHash{}%
If the static type of $f$ is \DYNAMIC{} bounded or \FUNCTION{} bounded,
no further static checks are performed on the invocation $i$
\commentary{(apart from separate static checks on subterms like arguments)},
and the static type of $i$ is \DYNAMIC.
Otherwise, it is a compile-time error if the static type of $f$ is not
function-type bounded.

\LMHash{}%
If no error occurred and the static analysis of $i$ is not complete
then the static type $T_f$ of $f$ is function-type bounded;
let $F$ be the associated function type of $T_f$.

\LMHash{}%
Let $S_0$ be the return type of $F$,
let $X_1\ \EXTENDS\ B_1, \ldots, X_s\ \EXTENDS\ B_s$
be the formal type parameters,
let $h$ be the number of required parameters,
let $p_1, \ldots, p_n$ be the positional parameters,
and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters of $F$.
Let $S_i$ be the static type of the formal parameters $p_i, i \in 1 .. h+k$,
and for each $q$ let $S_q$ be the type of the parameter named $q$,
where each parameter type is obtained by replacing $X_j$ by $A_j, j \in 1 .. s$,
in the given parameter type annotation.
Finally, let $T_i$ be the static type of $a_i$.

\commentary{%
  We have an actual argument list consisting of $r$ type arguments,
  $m$ positional arguments, and $l$ named arguments.
  We have a function with $s$ type parameters,
  $h$ required parameters, and $k$ optional parameters.
  Figure~\ref{fig:argumentsAndParameters} shows how this situation arises.%
}

% View on declaration:
%
%     |**   ...        *|**        ...         *|**     ...          *|
%      <-s type par.s--> <--h required par.s---> <--k optional par.s->
%                        <--n pos, par.s, h=n--> <---k named par.s---> NAMED
%                        <----------n positional par.s, n=h+k--------> POS
%
% Actual argument part:
%
%     |**   ...        *|**           ...          *|**     ...       *|
%      <-r type arg.s--> <----m positional arg.s---> <--l named arg.s->
\begin{figure}[h]
  \def\A#1{\mbox{\commentary{{#1} arguments}}}
  \def\P#1{\mbox{\commentary{{#1} parameters}}}
  %
  \flushleft{\commentary{Actual arguments:}}
  \begin{displaymath}
    \begin{array}{rl}
      \left<\A{$r$ type}\right>
      \left(
      \begin{array}{r@{,\;}l}
        \A{$m$ positional}&\A{$l$ named}
      \end{array}
      \right)
    \end{array}
  \end{displaymath}
  %
  \flushleft{\commentary{Declaration with named parameters: $n = h$}}
  \begin{displaymath}
    \begin{array}{rl}
      \left<\P{$s$ type}\right>
      \left(
      \begin{array}{r@{,\;}l}
        \P{$h$ required}&\P{$k$ optional}\\
        \multicolumn{2}{c}{\mbox{\scriptsize\textit{which may also be viewed as}}}\\
        \P{$n$ positional}&\P{$k$ named}\\
      \end{array}
      \right)
    \end{array}
  \end{displaymath}
  %
  \flushleft{\commentary{Declaration with optional positional parameters: $n = h + k$}}
  \begin{displaymath}
    \begin{array}{rl}
      \left<\P{$s$ type}\right>
      \left(
      \begin{array}{r@{,\;}l}
        \P{$h$ required}&\P{$k$ optional}\\
        \multicolumn{2}{c}{\mbox{\scriptsize\textit{which may also be viewed as}}}\\
        \multicolumn{2}{c}{\P{$n$ positional}}
      \end{array}
      \right)
    \end{array}
  \end{displaymath}
  %
  \caption{Possible actual argument parts and formal parameter parts.}
  \label{fig:argumentsAndParameters}
\end{figure}

\LMHash{}%
% Type inference is assumed complete, so we must have
% the correct number of type arguments.
It is a compile-time error if $r \not= s$.
It is a compile-time error if $r = s$ and for some $j \in 1 .. s$,
$A_j \not<: [A_1/X_1, \ldots, A_r/X_s]B_j$.
It is a compile-time error unless $h \le m \le n$.
If $l > 0$,
it is a compile-time error unless $F$ has named parameters and
$q_j \in \{p_{h+1}, \ldots, p_{h+k}\}, j \in 1 .. l$.

\commentary{%
  That is, the number of type arguments must match
  the number of type parameters,
  and the bounds must be respected.
  We must receive at least the required number of positional arguments,
  and not more than the total number of positional parameters.
  For each named argument there must be a named parameter with the same name.%
}

\LMHash{}%
The static type of $i$ is $[A_1/X_1, \ldots, A_r/X_s]S_0$.

\LMHash{}%
It is a compile-time error if $T_j$ may not be assigned to
$S_j, j \in 1 .. m$.
It is a compile-time error if $T_{m+j}$ may not be assigned to
$S_{q_j}, j \in 1 .. l$.

\commentary{%
  Consider the case where the function invocation in focus here is
  an instance method invocation.
  In that case, for each actual argument,
  the corresponding parameter may be covariant.
  However, the above assignability requirements apply equally
  both when the parameter is covariant and when it is not.%
}

\rationale{%
  Parameter covariance in an instance method invocation can be introduced by
  a subtype of the statically known receiver type,
  which means that any attempt to flag a given actual argument as dangerous
  due to the dynamic type check that it will be subjected to
  will be incomplete:
  some actual arguments can be subjected to such a dynamic type check
  even though this is not known statically at the call site.
  This is not surprising for a mechanism like parameter covariance which is
  designed for the very purpose of allowing developers to explicitly request
  that this specific kind of compile-time safety is violated.
  The point is that this mechanism postpones the enforcement of
  the underlying invariant to run time,
  and in return allows some useful program designs
  that would otherwise be rejected at compile-time.%
}

\LMHash{}%
For the dynamic semantics,
let $f$ be a function with $s$ type parameters and $h$ required parameters;
let $p_1, \ldots, p_n$ be the positional parameters of $f$;
and let $p_{h+1}, \ldots, p_{h+k}$ be the optional parameters declared by $f$.

\LMHash{}%
An evaluated actual argument part

\noindent
\code{<$t_1, \ldots,\ t_r$>($o_1, \ldots,\ o_m,\ q_1$: $o_{m+1},\ \ldots,\ q_l$: $o_{m+l}$)}

\noindent
derived from an actual argument part of the form

\noindent
\code{<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_m,\ q_1$: $a_{m+1}, \ldots,\ q_l$: $a_{m+l}$)}

\noindent
is bound to the formal type parameters and formal parameters of $f$ as follows:

\LMHash{}%
% Passing a wrong number of actual type arguments.
If $r = 0$ and $s > 0$ then
if $f$ does not have default type arguments
(\ref{instantiationToBound})
then a dynamic error occurs.
Otherwise replace the actual type argument list:
Let $r$ be $s$ and let $t_i$ for $i \in 1 .. s$ be the result of
instantiation to bound
(\ref{instantiationToBound})
on the formal type parameters of $f$,
substituting the actual values of any free type variables
(\ref{actualTypes}).
Otherwise, if $r \not= s$, a \code{NoSuchMethodError} is thrown.

\LMHash{}%
% Passing named arguments to a function with optional positional parameters.
If $l > 0$ and $n \not= h$, a \code{NoSuchMethodError} is thrown.
% Passing too few or too many positional arguments.
If $m < h$, or $m > n$, a \code{NoSuchMethodError} is thrown.
% When l>0, h=n and there are k named parameters p_{h+1}..p_{h+k}.
Furthermore, each
$q_i, i \in 1 .. l$,
must have a corresponding named parameter in the set
$\{p_{h+1}, \ldots, p_{h+k}\}$,
or a \code{NoSuchMethodError} is thrown.
% Finally, bindings!
Then $p_i$ is bound to
$o_i, i \in 1 .. m$,
and $q_j$ is bound to $o_{m+j}, j \in 1 .. l$.
All remaining formal parameters of $f$ are bound to their default values.

\commentary{%
  All of these remaining parameters are necessarily optional
  and thus have default values.%
}

\LMHash{}%
% Check the type arguments.
% This error can occur due to covariance and due to dynamic invocation.
It is a dynamic type error if $t_i$ is not a subtype of the actual bound
(\ref{actualTypes})
of the $i$th type argument of $f$, for actual type arguments $t_1, \ldots, t_r$.
% Check the types of positional arguments.
% This error can occur due to implicit casts, covariance, and dynamic calls.
It is a dynamic type error if $o_i$ is not the null object (\ref{null})
and the actual type
(\ref{actualTypes})
of $p_i$ is not a supertype of the dynamic type of $o_i, i \in 1 .. m$.
% Check the types of named arguments.
% This error can occur due to implicit casts, covariance, and dynamic calls.
It is a dynamic type error if $o_{m+j}$ is
not the null object and the actual type
(\ref{actualTypes})
of $q_j$ is not a supertype of the dynamic type of $o_{m+j}, j \in 1 .. l$.


\subsubsection{Unqualified Invocation}
\LMLabel{unqualifiedInvocation}

\LMHash{}%
An unqualified function invocation $i$ has the form

\noindent
\code{\id<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
where \id{} is an identifier.

\commentary{%
  Note that the type argument list is omitted when $r = 0$ (\ref{generics}).%
}

\LMHash{}%
Perform a lexical lookup of \id{}
(\ref{lexicalLookup})
from the location of $i$.

\LMHash{}%
\Case{Lexical lookup yields a declaration}
Let $D$ be the declaration yielded by the lexical lookup of \id.

\begin{itemize}
\item
  When $D$ is a type declaration, that is,
  a declaration of a class, mixin, enum, type alias, or type parameter,
  the following applies:
  If $D$ is a declaration of a class $C$
  that has a constructor named $C$
  then the meaning of $i$ depends on the context:
  If $i$ occurs in a constant context
  (\ref{constantContexts}),
  then $i$ is treated as
  (\ref{notation})
  \code{\CONST\,\,$i$};
  if $i$ does not occur in a constant context
  then $i$ is treated as \code{\NEW\,\,$i$}.
  If $D$ is not a class declaration,
  or it declares a class named $C$ that has no constructor named $C$,
  a compile-time error occurs.
\item
  Otherwise, if $D$ is a declaration of
  a local function,
  a library function, or
  a library or static getter, or a variable,
  then $i$ is treated as
  (\ref{notation})
  a function expression invocation
  (\ref{functionExpressionInvocation}).
\item
  Otherwise, if $D$ is
  a static method or getter
  \commentary{(which may be implicitly induced by a static variable)}
  in the enclosing class or mixin $C$,
  $i$ is treated as
  (\ref{notation})
  \code{$C$.$i$}
  (\ref{ordinaryInvocation}).
\item
  If $D$ is an instance member of an extension $E$
  with type parameters \List{X}{1}{k},
  $i$ is treated as \code{$E$<\List{X}{1}{k}>(\THIS).$i$}.
  Both the static analysis and evaluation
  proceeds with the transformed expression,
  so there is no need to further specify the treatment of $i$.

  \commentary{%
    In other words, inside $E$ the instance members of $E$ will shadow
    the instance members of the \ON{} type, that is,
    the extension has higher priority than the object interface.
    The opposite is true for invocations everywhere outside $E$.

    There is no need to consider an instance member of a class,
    because a lexical lookup in a class will never yield a declaration
    which is an instance member.%
  }
\end{itemize}
\vspace{-2ex}
\EndCase

\Case{Lexical lookup yields an import prefix}
When the lexical lookup of \id{} yields an import prefix,
a compile-time error occurs.
\EndCase

\Case{Lexical lookup yields nothing}
When the lexical lookup of \id{} yields nothing,
$i$ is treated as
(\ref{notation})
the ordinary method invocation
\code{\THIS.$i$}
(\ref{ordinaryInvocation}).

\commentary{%
  This occurs when the lexical lookup has determined that
  $i$ must invoke an instance member of a class or an extension,
  and the location of $i$ can access \THIS,
  and the interface of the enclosing class has a member named \id,
  or there is an applicable extension with such a member.
  Both the static analysis and evaluation proceeds with
  \code{\THIS.$i$},
  so there is no need to further specify the treatment of $i$.%
}
\EndCase

\commentary{%
  Note that an unqualified invocation does not specify an evaluation semantics.
  This is because every case which is not an error ends in the conclusion that
  the unqualified invocation should be treated as some other construct,
  which is specified elsewhere.%
}


\subsubsection{Function Expression Invocation}
\LMLabel{functionExpressionInvocation}

\LMHash{}%
A function expression invocation $i$ has the form

\noindent
\code{$e_f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
where $e_f$ is an expression.

\commentary{%
  Note that the type argument list is omitted when $r = 0$
  (\ref{generics}).%
}

\LMHash{}%
Consider the situation where $e_f$ denotes a class $C$
that contains a declaration of a constructor named $C$,
or it is of the form \code{$e'_f$.\id} where
$e'_f$ denotes a class $C$ that contains a declaration of
a constructor named \code{$C$.\id}.
If $i$ occurs in a constant context
(\ref{constantContexts})
then $i$ is treated as \code{\CONST\,\,$i$},
and if $i$ does not occur in a constant context
then $i$ is treated as \code{\NEW\,\,$i$}.

\commentary{%
  When $i$ is treated as another construct $i'$,
  both the static analysis and the dynamic semantics
  is specified in the section about $i'$
  (\ref{notation}).%
}

\LMHash{}%
Otherwise, it is a compile-time error if $e_f$ is a type literal.

\commentary{%
  This error was already specified elsewhere
  (\ref{unqualifiedInvocation})
  for the case where $e_f$ is an identifier,
  but $e_f$ may also have other forms, e.g., \code{p.C}.%
}

\LMHash{}%
Otherwise, if $e_f$ is an identifier \id, then \id{} must necessarily denote
a local function, a library function, a library or static getter,
or a variable as described above,
or $i$ would not have been treated as a function expression invocation.

\LMHash{}%
If $e_f$ is a property extraction expression
(\ref{propertyExtraction})
then $i$ treated as an ordinary method invocation
(\ref{ordinaryInvocation}).

\commentary{%
  \code{$a.b(x)$} is treated as a method invocation of method
  \code{$b()$} on object \code{$a$},
  not as an invocation of getter \code{$b$} on \code{$a$}
  followed by a function call \code{$(a.b)(x)$}.
  If a method or getter \code{$b$} exists, the two will be equivalent.
  However, if \code{$b$} is not defined on \code{$a$},
  the resulting invocation of \code{noSuchMethod()} would differ.
  The \code{Invocation} passed to \code{noSuchMethod()} would describe
  a call to a method \code{$b$} with argument \code{$x$} in the former case,
  and a call to a getter \code{$b$} (with no arguments) in the latter.%
}

\LMHash{}%
Let $F$ be the static type of $e_f$.
If $F$ is an interface type that has a method named \CALL,
$i$ is treated as
(\ref{notation})
the ordinary invocation

\noindent
\code{$e_f$.\CALL<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\LMHash{}%
Otherwise, the static analysis of $i$ is performed as specified
in Section~\ref{bindingActualsToFormals},
using $F$ as the static type of the invoked function,
and the static type of $i$ is as specified there.

\LMHash{}%
Evaluation of a function expression invocation

\noindent
\code{$e_f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}

\noindent
proceeds to evaluate $e_f$, yielding an object $o$.
Let $f$ be a fresh variable bound to $o$.
If $o$ is a function object then the function invocation

\noindent
\code{$f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}

\noindent
is evaluated by binding actuals to formals
as specified in Section~\ref{bindingActualsToFormals},
and executing the body of $f$ with those bindings;
the returned result is then the result of evaluating $i$.

\LMHash{}%
Otherwise $o$ is not a function object.
If $o$ has a method named \CALL{}
the following ordinary method invocation is evaluated,
and its result is then the result of evaluating $i$:

\noindent
\code{$f$.call<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\LMHash{}%
Otherwise $o$ has no method named \CALL.
A new instance $im$ of the predefined class \code{Invocation} is created,
such that:

\begin{itemize}
\item \code{$im$.isMethod} evaluates to \TRUE.
\item \code{$im$.memberName} evaluates to the symbol \code{\#call}.
\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
  whose dynamic type implements \code{List<Object>},
  containing the objects resulting from evaluation of
  \code{<Object>[$a_1, \ldots,\ a_n$]}.
\item \code{$im$.namedArguments} evaluates to an unmodifiable map
  whose dynamic type implements \code{Map<Symbol, Object>},
  with the keys and values resulting from evaluation of

  \code{<Symbol, Object>\{$\#x_{n+1}$: $a_{n+1}, \ldots,\ \#x_{n+k}$: $a_{n+k}$\}}.
\item \code{$im$.typeArguments} evaluates to an unmodifiable list
  whose dynamic type implements \code{List<Type>},
  with the values resulting from evaluation of

  \code{<Type>[$A_1, \ldots,\ A_r$]}.
\end{itemize}

\LMHash{}%
Then the method invocation \code{f.noSuchMethod($im$)} is evaluated,
and its result is then the result of evaluating $i$.

\commentary{%
  The situation where \code{noSuchMethod} is invoked can only arise
  when the static type of $e_f$ is \DYNAMIC.
  The run-time semantics ensures that
  a function invocation may amount to an invocation of
  the instance method \CALL.
  However, an interface type with a method named \CALL{}
  is not itself a subtype of any function type
  (\ref{subtypeRules}).%
}


\subsection{Function Closurization}
\LMLabel{functionClosurization}

\LMHash{}%
Let $f$ be an expression denoting
a declaration of a top-level function, a local function,
a static method of a class, of a mixin, or of an extension
(\ref{identifierReference});
or let $f$ be a function literal
(\ref{functionExpressions}).
Evaluation of $f$ yields a function object
which is the outcome of a \Index{function closurization}
applied to the declaration denoted by $f$
respectively to the function literal $f$ considered as a function declaration.
% Note that we do not promise that this will be a fresh function object,
% such that constant expressions are covered as well, and others may be
% identical even if not required, e.g., local functions with no free variables.
\IndexCustom{Closurization}{closurization}
denotes instance method closurization
(\ref{instanceMethodClosurization})
as well as function closurization,
and it is also used as a shorthand for either of them
when there is no ambiguity.

\LMHash{}%
Function closurization applied to a function declaration $f$
amounts to the creation of a function object $o$
which is an instance of a class $C$ whose interface is
a subtype of the actual type $F$
(\ref{actualTypes})
corresponding to the signature in the function declaration $f$,
using the current bindings of type variables, if any.
There does not exist a function type $F'$ which is a proper subtype of $F$
such that $C$ is a subtype of $F'$.

\commentary{%
  If $f$ is a static method or a top-level function
  then $o$ has primitive equality
  (\ref{theOperatorEqualsEquals}).%
}

\commentary{%
  In other words, $C$ has the freedom to be a proper subtype of
  the function type that we can read off of the declaration of $f$
  because it may need to be a specific internal platform defined class,
  but $C$ does not have the freedom to be a subtype of
  a different and more special function type, and it cannot be \code{Null}.%
}

\LMHash{}%
An invocation of $o$ with a given argument list will bind actuals to formals
in the same way as an invocation of $f$
(\ref{bindingActualsToFormals}),
and then execute the body of $f$
in the captured scope amended with the bound parameter scope,
yielding the same completion
(\ref{statementCompletion})
as the invocation of $f$ would have yielded.

\LMHash{}%
Let $e_1$ and $e_2$ be two constant expressions that both
evaluate to a function object which is obtained by function closurization
of the same function declaration.
In this case \code{identical($e_1$, $e_2$)} shall evaluate to true.

\commentary{%
  That is, constant expressions whose evaluation is a function closurization
  are canonicalized.%
}


\subsection{Generic Function Instantiation}
\LMLabel{genericFunctionInstantiation}

%% TODO(eernst): The specification of generic function instantiation relies
%% on type inference in a different way than other mechanisms that we have
%% specified, because it is impossible to claim that 'type inference is
%% assumed to have taken place already' and then we just consider the
%% program where the missing type arguments or type annotations have been
%% added syntactically. Consequently, this section will probably need to be
%% rewritten rather extensively when we add a specification of inference.

\LMHash{}%
Generic function instantiation is a mechanism that yields
a non-generic function object based on a given generic function.

\rationale{%
  The essence of generic function instantiation
  is to allow for ``curried'' invocations,
  in the sense that a generic function can receive its actual
  type arguments separately
  (it must then receive \emph{all} type arguments, not just some of them),
  and that yields a non-generic function object.
  The type arguments are passed implicitly, based on type inference;
  %% TODO(eernst): Come constructor-tearoffs, revise this.
  a future version of Dart may allow for passing them explicitly.%
}
\commentary{Here is an example:}

\begin{dartCode}
X fg<X \EXTENDS{} num>(X x) => x;
\\
\CLASS{} A \{
  \STATIC{} X fs<X \EXTENDS{} num>(X x) => x;
\}
\\
\VOID{} main() \{
  X fl<X \EXTENDS{} num>(X x) => x;
  List<int \FUNCTION{}(int)> functions = [fg, A.fs, fl];
\}
\end{dartCode}

\noindent
\commentary{%
  Each function object stored in \code{functions}
  has dynamic type \code{int\,\,\FUNCTION(int)},
  and it is obtained by implicitly
  ``passing the actual type argument \code{int}''
  to the corresponding generic function.%
}

\LMHash{}%
\BlindDefineSymbol{f,G}
Let $f$ be an expression whose static type $G$ is
\BlindDefineSymbol{T_0,X_j,B_j,s,p}%
a generic function type of the form
\RawFunctionType{T_0}{X}{B}{s}{\metavar{p}}
where \code{($p$)} is derived from \synt{formalParameterList}.
\commentary{Note that $s > 0$ because $G$ is generic.}
Assume that the context type is a non-generic function type $F$.
In this situation a compile-time error occurs
(\ref{variables},
\ref{functions},
\ref{generativeConstructors},
\ref{redirectingGenerativeConstructors},
\ref{initializerLists},
\ref{new},
\ref{const},
\ref{bindingActualsToFormals},
\ref{assignment},
\ref{localVariableDeclaration},
\ref{switch},
\ref{return},
\ref{yieldEach}),
except when the following step succeeds:

\LMHash{}%
\IndexCustom{Generic function type instantiation}{%
  generic function type instantiation}:
Type inference is applied to $G$ with context type $F$,
and it yields the actual type argument list
\BlindDefineSymbol{T_j}%
\List{T}{1}{s}.

\commentary{%
  The generic function type instantiation fails
  in the case where type inference fails,
  in which case the above mentioned compile-time error occurs.
  It will be specified in a future version of this document
  how type inference computes \List{T}{1}{s}
  (\ref{overview}).%
}

\LMHash{}%
Assume that the generic function type instantiation succeeded.
Let \DefineSymbol{F'} denote the type
$[T_1/X_1, \ldots, T_s/X_s](\FunctionTypeSimple{T_0}{$p$})$.
\commentary{%
  Note that it is guaranteed that $F'$ is assignable to $F$,
  or inference would have failed.%
}
Henceforth in the static analysis,
this occurrence of $f$ is considered to have static type $F'$.

\LMHash{}%
Execution of $f$ proceeds as follows.
Evaluate $f$ to an object $o$.
%% TODO(eernst): Come null-safety, remove the next line.
A dynamic error occurs if $o$ is the null object.
Let \RawFunctionType{S_0}{Y}{B'}{s}{$q$} be the dynamic type of $o$
\commentary{(by soundness, this type is a subtype of $G$)}.
$f$ then evaluates to a function object $o'$ with dynamic type
$[t_1/Y_1, \ldots, t_s/Y_s](\FunctionTypeSimple{S_0}{$q$})$,
where $t_j$ is the actual value of $T_j$, for $j \in 1 .. k$.
An invocation of $o'$ with actual arguments \metavar{args} has
the same effect as an invocation of $o$
with actual type arguments \List{t}{1}{s} and actual arguments \metavar{args}.

\LMHash{}%
Let $f_1$ and $f_2$ be two constant expressions that are subject to
generic function instantiation.
Assume that $f_1$ and $f_2$ without a context type evaluate to $o_1$
respectively $o_2$ such that \code{identical($o_1$, $o_2$)} is true.
Assume that the given context types give rise to a successful
generic function type instantiation with
the same actual type arguments for $f_1$ and $f_2$,
yielding the non-generic function objects $o'_1$ respectively $o'_2$.
In this case \code{identical($o'_1$, $o'_2$)} shall evaluate to true.

\commentary{%
  That is, constant expressions whose evaluation is
  a generic function instantiation are canonicalized,
  based on the underlying function and on the actual type arguments.
  As a consequence, they are also equal according to operator \lit{==}.%
}

\LMHash{}%
Let $g_1$ and $g_2$ be two expressions
\commentary{(which may or may not be constant)}
that are subject to generic function instantiation.
Assume that $g_1$ and $g_2$ without a context type evaluate to $o_1$
respectively $o_2$ such that \code{$o_1$ == $o_2$)} is true.
Assume that the given context types give rise to a successful
generic function type instantiation with
the same actual type arguments for $g_1$ and $g_2$,
yielding the non-generic function objects $o'_1$ respectively $o'_2$.
In this case \code{$o'_1$ == $o'_2$} shall evaluate to true.

\commentary{%
  When one or both of the expressions is not constant,
  it is unspecified whether
  \code{identical($o_1$,\,\,$o_2$)} evaluates to \TRUE{} or \FALSE,
  but operator \lit{==} yields true for equal function objects
  instantiated with the same actual type arguments.%
}

\rationale{%
  No notion of equality is appropriate when the type arguments differ,
  even if the resulting function objects
  turn out to have exactly the same type at run time,
  because execution of two function objects that differ in these ways
  can have different side-effects and return different results
  when executed starting from exactly the same state.%
}


\subsection{Lookup}
\LMLabel{lookup}

\LMHash{}%
A \Index{lookup} is a procedure which selects
a concrete instance member declaration based on a traversal of
a sequence of classes, starting with a given class $C$
and proceeding with the superclass of the current class at each step.
A lookup may be part of the static analysis, and it may be performed
at run time. It may succeed or fail.

\commentary{%
  We define several kinds of lookup with a very similar structure.
  We spell out each of them in spite of the redundancy,
  in order to avoid introducing meta-level abstraction mechanisms
  just for this purpose.
  The point is that we must indicate for each lookup
  which kind of member it is looking for,
  because, e.g., a `method lookup' and a `getter lookup' are used
  in different situations.%
}

{ % Scope for `lookup' definition.

\def\LookupDefinitionWithStart#1{
\LMHash{}%
The result of a
{\em {#1} lookup for $m$ in $o$ with respect to $L$ starting in class $C$}
is the result of a {#1} lookup for $m$ in $C$ with respect to $L$.
The result of a {\em {#1} lookup for $m$ in $C$ with respect to $L$} is:
If $C$ declares a concrete instance {#1} named $m$
that is accessible to $L$,
then that {#1} declaration is the result of the {#1} lookup,
and we say that the {#1} was {\em looked up in $C$}.
Otherwise, if $C$ has a superclass $S$,
the result of the {#1} lookup is
the result of a {#1} lookup for $m$ in $S$ with respect to $L$.
Otherwise, we say that the {#1} lookup has failed.

}

\LMHash{}%
Let $m$ be an identifier, $o$ an object, $L$ a library,
and $C$ a class which is the class of $o$ or a superclass thereof.

\LookupDefinitionWithStart{method}
\LookupDefinitionWithStart{getter}
\LookupDefinitionWithStart{setter}

\def\LookupDefinition#1{%
The result of a
{\em {#1} lookup for $m$ in $o$ with respect to $L$}
is the result of a
{#1} lookup for $m$ in $o$ with respect to $L$
starting with the class of $o$.
}

\LMHash{}%
Let $m$ be an identifier, $o$ an object, and $L$ a library.
\LookupDefinition{method}
\LookupDefinition{getter}
\LookupDefinition{setter}

} % End of scope for lookup definitions.

\commentary{%
  Note that for getter (setter) lookup, the result may be
  a getter (setter) which has been induced by an instance variable
  declaration.%
}

\commentary{%
  Note that we sometimes use phrases like `looking up method $m$'
  to indicate that a method lookup is performed,
  and similarly for setter lookups and getter lookups.%
}

\rationale{%
  The motivation for ignoring abstract members during lookup
  is largely to allow smoother mixin composition.%
}


\subsection{Top level Getter Invocation}
\LMLabel{topLevelGetterInvocation}

\LMHash{}%
Evaluation of a top-level getter invocation $i$ of the form $m$,
where $m$ is an identifier,
proceeds as follows:

\LMHash{}%
The getter function $m$ is invoked.
The value of $i$ is the result returned by the call to the getter function.
\commentary{%
  Note that the invocation is always defined.
  Per the rules for identifier references,
  an identifier will not be treated as a top-level getter invocation
  unless the getter $i$ is defined.%
}

\LMHash{}%
The static type of $i$ is the declared return type of $m$.


\subsection{Member Invocations}
\LMLabel{memberInvocations}

\begin{figure}[h]
  \begin{minipage}[t]{\textwidth}
    \begin{displaymath}
      \hspace{-2mm}\begin{array}[t]{lll}
        \parbox{.22\textwidth}{\small Simple member\\invocation}
        & \parbox{.17\textwidth}{\small Corresponding member name} \\[3mm]
        \hline
        \code{$r$.\id, $r$?.\id}                         & \id \\
        \code{$r$.\id{} = $e$,
          $r$?.\id{} = $e$}                              & \code{\id=} \\
        \code{$r$.\id(\metavar{args}),
          $r$?.\id(\metavar{args})}                      & \id \\
        \code{$r$.\id<\metavar{types}>(\metavar{args})}  & \id \\
        \code{$r$?.\id<\metavar{types}>(\metavar{args})} & \id \\
        \code{-$r$}                                      & \code{unary-} \\
        \code{\gtilde{}$r$}                              & \gtilde{} \\
        \code{$r$ $\oplus$ $e$}                          & \oplus \\
        \code{$r$[$e$]}                                  & \code{[]} \\
        %% TODO(eernst): Come nnbd, uncomment this.
        % \code{$r$?[$e$]}                                 & \code{[]} \\
        \code{$r$[$e_1$] = $e_2$}                        & \code{[]=} \\
        %% TODO(eernst): Come nnbd, uncomment this.
        % \code{$r$?[$e_1$] = $e_2$}                       & \code{[]=} \\
        \code{$r$(\metavar{args})}                       & \CALL{} \\
        \code{$r$<\metavar{types}>(\metavar{args})}      & \CALL{} \\
      \end{array}
      \quad
      \begin{array}[t]{ll}
        \parbox{.23\textwidth}{\small Composite member\\invocation}
        & \parbox{.18\textwidth}{\small Corresponding member name} \\[3mm]
        \hline
        \code{$r$.\id{} $\otimes$= $e$}      & \id \\
        \code{$r$?.\id{} $\otimes$= $e$}     & \id \\
        \code{$r$[$e_1$] $\otimes$= $e_2$}  & \code{[]} \\
        %% TODO(eernst): Come nnbd, uncomment this.
        % \code{$r$?[$e_1$] $\otimes$= $e_2$} & \code{[]} \\
        \code{++$r$.\id, -{}-$r$.\id}       & \id \\
        \code{$r$.\id++, $r$.\id-{}-}       & \id \\
        \code{++$r$[$e$], -{}-$r$[$e$]}     & \code{[]} \\
        \code{$r$[$e$]++, $r$[$e$]-{}-}     & \code{[]}
      \end{array}
    \end{displaymath}
  \end{minipage}

  \vspace{4mm}
  \begin{minipage}[t]{\textwidth}
    \small
    In the tables above,
    $r$, $e$, $e_1$, $e_2$ are expressions;
    \metavar{args} is derived from \synt{arguments};
    \metavar{types} is derived from \synt{typeArguments};
    `$\oplus$' is an \synt{operator} which is not \lit{==};
    %% TODO(eernst): Add exception for &&=, ||= when support for them is added.
    and `\code{$\otimes$=}' is a \synt{compoundAssignmentOperator}.
  \end{minipage}
  %
  \caption{Member invocations with syntactic receiver $r$.}
  \label{fig:memberInvocations}
\end{figure}

\LMHash{}%
A \Index{member invocation} is an expression with a specific syntactic form
whose dynamic semantics involves invocation of
one or two instance members of a given receiver,
or invocation of extension members.
This section specifies which syntactic forms are member invocations,
and defines some terminology
which is needed in order to denote
specific parts of several syntactic forms collectively.

\LMHash{}%
The static analysis and dynamic semantics of
each of the syntactic forms that are member invocations
is specified separately,
this section is only concerned with
the syntactic classification and terminology.

\commentary{%
  For example, one kind of member invocation is an ordinary method invocation
  (\ref{ordinaryInvocation}).%
}

\LMHash{}%
A
\IndexCustom{simple member invocation}{member invocation!simple}
respectively
\IndexCustom{composite member invocation}{member invocation!composite}
on a
\IndexCustom{syntactic receiver}{member invocation!syntactic receiver}
expression $r$ is an expression of
one of the forms shown in Fig.~\ref{fig:memberInvocations}.
Each member invocation has a
\IndexCustom{corresponding member name}{%
  member invocation!corresponding member name}
as shown in the figure.

\LMHash{}%
Each member invocation in Fig.~\ref{fig:memberInvocations} that contains
\lit{?} is a
\IndexCustom{conditional member invocation}{member invocation!conditional}.
An
\IndexCustom{unconditional member invocation}{member invocation!unconditional}
is a member invocation which is not conditional.

\commentary{%
  For a simple member invocation the corresponding member name is
  the name of the member which is invoked
  in the case where the member invocation invokes an instance member.
  For a composite member invocation it is the name of the getter
  and the basename of both the getter and the setter.%
}

\rationale{%
  Note that $r$ cannot be \SUPER{}
  even though \code{\SUPER.m()} invokes an instance method.
  This is because the semantics of a superinvocation is different from
  that of other invocations.
  Among the binary operators, \lit{==} is not included.
  This is because evaluation of \code{$e_1$ == $e_2$}
  involves more steps than an instance member invocation.
  Similarly, \lit{\&\&}, and \lit{||} are not included
  because their evaluation does not involve method invocation.%
}

\begin{figure}[t]
  \begin{minipage}[h]{\textwidth}
    \begin{displaymath}
      \begin{array}{ll}
        \mbox{Source} & \mbox{Desugared form} \\
        \hline
        % ---------- Simple member invocations.
        \code{$r$?.\id} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r'$.\id}
        \\
        \code{$r$?.\id{} = $e$} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r'$.\id{} = $e$}
        \\
        \code{$r$?.\id(\metavar{args})} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r'$.\id(\metavar{args})}
        \\
        \code{$r$?.\id<\metavar{types}>(\metavar{args})} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r$.\id<\metavar{types}>(\metavar{args})}
        \\
        %% TODO(eernst): Come nnbd, uncomment this.
        \code{$r$?[$e$]} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r'$[$e$]}
        \\
        %% TODO(eernst): Come nnbd, uncomment this.
        \code{$r$?[$e_1$] = $e_2$} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r'$[$e_1$] = $e_2$}
        \\
        % ---------- Composite member invocations.
        \code{$r$.\id{} ??= $e$} &
        \Let{$v$}{$r'$.\id}{$v$\,==\,\NULL\ ?\ $r'$.\id\,=\,$e$\,:\,$v$}
        \\
        \code{$r$.\id{} $\otimes$= $e$} &
        \code{$r'$.\id{} = $r'$.\id{} $\otimes$ $e$}
        \\
        \code{$r$?.\id{} $\otimes$= $e$} &
        \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ $r'$.\id\,$\otimes$=\,\,$e$}
        \\
        \code{$r$[$e_1$] ??= $e_2$} &
        \LetTwo{$v$}{$e_1$}{$v'$}{$r'$[$v$]}{%
          $v'$\,==\,\NULL\ ?\ $r'$[$v$]\,=\,$e_2$\,:\,$v'$}
        \\
        \code{$r$[$e_1$] $\otimes$= $e_2$} &
        \Let{$v$}{$e_1$}{$r'$[$v$] = $r'$[$v$]\,$\otimes$\,$e_2$}
        \\
        %% TODO(eernst): Come nnbd, un-comment this. 4 similar cases below.
        %% \code{$r$?[$e_1$] $\otimes$= $e_2$} &
        %% \code{$r'$\,==\,\NULL\ ?\ \NULL\ :\ %
        %%   $r'$[$e_1$]\,\,$\otimes$=\,\,$e_2$}
        %% \\
        \code{++$r$.\id} &
        \code{$r$.\id{} += 1}
        \\
        \code{-{}-$r$.\id} &
        \code{$r$.\id{} -= 1}
        \\
        \code{$r$.\id++} &
        \LetTwo{$v$}{$r'$.\id}{$v'$}{$r'$.\id\,=\,$v$\,+\,1}{$v$}
        \\
        \code{$r$.\id-{}-} &
        \LetTwo{$v$}{$r'$.\id}{$v'$}{$r'$.\id\,=\,$v$\,-\,1}{$v$}
        \\
        \code{++$r$[$e$]} &
        \code{$r$[$e$] += 1}
        \\
        \code{-{}-$r$[$e$]} &
        \code{$r$[$e$] -= 1}
        \\
        \code{$r$[$e$]++} &
        \LetThree{$v$}{$e$}{$v'$}{$r'$[$v$]}{$v''$}{%
          $r'$[$v$]\,=\,$v'$\,+\,1}{$v'$}
        \\
        \code{$r$[$e$]-{}-} &
        \LetThree{$v$}{$e$}{$v'$}{$r'$[$v$]}{$v''$}{%
          $r'$[$v$]\,=\,$v'$\,-\,1}{$v'$}
      \end{array}
    \end{displaymath}
  \end{minipage}
  %
  \caption{Desugaring of member invocations.
    `\code{$\otimes$=}' is a \synt{compoundAssignmentOperator}.
    The first applicable rule is used.
    In particular, `\code{$\otimes$=}' cannot be `\code{??=}'
    when an earlier rule with `\code{??=}' matches.
    $r'$ is known as the \emph{replacement receiver} of
    the composite member invocation,
    and it is specified in the main text
    (\ref{memberInvocations}).}
  \label{fig:desugarCompositeMemberInvocations}
\end{figure}

\LMHash{}%
A composite member invocation is an abbreviated form
whose meaning is reduced to simple member invocations
as shown in Fig.~\ref{fig:desugarCompositeMemberInvocations}.
This step is known as a \Index{desugaring} transformation,
and we say that the resulting expression has been \Index{desugared}.
Fig.~\ref{fig:desugarCompositeMemberInvocations} contains
several occurrences of $r'$
which is the
\IndexCustom{replacement receiver}{method invocation!replacement receiver}
of the composite method invocation.
The meaning of each occurrence of $r'$ is determined as follows:

\LMHash{}%
When the receiver $r$ is an extension application
(\ref{explicitExtensionInvocations})
of the form \code{$E$<\List{T}{1}{k}>($e_r$)}
\commentary{(where $k = 0$ means that the type argument list is absent)}:
Let $v_r$ be a fresh variable bound to the value of $e_r$
and with the same static type as $e_r$,
then $r'$ is \code{$E$<\List{T}{1}{k}>($v_r$)} when it occurs
as the receiver of a member invocation,
and otherwise $r'$ is $v_r$.

\LMHash{}%
When $r$ is not an extension application,
$r'$ is a fresh variable bound to the value of $r$,
with the same static type as $r$.

\commentary{%
  This corresponds to an extra outermost \LET{} in each rule
  in Fig.~\ref{fig:desugarCompositeMemberInvocations}
  where $r'$ occurs,
  and an explicit distinction between the two forms of $r$,
  but the figure would be considerably more verbose if it had been
  specified in that manner.%
}


\subsection{Method Invocation}
\LMLabel{methodInvocation}

\LMHash{}%
Method invocation can take several forms as specified below.


\subsubsection{Ordinary Invocation}
\LMLabel{ordinaryInvocation}

\LMHash{}%
An ordinary method invocation can be conditional or unconditional.

\LMHash{}%
\Case{\code{$e$?.$m$<$\cdots$>($\cdots$)}}
Consider a
\IndexCustom{conditional ordinary method invocation}{%
  method invocation!conditional ordinary}
$i$ of the form
\code{$e$?.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\commentary{%
  Note that non-generic invocations arise as the special case where
  the number of type arguments is zero,
  in which case the type argument list is omitted,
  and similarly for formal type parameter lists (\ref{generics}).%
}

\LMHash{}%
The static type of $i$ is the same as the static type of

\noindent
\code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\noindent
Exactly the same compile-time errors that would be caused by

\noindent
\code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}

\noindent
are also generated in the case of $i$.

\LMHash{}%
Evaluation of $i$ proceeds as follows:

\LMHash{}%
If $e$ is a type literal or denotes an extension, $i$ is treated as

\noindent
\code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\LMHash{}%
Otherwise, evaluate $e$ to an object $o$.
If $o$ is the null object, $i$ evaluates to the null object (\ref{null}).
Otherwise let $v$ be a fresh variable bound to $o$ and evaluate
\code{$v$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
to an object $r$.
Then $e$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$C$.$m$<$\cdots$>($\cdots$)}}
A \IndexCustom{static member invocation}{member invocation!static}
$i$ is an invocation of the form
\code{$C$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$:\ $a_{n+1}, \ldots,\ x_{n+k}$:\ $a_{n+k}$)},
where $C$ is a type literal, or $C$ denotes an extension.

\commentary{%
  Non-generic invocations arise as the special case
  where the number of type arguments is zero (\ref{generics}).%
}

\LMHash{}%
A compile-time error occurs
unless $C$ denotes a class, a mixin, or an extension that declares
a static member named $m$,
which we will call the
\IndexCustom{denoted member}{static member invocation!denoted member}
of $i$.
When the denoted member is a static method, let $F$ be its function type;
when the denoted member is a static getter, let $F$ be its return type;
when the denoted member is neither, a compile-time error occurs.

\LMHash{}%
The static analysis of $i$ is then performed
as specified in Section~\ref{bindingActualsToFormals},
considering $F$ to be the static type of the function to call,
and the static type of $i$ is as specified there.

\LMHash{}%
Evaluation of a static method invocation $i$ of the form

\noindent
\code{$C$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}

\noindent
proceeds as follows:

\LMHash{}%
If the denoted member of $i$ is a static method,
let $f$ be the function declared by that member.
The binding of actual arguments to formal parameters is performed
as specified in Section~\ref{bindingActualsToFormals}.
The body of $f$ is then executed with respect to the bindings
that resulted from the evaluation of the argument part.
The value of $i$ is the object returned by the execution of $f$'s body.

\LMHash{}%
If the denoted member of $i$ is a static getter,
invoke said getter and let $v_f$ be
a fresh variable bound to the returned object.
Then the value of $i$ is the value of
\code{$v_f$<$A_1, \ldots,\ A_r$>($a_1,\ \ldots,\ a_n,\ x_{n+1}$: $a_{n+1},\ \ldots,\ x_{n+k}$: $a_{n+k}$)}.
\EndCase

\LMHash{}%
\Case{\code{$e$.$m$<$\cdots$>($\cdots$)}}
An \IndexCustom{unconditional ordinary method invocation}{%
  method invocation!unconditional ordinary}
$i$ has the form
\code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},
where $e$ is an expression that is not a type literal,
and does not denote an extension.

\commentary{%
  Non-generic invocations arise as the special case
  where the number of type arguments is zero (\ref{generics}).%
}

\LMHash{}%
Let $T$ be the static type of $e$.

\LMHash{}%
If $T$ is \DYNAMIC{} bounded
(\ref{bindingActualsToFormals})
and $m$ is one of
\code{hashCode}, \code{noSuchMethod}, \code{runtimeType}, or \code{toString}
then we say that $i$ is a
\IndexCustom{dynamic \code{Object} member invocation}{
  dynamic Object member invocation},
whose static analysis is specified separately below.

\LMHash{}%
Otherwise, it is a compile-time error if $T$ does not have an accessible
(\ref{privacy})
instance member named $m$, unless either:

\begin{itemize}
\item
  $T$ is \DYNAMIC{} bounded;
  in this case no further static checks are performed on $i$
  \commentary{(apart from separate static checks on subterms like arguments)}
  and the static type of $i$ is \DYNAMIC.
  Or
\item
  $T$ is \FUNCTION{} bounded
  (\ref{bindingActualsToFormals})
  and $m$ is \CALL;
  in this case no further static checks are performed on $i$
  \commentary{(apart from separate static checks on subterms like arguments)}
  and the static type of $i$ is \DYNAMIC.
\rationale{%
  This means that for invocations of an instance method named \CALL,
  a receiver of type \FUNCTION{} is treated like a receiver of type \DYNAMIC.
  The expectation is that any concrete subclass of \FUNCTION{}
  will implement \CALL,
  but there is no method signature
  which can be assumed for \CALL{} in \FUNCTION{}
  because every signature will conflict with
  some potential overriding declarations.%
}
\end{itemize}

\LMHash{}%
If $T$ did not have an accessible member named $m$
the static type of $i$ is \DYNAMIC,
and no further static checks are performed on $i$
\commentary{%
  (except that subexpressions of $i$ are subject to their own static analysis)%
}.

\LMHash{}%
If $i$ is a dynamic \code{Object} member invocation
(\ref{ordinaryInvocation})
then the static type of the member is specified in
Section~\ref{typeDynamic}.
In this case, if $m$ is \code{hashCode} or \code{runtimeType}
then let $F$ be the return type of said getter;
if $m$ is \code{noSuchMethod} or \code{toString}
then let $F$ be the type of said method.

\commentary{%
  Note that it is always a compile-time error if $m$
  is \code{hashCode} or \code{runtimeType}.%
}

\LMHash{}%
Otherwise, \code{$T$.$m$} denotes an instance member.
Let $L$ be the library that contains $i$.
Let $d$ be the result of method lookup for $m$ in $T$ with respect to $L$,
and if the method lookup succeeded then let $F$ be the static type of $d$.

\LMHash{}%
Otherwise, let $d$ be the result of getter lookup
for $m$ in $T$ with respect to $L$,
and let $F$ be the return type of $d$.
\commentary{%
  Since \code{$T$.$m$} exists we cannot have a failure in both lookups.%
}
If the getter return type $F$ is an interface type
that has a method named \CALL,
$i$ is treated as
(\ref{notation})
the ordinary invocation

\noindent
\code{$e$.$m$.call<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
which determines any further static analysis.

\LMHash{}%
Otherwise, the static analysis of $i$ is performed
as specified in Section~\ref{bindingActualsToFormals},
considering $F$ to be the static type of the function to call,
and the static type of $i$ is as specified there,
except that invocations of methods named \code{remainder}
or \code{clamp} on subtypes of \code{num} that are not subtypes of \code{Never}
have special rules similar to those for additive (\ref{additiveExpressions})
and multipliative (\ref{multiplicativeExpressions}) operators.

\LMHash{}%
Let $i$ be an invocation of the form \code{$e$.remainder($e_2$)}
and let $C$ be the context type of $i$.
The context type of $e_2$ is then determined as follows:
If \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}}, then:

\begin{itemize}
  \item{} If \SubtypeNE{\code{int}}{C} and not \SubtypeNE{\code{num}}{C},
      and \SubtypeNE{T}{\code{int}}
      then the context type of $e_2$ is \code{int}.
  \item{} If \SubtypeNE{\code{double}}{C} and not \SubtypeNE{\code{num}}{C},
      and not \SubtypeNE{T}{\code{double}}
     then the context type of $e_2$ is \code{double}.
  \item{} Otherwise the context type of $e_2$ is \code{num}.
\end{itemize}

\LMHash{}%
Let further $S$ be the static type of $e_2$.
If \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}}
and $S$ is assignable to \code{num},
then the static type of $i$ is determined as follows:

\begin{itemize}
  \item{} If \SubtypeNE{T}{\code{double}}
    then the static type of $i$ is $T$.
  \item{} Otherwise, if \SubtypeNE{S}{\code{double}}
    and not \SubtypeNE{S}{\code{Never}},
    then the static type of $i$ is \code{double}.
  \item{} Otherwise, if \SubtypeNE{T}{\code{int}},
    \SubtypeNE{S}{\code{int}} and not \SubtypeNE{S}{\code{Never}},
    then the static type of $i$ is \code{int}.
  \item{} Otherwise the static type of $i$ is \code{num}.
\end{itemize}

\LMHash{}%
Let $i$ be an invocation of the form \code{$e$.clamp($e_2$,\,\,$e_3$)},
where \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}},
and let $C$ be the context type of $i$.
The context type of $e_2$ and $e_3$ is then determined as follows:

\begin{itemize}
  \item{} If \SubtypeNE{T}{\code{int}},
    \SubtypeNE{\code{int}}{S} and not \SubtypeNE{\code{num}}{S},
    then the context type of $e_2$ and $e_3$ is \code{int}.
  \item{} If \SubtypeNE{T}{\code{double}},
    \SubtypeNE{\code{double}}{S} and not \SubtypeNE{\code{num}}{S},
    then the context type of $e_2$ and $e_3$ is \code{double}.
  \item{} Otherwise the context type of $e_2$ and $e_3$ is \code{num}.
\end{itemize}

\LMHash{}%
Let further $T_2$ be the static type of $e_2$ and $T_3$ be the static type
of $e_3$.

\begin{itemize}
  \item{} If all of $T$, $T_2$ and $T_3$ are subtypes of \code{int}, but
    not subtypes of \code{Never}, then the static type of $i$ is \code{int}.
  \item{} If all of $T$, $T_2$ and $T_3$ are subtypes of \code{double}, but
    not subtypes of \code{Never}, then the static type of $i$ is \code{double}.
  \item{} Otherwise the static type of $i$ is \code{num}.
\end{itemize}

\LMHash{}%
It is a compile-time error to invoke an instance method on a type literal
that is immediately followed by the token `.' (a period).
\commentary{For instance, \code{int.toString()} is an error.}

\rationale{%
  The reason for this rule is that member access on a type literal
  is reserved for invocation of static members.
  Invocation of a static member of a class, mixin, enum, or extension
  uses said entity as a \emph{namespace},
  not as an actual class, mixin, enum, or extension.
  In particular, the syntactic receiver is not evaluated
  to an object---that would not even be possible for an extension.%
}

\commentary{%
  A member access on a type literal
  (e.g., \code{C.id()}, \code{C.id}, or \code{C?.id()}),
  always treats the declaration denoted by the literal as
  a namespace for accessing static members or constructors.
  For instance, \code{int.toString()} is an error
  because \code{int} does not declare a static member named \code{toString}.
  It will not evaluate \code{int} to a \code{Type} object
  and then call its \code{toString} instance method.
  To do that, you can use \code{(int).toString()}.
  Note that cascades are different:
  they \emph{always} evaluate their receiver to an object first.

  As a natural consequence,
  a type literal cannot be the receiver in
  an implicit invocation of an extension method
  (\ref{implicitExtensionInvocations}).%
}

\LMHash{}%
Evaluation of an unconditional ordinary method invocation $i$ of the form
\code{$e$.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
proceeds as follows:

\LMHash{}%
First, the expression $e$ is evaluated to an object $o$.
Let $f$ be the result of looking up
(\ref{lookup})
method $m$ in $o$ with respect to the current library $L$.

\LMHash{}%
If the method lookup succeeded,
the binding of actual arguments to formal parameters is performed
as specified in Section~\ref{bindingActualsToFormals}.
The body of $f$ is then executed with respect to the bindings
that resulted from the evaluation of the argument list,
and with \THIS{} bound to $o$.
The value of $i$ is the object returned by the execution of $f$'s body.

\LMHash{}%
If the method lookup failed,
then let $g$ be the result of looking up getter
(\ref{lookup})
$m$ in $o$ with respect to $L$.

\LMHash{}%
If the getter lookup succeeded then invoke the getter $o.m$
and let $v_g$ be the returned object.
Then the value of $i$ is the value of

\noindent
\code{$v_g$<$A_1, \ldots,\ A_r$>($a_1,\ \ldots,\ a_n,\ x_{n+1}$: $a_{n+1},\ \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\LMHash{}%
If getter lookup has also failed,
then a new instance $im$ of the predefined class \code{Invocation} is created,
such that:

\begin{itemize}
\item \code{$im$.isMethod} evaluates to \TRUE.
\item \code{$im$.memberName} evaluates to the symbol \code{m}.
\item \code{$im$.positionalArguments} evaluates to an unmodifiable list
  whose dynamic type implements \code{List<Object>},
  containing the objects resulting from the evaluation of
  \code{<Object>[$a_1, \ldots,\ a_n$]}.
\item \code{$im$.namedArguments} evaluates to an unmodifiable map
  whose dynamic type implements \code{Map<Symbol, Object>},
  with the keys and values resulting from the evaluation of

  \code{<Symbol, Object>\{$\#x_{n+1}$: $a_{n+1}, \ldots,\ \#x_{n+k}$: $a_{n+k}$\}}.
\item \code{$im$.typeArguments} evaluates to an unmodifiable list
  whose dynamic type implements \code{List<Type>},
  containing the objects resulting from the evaluation of
  \code{<Type>[$A_1, \ldots,\ A_r$]}.
\end{itemize}

\LMHash{}%
Then the method \code{noSuchMethod()} is looked up in $o$ and
invoked with argument $im$,
and the result of this invocation is the result of evaluating $i$.

\commentary{%
  The situation where \code{noSuchMethod} is invoked can only arise
  when the static type of $e$ is \DYNAMIC.
  Notice that the wording avoids re-evaluating the receiver $o$ and
  the arguments $a_i$.%
}
\EndCase


\subsubsection{Cascades}
\LMLabel{cascades}

\LMHash{}%
A \Index{cascade} is a kind of expression that allows for performing
multiple operations on a given object
without storing it in a variable and accessing it via a name.
In general, a cascade can be recognized by the use of exactly two periods,
\lit{..}.

\begin{grammar}
<cascade> ::= <cascade> `..' <cascadeSection>
  \alt <conditionalExpression> (`?..' | `..') <cascadeSection>

<cascadeSection> ::= <cascadeSelector> <cascadeSectionTail>

<cascadeSelector> ::= `[' <expression> `]'
  \alt <identifier>

<cascadeSectionTail> ::= <cascadeAssignment>
  \alt <selector>* (<assignableSelector> <cascadeAssignment>)?

<cascadeAssignment> ::= <assignmentOperator> <expressionWithoutCascade>
\end{grammar}

\LMHash{}%
A \IndexCustom{cascaded member access}{cascaded member access}
is an expression derived from \synt{cascade}.

\rationale{%
  A \synt{cascadeSection} allows for accessing members, including setters.
  The motivation for having a cascaded member access is that it allows for
  performing a chain of operations based on an object
  while preserving a reference to that object for further processing.%
}

\commentary{%
  Let $e_0$ be an extension application
  (\ref{extensions}).
  Note that it is then a compile-time error
  to have a \synt{cascade} of the form
  \code{$e_0$..$c$} or \code{$e_0$?..$c$},
  where $c$ is a \synt{cascadeSection}.%
}

\commentary{%
  For example, \code{C()..foo.bar = 2} allows us to obtain a reference to
  the object $o$ which is the result of evaluating \code{C()},
  and at the same time use $o$ to invoke the getter \code{foo} and
  the setter \code{bar=} on the value returned by that getter.%
}

\LMHash{}%
An expression of the form \code{$e_0$?..$s$} where
$e_0$ is a \synt{conditionalExpression} and
$s$ is a \synt{cascadeSection} is an
\IndexCustom{initially conditional cascaded member access}{%
  cascaded member access!initially conditional}.
Moreover, if \code{$e_0$} is
an initially conditional cascaded member access and
$s$ is derived from \synt{cascadeSection} then
\code{$e_0$..$s$} is also initially conditional.

\commentary{%
  In short, a cascade is initially conditional if
  the ``innermost dots'' are \lit{?..} rather than \lit{..}.
  Note that only the innermost dots can have the \lit{?}.
  All the non-innermost ones are implicitly skipped if the receiver is null,
  so any \lit{?} on a non-innermost \lit{..} would be useless.%
}

\LMHash{}%
The static analysis and dynamic semantics of a cascaded member access
is specified in terms of the following desugaring step.

\LMHash{}%
Let $e$ be a cascaded member access which is not initially conditional.
This implies that there exist terms \List{c}{1}{k}
derived from \synt{cascadeSection}
and a \synt{conditionalExpression} $e_0$
which is not an extension application,
and $e$ is \code{$e_0$..$c_1\ \cdots\ $..$c_k$}.
In this case, $e$ is desugared to

\noindent
\LetThree{$v$}{$e_0$}{$v_1$}{$v$.$c_1$,\ $\cdots$}{$v_k$}{$v$.$c_k$}{$v$}.

\LMHash{}%
Let $e$ be a cascaded member access which is initially conditional.
This implies that there exist terms \List{c}{1}{k}
derived from \synt{cascadeSection}
and a \synt{conditionalExpression} $e_0$
which is not an extension application,
and $e$ is \code{$e_0$?..$c_1\ \cdots\ $..$c_k$}.
In this case, $e$ is desugared to

\noindent
\Let{$v$}{$e_0$}{%
$v$\,==\,\NULL\ ?\ \NULL\ :\ \LetMany{$v_1$}{$v$.$c_1$}{$v_k$}{$v$.$c_k$}{$v$}}.

\commentary{%
  Note that the grammar is such that \code{$v$.$c_j$} is
  a syntactically correct expression for all $j$.%
}


\subsubsection{Superinvocations}
\LMLabel{superInvocations}

% Conditional superinvocations are meaningless: \THIS{} is not null.

\LMHash{}%
A \Index{method superinvocation} $i$ has the form
\BlindDefineSymbol{i, m, A_j, a_j, x_j}%

\noindent
\code{\SUPER.$m$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\commentary{%
  Note that non-generic invocations arise as
  the special case where the number of type arguments is zero,
  in which case the type argument list is omitted,
  and similarly for formal type parameter lists (\ref{generics}).%
}

\LMHash{}%
It is a compile-time error if a method superinvocation occurs
in a top-level function or variable initializer,
in an instance variable initializer or initializer list,
in class \code{Object},
in a factory constructor,
or in a static method or variable initializer.

{ % Scope for superclass name.

\def\SuperClass{\ensuremath{S_{\mbox{\scriptsize{}super}}}}

\LMHash{}%
\BlindDefineSymbol{\SuperClass, L}%
Let \SuperClass{} be the superclass (\ref{superclasses})
of the immediately enclosing class for $i$,
\BlindDefineSymbol{D, F}%
and let $L$ be the library that contains $i$.
Let the declaration $D$ be
the result of looking up the method $m$ in \SuperClass{}
with respect to $L$ (\ref{lookup}),
and let $F$ be the static type of $D$.
Otherwise, if the method lookup failed,
let the declaration $D$ be the result of looking up
the getter $m$ with respect to $L$ in \SuperClass{}
(\ref{lookup}),
and let $F$ be the return type of $D$.
If both lookups failed, a compile-time error occurs.

\LMHash{}%
Otherwise
\commentary{(when one of the lookups succeeded)},
the static analysis of $i$ is performed
as specified in Section~\ref{bindingActualsToFormals},
considering the function to have static type $F$,
and the static type of $i$ is as specified there.

\commentary{%
  Note that member lookups ignore abstract declarations,
  which means that there will be a compile-time error
  if the targeted member $m$ is abstract,
  as well as when it does not exist at all.%
}

\LMHash{}%
An
\IndexCustom{implicit \CALL{} superinvocation}{%
  method superinvocation!implicit \CALL}
has the form

\noindent
\code{\SUPER<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)},

\noindent
and it is treated as

\noindent
\code{\SUPER.\CALL<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}.

\commentary{The type argument list is again omitted when $r = 0$.}

\LMHash{}%
\BlindDefineSymbol{o, C, \SuperClass}%
Evaluation of $i$ proceeds as follows:
Let $o$ be the current binding of \THIS,
let $C$ be the enclosing class for $i$,
and let \SuperClass{} be the superclass (\ref{superclasses}) of $C$.
Let \DefineSymbol{L} be the library that contains $C$.
\BlindDefineSymbol{D, f}%
Let the declaration $D$ be the result of looking up
the method $m$ with respect to $L$ in $o$ starting with \SuperClass{}
(\ref{lookup}).
If the lookup succeeded,
let $f$ denote the function associated with $D$.
%
Otherwise
\commentary{(when method lookup failed)},
let the declaration $D$ be the result of looking up
the getter $m$ with respect to $L$ in $o$ starting with \SuperClass{}
(\ref{lookup}).
If the getter lookup succeeded,
invoke said getter with \THIS{} bound to $o$,
and let $f$ denote the returned object.

\commentary{%
  It cannot occur that both lookups fail,
  because the corresponding lookups would then have failed at compile-time,
  in which case the program has a compile-time error.%
}

\LMHash{}%
Otherwise perform the binding of actual arguments to formal parameters for
\code{$f$<$A_1, \ldots,\ A_r$>($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
as specified in Section~\ref{bindingActualsToFormals},
and execute the body of $f$ with said bindings
plus a binding of \THIS{} to $o$.
The result returned by $f$ is then the result of evaluating $i$.

} % End of scope for superclass name.


\subsubsection{Sending Messages}
\LMLabel{sendingMessages}

\LMHash{}%
Messages are the sole means of communication among isolates.
Messages are sent by invoking specific methods in the Dart libraries; there is no specific syntax for sending a message.

\commentary{%
  In other words, the methods supporting sending messages
  embody primitives of Dart that are not accessible to ordinary code,
  much like the methods that spawn isolates.%
}


\subsection{Property Extraction}
\LMLabel{propertyExtraction}

\LMHash{}%
\IndexCustom{Property extraction}{property extraction}
allows for a member to be accessed as a property rather than a function.
A property extraction can be either:

\begin{enumerate}
\item An instance method closurization,
  which converts a method into a function object
  (\ref{instanceMethodClosurization}).
  Or
\item A getter invocation, which returns
  the result of invoking of a getter method
  (\ref{getterAccessAndMethodExtraction}).
\end{enumerate}

\commentary{%
  Function objects derived from members via closurization
  are colloquially known as tear-offs.%
}

\LMHash{}%
Property extraction comes in several forms, as described below.

\LMHash{}%
\Case{Conditional}
Consider a \IndexCustom{conditional property extraction expression}{%
  property extraction!conditional}
$i$ of the form \code{$e$?.\id}.

\LMHash{}%
If $e$ is a type literal, $i$ is treated as \code{$e$.\id}.

\LMHash{}%
Otherwise, the static type of $i$ is the same as
the static type of \code{$e$.\id}.
Let $T$ be the static type of $e$,
and let $y$ be a fresh variable of type $T$.
Except for errors inside $e$ and references to the name $y$,
exactly the same compile-time errors that would be caused by \code{$y$.\id}
are also generated in the case of \code{$e$?.\id}.

\LMHash{}%
Evaluation of a conditional property extraction expression $i$
of the form \code{$e$?.\id} proceeds as follows:

\LMHash{}%
If $e$ is a type literal or $e$ denotes an extension,
evaluation of $i$ amounts to evaluation of \code{$e$.\id}.

\LMHash{}%
Otherwise evaluate $e$ to an object $o$.
If $o$ is the null object, $i$ evaluates to the null object (\ref{null}).
Otherwise let $x$ be a fresh variable bound to $o$
and evaluate \code{$x$.\id} to an object $r$.
Then $i$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{Static}
Let \id{} be an identifier;
a \IndexCustom{static property extraction}{%
  property extraction!static}
$i$ is an expression of the form \code{$C$.\id},
where $C$ is a type literal or $C$ denotes an extension.

\LMHash{}%
A compile-time error occurs
unless $C$ denotes a class, a mixin, or an extension that declares
a static member named $m$,
which we will call the
\IndexCustom{denoted member}{static property extraction!denoted member}
of $i$.
If the denoted member is a static getter,
the static type of $i$ is the return type of said getter;
if the denoted member is a static method,
the static type of $i$ is the function type of said method;
if the denoted member is neither, a compile-time error occurs.

\LMHash{}%
Evaluation of a static property extraction $i$ of the form \code{$C$.\id}
proceeds as follows:
If the denoted member of $i$ is a static getter,
said getter is invoked, yielding an object $o$,
and $i$ then evaluates to $o$.
If the denoted member of $i$ is a static method,
$i$ evaluates to a function object by function closurization
(\ref{functionClosurization})
applied to said static method.
\EndCase

\LMHash{}%
\Case{Unconditional}
Let \id{} be an identifier;
an \IndexCustom{unconditional property extraction}{%
  property extraction!unconditional}
is an expression of the form \code{$e$.\id}
where $e$ is an expression that is not a type literal,
and does not denote an extension
(\ref{getterAccessAndMethodExtraction});
or it is an expression of the form \code{\SUPER.\id}
(\ref{superGetterAccessAndMethodClosurization}).
\EndCase

\LMHash{}%
\Case{Implicit}
Let $e$ be an expression whose static type is
an interface type that has a method named \CALL.
In the case where the context type for $e$ is a function type
or the type \FUNCTION,
$e$ is treated as \code{$e$.\CALL}.

\commentary{%
  This means that a ``callable object'' may be treated as a function
  that supports a mechanism similar to function closurization
  (\ref{functionClosurization})
  by desugaring it to a method closurization on \CALL.
  This only occurs when it is statically known that it is a callable object,
  and when the context type requires a function.%
}
\EndCase


\subsubsection{Getter Access and Method Extraction}
\LMLabel{getterAccessAndMethodExtraction}

\LMHash{}%
Consider an unconditional property extraction $i$
(\ref{propertyExtraction})
of the form \code{$e$.\id}.
It is a compile-time error if \id{} is the name of
an instance member of the built-in class \code{Object}
and $e$ is a type literal.

\commentary{%
  This means that we cannot use \code{int.toString}
  to obtain a function object for the \code{toString} method of the
  \code{Type} object for \code{int}.
  But we can use \code{(int).toString}:
  $e$ is then not a type literal, but a parenthesized expression.%
}

\rationale{%
  This is a pragmatic trade-off.
  The ability to tear off instance methods on instances of \code{Type}
  was considered less useful,
  and it was considered more useful to insist on the simple rule that
  a method tear-off on a type literal is \emph{always} a tear-off
  of a static method on the denoted class.%
}

\LMHash{}%
Let $T$ be the static type of $e$.

\LMHash{}%
If $T$ is \DYNAMIC{} bounded
(\ref{bindingActualsToFormals})
and $m$ is one of
\code{hashCode}, \code{noSuchMethod}, \code{runtimeType}, or \code{toString}
then we say that $i$ is a
\IndexCustom{dynamic \code{Object} property extraction}{
  dynamic Object property extraction},
whose static analysis is specified separately below.

\LMHash{}%
Otherwise, it is a compile-time error if $T$ does not have
a method or getter named \id{}
unless $T$ is \DYNAMIC{} bounded,
or $T$ is \FUNCTION{} bounded
(\ref{bindingActualsToFormals})
and \id{} is \CALL.
The static type of $i$ is:

\begin{itemize}
\item The return type as specified in Section~\ref{typeDynamic}
  if $i$ is a dynamic \code{Object} property extraction
  and \id{} is \code{hashCode} or \code{runtimeType}.
\item The static type as specified in Section~\ref{typeDynamic}
  if $i$ is a dynamic \code{Object} property extraction
  and \id{} is \code{noSuchMethod} or \code{toString}.
\item The declared return type of \code{$T$.\id},
  if $T$ has an accessible instance getter named \id.
\item The function type of the method signature \code{$T$.\id},
  if $T$ has an accessible instance method named \id.
\item \FUNCTION{} if $T$ is \FUNCTION{} bounded and \id{} is \CALL.
\item The type \DYNAMIC{} otherwise.
  \commentary{This only occurs when $T$ is \DYNAMIC{} bounded.}
\end{itemize}

\commentary{%
  Note that the type of a method tear-off ignores
  whether any given parameter is covariant.
  However, the dynamic type of a function object
  thus obtained does take parameter covariance into account.%
}

\LMHash{}%
Evaluation of a property extraction $i$ of the form \code{$e$.\id}
proceeds as follows:

\LMHash{}%
First, the expression $e$ is evaluated to an object $o$.
Let $f$ be the result of looking up (\ref{lookup}) method
(\ref{instanceMethods})
\id{} in $o$ with respect to the current library $L$.
If method lookup succeeds then $i$ evaluates to
the closurization of method $f$ on object $o$
(\ref{instanceMethodClosurization}).

\commentary{%
  Note that $f$ is never an abstract method,
  because method lookup skips abstract methods.
  If the method lookup failed, e.g.,
  because there is an abstract declaration of \id, but no concrete declaration,
  we will continue to the next step.
  However, since methods and getters never override each other,
  getter lookup will necessarily fail as well,
  and \code{noSuchMethod()} will ultimately be invoked.
  The regrettable implication is that the error will refer to a missing getter
  rather than an attempt to closurize an abstract method.%
}

\LMHash{}%
Otherwise, $i$ is a getter invocation.
Let $f$ be the result of looking up (\ref{lookup}) getter
(\ref{getters})
\id{} in $o$ with respect to $L$.
Otherwise, the body of $f$ is executed with \THIS{} bound to $o$.
The value of $i$ is the result returned by the call to the getter function.

\LMHash{}%
If the getter lookup has failed,
then a new instance $im$ of the predefined class \code{Invocation} is created,
such that:

\begin{itemize}
\item \code{$im$.isGetter} evaluates to \TRUE.
\item \code{$im$.memberName} evaluates to the symbol \code{m}.
\item \code{$im$.positionalArguments} evaluates to an object
  whose dynamic type implements \code{List<Object>},
  and which is empty and unmodifiable.
\item \code{$im$.namedArguments} evaluates to an object
  whose dynamic type implements \code{Map<Symbol, Object>},
  and which is empty and unmodifiable.
\item \code{$im$.typeArguments} evaluates to an object
  whose dynamic type implements \code{List<Type>},
  and which is empty and unmodifiable.
\end{itemize}

\LMHash{}%
Then the method \code{noSuchMethod()} is looked up
in $o$ and invoked with argument $im$,
and the result of this invocation is the result of evaluating $i$.

\commentary{%
  The situation where \code{noSuchMethod} is invoked can only arise
  when the static type of $e$ is \DYNAMIC.%
}


\subsubsection{Super Getter Access and Method Closurization}
\LMLabel{superGetterAccessAndMethodClosurization}

\LMHash{}%
Consider a property extraction $i$ of the form \code{\SUPER.\id}.

\LMHash{}%
Let $S$ be the superclass of the immediately enclosing class.
It is a compile-time error if $S$ does not have
an accessible instance method or getter named \id.
The static type of $i$ is:

\begin{itemize}
\item The declared return type of \code{$S$.\id},
  if $S$ has an accessible instance getter named \id.
\item The function type of the method signature \code{$S$.\id},
  if $S$ has an accessible instance method named \id.
\item The type \DYNAMIC{} otherwise.
  \commentary{This only occurs when $T$ is \DYNAMIC{} or \FUNCTION.}
\end{itemize}

\commentary{%
  Note that the type of a method tear-off ignores
  whether any given parameter is covariant.
  However, the dynamic type of a function object
  thus obtained does take parameter covariance into account.%
}

\LMHash{}%
Evaluation of a property extraction $i$ of the form $\SUPER.m$
proceeds as follows:

\LMHash{}%
Let $g$ be the method implementation currently executing,
and let $C$ be the class in which $g$ is declared.
Let $S$ be the superclass of $C$.
Let $f$ be the result of looking up method \id{} in $S$
with respect to the current library $L$.
If method lookup succeeds then $i$ evaluates to
the closurization of method $f$
with respect to superclass $S$
(\ref{superClosurization}).

\LMHash{}%
Otherwise, $i$ is a getter invocation.
Let $f$ be the result of looking up
getter \id{} in $S$ with respect to $L$.
The body of $f$ is executed with \THIS{} bound to the current value of \THIS.
The value of $i$ is the result returned by the call to the getter function.

\commentary{%
  The getter lookup will not fail, because it is a compile-time error to have
  a super property extraction of a member \id{} when the superclass $S$
  does not have a concrete member named \id.%
}


\subsubsection{Instance Method Closurization}
\LMLabel{instanceMethodClosurization}

\LMHash{}%
This section specifies the dynamic semantics of instance method closurizations.

\commentary{%
  Note that the non-generic case is covered implicitly using $s = 0$,
  in which case the type parameter declaration lists
  and the actual type argument lists passed in invocations
  are omitted (\ref{generics}).%
}

\LMHash{}%
An \Index{instance method closurization}
is a closurization of some method on some object, defined below,
or a super closurization (\ref{superClosurization}).

\LMHash{}%
Let $o$ be an object, and let $u$ be a fresh final variable bound to $o$.
The \Index{closurization of method} $f$ on object $o$
is defined to be equivalent
\commentary{(except for equality, as noted below)}
to:

\begin{itemize}
%\item $(a) \{\RETURN{}$ $u$ $op$ $a;$\} if $f$ is named $op$
%  and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \gtilde/, *, \%, $|$,
%  \^{}, \&, $<<$, $>>$} (this precludes closurization of unary -).
%\item $() \{\RETURN{}$ \gtilde{} $u;$\} if $f$ is named \gtilde.
%\item $(a) \{\RETURN{}$ $u[a];$\} if $f$ is named \code{[]}.
%\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named \code{[]=}.
\item
\begin{normativeDartCode}
<\TypeParameters{X}{B'}{s}>
($\PairList{T}{p}{1}{n},\ $\{$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$\}) =>
\quad$u$.$m$<\List{X}{1}{s}>($\List{p}{1}{n},\ p_{n+1}$: $p_{n+1}, \ldots,\ p_{n+k}$: $p_{n+k}$);
\end{normativeDartCode}
where $f$ is an instance method named $m$
which has type parameter declarations
\TypeParametersStd,
required parameters \List{p}{1}{n},
and named parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k},
using \code{null} for parameters whose default value is not specified.
\item
\begin{normativeDartCode}
<\TypeParameters{X}{B'}{s}>
($\PairList{T}{p}{1}{n},\ $[$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$]) =>
\quad$u$.$m$<\List{X}{1}{s}>(\List{p}{1}{n+k});
\end{normativeDartCode}
where $f$ is an instance method named $m$
which has type parameter declarations
\TypeParametersStd,
required parameters \List{p}{1}{n},
and optional positional parameters
\List{p}{n+1}{n+k} with defaults \List{d}{1}{k},
using \code{null} for parameters whose default value is not specified.
\end{itemize}

\LMHash{}%
$B'_j, j \in 1 .. s$, are determined as follows:
If $o$ is an instance of a non-generic class, $B'_j = B_j, j \in 1 .. s$.
Otherwise, let $X'_1, \ldots, X'_{s'}$ be
the formal type parameters of the class of $o$,
and $t'_1, \ldots, t'_{s'}$ be the actual type arguments.
Then $B'_j = [t'_1/X'_1, \ldots, t'_{s'}/X'_{s'}]B_j, j \in 1 .. s$.

\commentary{%
  That is, we replace the formal type parameters of the enclosing class,
  if any,
  by the corresponding actual type arguments.%
}

\LMHash{}%
The parameter types $T_j, j \in 1 .. n+k$, are determined as follows:
Let the method declaration $D$ be the implementation of $m$
which is invoked by the expression in the body.
Let $T$ be the class that contains $D$.

\commentary{%
  Note that $T$ is the dynamic type of $o$, or a superclass thereof.%
}

\LMHash{}%
For each parameter $p_j$, $j \in 1 .. n+k$, if $p_j$ is covariant
(\ref{covariantParameters})
then $T_j$ is the built-in class \code{Object}.

\commentary{%
  This is concerned with the dynamic type of the function object obtained by
  the member closurization.
  The static type of the expression that gives rise to the member closurization
  is specified elsewhere
  (\ref{propertyExtraction},
  \ref{getterAccessAndMethodExtraction}).
  Note that for the static type it is ignored whether a parameter is covariant.%
}

\LMHash{}%
If $T$ is a non-generic class then for $j \in 1 .. n+k$,
%% TODO(eernst): Refer to nnbd notion of 'same type'.
$T_j$ is a type annotation that denotes the same type as that
which is denoted by the type annotation on
the corresponding parameter declaration in $D$.
If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC.

\LMHash{}%
Otherwise $T$ is a generic instantiation of a generic class $G$.
Let $X''_1, \ldots, X''_{s''}$ be the formal type parameters of $G$,
and $t''_1, \ldots, t''_{s''}$ be the actual type arguments of $o$ at $T$.
Then $T_j$ is a type annotation that denotes
$[t''_1/X''_1, \ldots, t''_{s''}/X''_{s''}]S_j$,
where $S_j$ is the type annotation of the corresponding parameter in $D$.
If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC.

\LMHash{}%
There is one way in which
the function object yielded by the instance method closurization differs from
the function object obtained by function closurization on
the above mentioned function literal:
Assume that $o_1$ and $o_2$ are objects, $m$ is an identifier,
and $c_1$ and $c_2$ are function objects
obtained by closurization of $m$ on $o_1$ respectively $o_2$.
Then \code{$c_1$ == $c_2$} evaluates to true
if and only if $o_1$ and $o_2$ is the same object.

\commentary{%
  % Spell out the consequences for `==` and for `identical`, for the receivers
  % and for the closurizations.
  In particular, two closurizations of a method $m$
  from the same object are equal,
  and two closurizations of a method $m$
  from non-identical objects are not equal.
  Assuming that $v_i$ is a fresh variable bound to an object, $i \in 1 .. 2$,
  it also follows that \code{identical($v_1.m, v_2.m$)} must be false
  when $v_1$ and $v_2$ are not bound to the same object.
  However, Dart implementations are not required
  to canonicalize function objects,
  which means that \code{identical($v_1.m, v_2.m$)}
  is not guaranteed to be true,
  even when it is known that $v_1$ and $v_2$ are bound to the same object.%
}

\rationale{%
  The special treatment of equality in this case facilitates
  the use of extracted property functions in APIs where callbacks
  such as event listeners must often be registered and later unregistered.
  A common example is the DOM API in web browsers.%
}


\subsubsection{Super Closurization}
\LMLabel{superClosurization}

\LMHash{}%
This section specifies the dynamic semantics of
super closurizations.

\commentary{%
  Note that the non-generic case is covered implicitly using $s = 0$,
  in which case the type parameter declarations are omitted (\ref{generics}).%
}

\LMHash{}%
Consider expressions in the body of a class $T$ which is
a subclass of a given class $S$,
where a method declaration that implements $f$ exists in $S$,
and there is no class $U$ which is
a subclass of $S$ and a superclass of $T$ which implements $f$.

\commentary{%
  In short, consider a situation where
  a superinvocation of $f$ will execute $f$ as declared in $S$.%
}

\LMHash{}%
A \Index{super closurization}
is a closurization of a method with respect to a class, as defined next.
The \Index{closurization of a method} $f$ with respect to the class $S$
is defined to be equivalent
\commentary{(except for equality, as noted below)}
to:

\begin{itemize}
%\item $(a) \{\RETURN{}$ \SUPER{} $op$ $a;$\} if $f$ is named $op$
%   and $op$ is one of \code{<, >, <=, >=, ==, -, +, /, \gtilde/, *, \%, $|$,
%   \^{}, \&, $<<$, $>>$}.
%\item $() \{\RETURN{}$ \gtilde\SUPER;\} if $f$ is named \gtilde.
%\item $(a) \{\RETURN{}$ $\SUPER[a];$\} if $f$ is named \code{[]}.
%\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named \code{[]=}.
\item
\begin{normativeDartCode}
<\TypeParameters{X}{B'}{s}>
($\PairList{T}{p}{1}{n},\ $\{$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$\}) =>
\quad\SUPER$.m$<\List{X}{1}{s}>($\List{p}{1}{n},\ p_{n+1}$: $p_{n+1}, \ldots,\ p_{n+k}$: $p_{n+k}$);
\end{normativeDartCode}
where $f$ is an instance method named $m$
which has type parameter declarations
\TypeParametersStd,
required parameters \List{p}{1}{n},
and named parameters \List{p}{n+1}{n+k} with defaults \List{d}{1}{k}.
\item
\begin{normativeDartCode}
<\TypeParameters{X}{B'}{s}>
($\PairList{T}{p}{1}{n},\ $[$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$]) =>
\quad\SUPER.$m$<\List{X}{1}{s}>(\List{p}{1}{n+k});
\end{normativeDartCode}
where $f$ is an instance method named $m$
which has type parameter declarations
\TypeParametersStd,
required parameters \List{p}{1}{n},
and optional positional parameters
\List{p}{n+1}{n+k} with defaults \List{d}{1}{k}.
\end{itemize}

\commentary{%
  Note that a super closurization is an instance method closurization,
  as defined in (\ref{instanceMethodClosurization}).%
}

\LMHash{}%
$B'_j, j \in 1 .. s$, are determined as follows:
If $S$ is a non-generic class then $B'_j = B_j, j \in 1 .. s$.
Otherwise, let $X'_1, \ldots, X'_{s'}$ be the formal type parameters of $S$,
and $t'_1, \ldots, t'_{s'}$ be the actual type arguments of \THIS{} at $S$.
Then $B'_j = [t'_1/X'_1, \ldots, t'_{s'}/X'_{s'}]B_j, j \in 1 .. s$.

\commentary{%
  That is, we replace the formal type parameters of the enclosing class, if any,
  by the corresponding actual type arguments.
  We need to consider the type arguments with respect to a specific class
  because it is possible for a class to pass different type arguments
  to its superclass
  than the ones it receives itself.%
}

\LMHash{}%
The parameter types $T_j, j \in 1 .. n+k$, are determined as follows:
Let the method declaration $D$ be the implementation of $m$ in $S$.

\LMHash{}%
For each parameter $p_j$, $j \in 1 .. n+k$, if $p_j$ is covariant
(\ref{covariantParameters})
then $T_j$ is the built-in class \code{Object}.

\commentary{%
  This is concerned with the dynamic type of the function object obtained by
  the super closurization.
  The static type of the expression that gives rise to the super closurization
  is specified elsewhere
  (\ref{propertyExtraction},
  \ref{superGetterAccessAndMethodClosurization}).
  Note that for the static type it is ignored whether a parameter is covariant.%
}

\LMHash{}%
If $S$ is a non-generic class then for $j \in 1 .. n+k$,
%% TODO(eernst): Refer to nnbd notion of 'same type'.
$T_j$ is a type annotation that denotes the same type as that
which is denoted by the type annotation on
the corresponding parameter declaration in $D$.
If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC.

\LMHash{}%
Otherwise $S$ is a generic instantiation of a generic class $G$.
Let $X''_1, \ldots, X''_{s''}$ be the formal type parameters of $G$,
and $t''_1, \ldots, t''_{s''}$ be the actual type arguments of $o$ at $S$.
Then $T_j$ is a type annotation that denotes
$[t''_1/X''_1, \ldots, t''_{s''}/X''_{s''}]S_j$,
where $S_j$ is the type annotation of the corresponding parameter in $D$.
If that parameter declaration has no type annotation then $T_j$ is \DYNAMIC.

\LMHash{}%
There is one way in which
the function object yielded by the super closurization differs from
the function object obtained by function closurization on
the above mentioned function literal:
Assume that an occurrence of the expression \SUPER.$m$ in a given class
is evaluated on two occasions where \THIS{}
is bound to $o_1$ respectively $o_2$,
and the resulting function objects are $c_1$ respectively $c_2$:
\code{$c_1$ == $c_2$} is then true
if and only if $o_1$ and $o_2$ is the same object.


\subsubsection{Generic Method Instantiation}
\LMLabel{genericMethodInstantiation}

%% TODO(eernst): Like generic function instantiation, generic method
%% instantiation relies on type inference. See the comment in
%% \ref{genericFunctionInstantiation} for further details.

\LMHash{}%
Generic method instantiation is a mechanism that yields
a non-generic function object,
based on a property extraction which denotes an instance method closurization
(\ref{instanceMethodClosurization}, \ref{superClosurization}).

\commentary{%
  It is a mechanism which is very similar to instance method closurization,
  but it only occurs in situations where
  a compile-time error would otherwise occur.%
}

\rationale{%
  The essence of generic method instantiation
  is to allow for ``curried'' invocations,
  in the sense that a generic instance method can receive its actual
  type arguments separately during closurization
  (it must then receive \emph{all} type arguments, not just some of them),
  and that yields a non-generic function object.
  The type arguments are passed implicitly, based on type inference;
  a future version of Dart may allow for passing them explicitly.%
}
\commentary{Here is an example:}

\begin{dartCode}
\CLASS{} A \{
  X fi<X \EXTENDS{} num>(X x) => x;
\}
\\
\CLASS{} B \EXTENDS{} /*\,or\,\,\IMPLEMENTS\,*/ A \{
  X fi<X \EXTENDS{} num>(X x, [List<X> xs]) => x;
\}
\\
\VOID{} main() \{
  A a = B();
  int \FUNCTION{}(int) f = a.fi;
\}
\end{dartCode}

\noindent
\commentary{%
  The function object which is stored in \code{f} at the end of \code{main}
  has dynamic type \code{int\,\,\FUNCTION(int,\,[List<int>])},
  and it is obtained by implicitly
  ``passing the actual type argument \code{int}''
  to the denoted generic instance method,
  thus obtaining a non-generic function object of the specified type.
  %
  Note that this function object accepts an optional positional argument,
  even though this is not part of
  the statically known type of the corresponding instance method,
  nor of the context type.%
}

\rationale{%
  In other words, generic method instantiation yields a function
  whose signature matches the context type as far as possible,
  but with respect to its parameter list shape
  (that is, the number of positional parameters and their optionality,
  or the set of names of named parameters),
  it will be determined by the method signature of the actual instance method
  of the given receiver.
  Of course, the difference can only be such that the actual type is
  % This is about the dynamic type, so there is no exception for \COVARIANT.
  a subtype of the given context type,
  otherwise the declaration of that instance method
  would have been a compile-time error.%
}

\LMHash{}%
Let $i$ be a property extraction expression of the form
\code{$e$?.\id}, \code{$e$.\id}, or \code{\SUPER.\id}
(\ref{propertyExtraction}, \ref{superGetterAccessAndMethodClosurization}),
which is statically resolved to denote an instance method named \id,
and let $G$ be the static type of $i$.
Consider the situation where $G$ is a function type of the form
\RawFunctionType{T_0}{X}{B}{s}{\metavar{parameters}}
with $s > 0$
\commentary{(that is, $G$ is a generic function type)},
and the context type is a non-generic function type $F$.
In this situation a compile-time error occurs
(\ref{variables},
\ref{functions},
\ref{generativeConstructors},
\ref{redirectingGenerativeConstructors},
\ref{initializerLists},
\ref{new},
\ref{const},
\ref{bindingActualsToFormals},
\ref{assignment},
\ref{localVariableDeclaration},
\ref{switch},
\ref{return},
\ref{yieldEach}),
except when generic function type instantiation
(\ref{genericFunctionInstantiation})
succeeds, that is:

\LMHash{}%
Type inference is applied to $G$ with context type $F$,
and it succeeds, yielding the actual type argument list
\List{T}{1}{s}.

{ % Scope for \gmiName.

\def\gmiName{\metavar{gmiName\ensuremath{_{\id}}}}

% For any given method name \id, \gmiName is the "associated" name which
% is used for the implicitly induced method that we use to get the function
% object which is the result of a generic method instantiation. Let's call
% that associated method the "generic instantiation method".
%
% The basic idea is that we consider all libraries included in the
% compilation of a complete Dart program, and then we select a suffix,
% say `_*`, which is globally unique (because no user-written identifier
% can have that suffix, and the compiler doesn't use anything similar
% for other purposes).
%
% When we have found such a "globally fresh suffix", it is easy to see
% that we can use it to specify the implicitly induced methods in a way
% that will do the right thing:
%
% Assume that a class `C` has a generic method `foo`, and it is subject
% to generic method instantiation.
%
% We then generate a generic instantiation method for `foo` in in `C`, with the
% name `foo_*`. If there is a subclass `D` of `C` which has an overriding
% declaration of `foo` then we also generate a `foo_*` generic instantiation
% method in `D`, and that one might return a closure with a different parameter
% list shape, because that's the way `foo` is declared in `D`.
%
% We can then call `e.foo_*<...>()` where `e` has static type `C`,
% at a location where the original source code had `e.foo` and the context
% type was non-generic (so generic method instantiation kicked in).
% This may invoke `foo_*` in `C`, or `D`, or some other class, whatever is the
% dynamic type of the result of evaluating `e`.
%
% Altogether, this ensures that we obtain a function object whose parameter
% list shape corresponds precisely to the parameter list shape of `foo` in
% the dynamic type of the receiver, as it should. There will not be any
% name clashes with user-written declarations, and overriding declarations
% will actually override as they should, because they all use that same
% "globally fresh suffix".
%
% The text below tries to communicate how this could work without being too
% much like a particular implementation.

\LMHash{}%
Consider the situation where generic function type instantiation succeeded.
Let \gmiName{} be a fresh name which is associated with \id,
which is private if and only if \id{} is private.
\commentary{%
  An implementation could use, say, \code{foo_*} when \id{} is \code{foo},
  which is known to be fresh because
  user-written identifiers cannot contain `\code{*}'.%
}
The program is then modified as follows:

\begin{itemize}
\item When $i$ is \code{$e$?.\id}:
  Replace $i$ by \code{$e$?.\gmiName<\List{T}{1}{s}>()}.
\item When $i$ is \code{$e$.\id}:
  Replace $i$ by \code{$e$.\gmiName<\List{T}{1}{s}>()}.
\item When $i$ is \code{\SUPER.\id}:
  Replace $i$ by \code{\SUPER.\gmiName<\List{T}{1}{s}>()}.
\end{itemize}

\LMHash{}%
The inserted expressions have no compile-time error and can be executed,
because the corresponding generic method is induced implicitly.
We use the phrase
\Index{generic instantiation method}
to denote these implicitly induced methods,
and designate the method that induced it as its
\IndexCustom{target}{generic instantiation method!target}.

\LMHash{}%
Assume that a class $C$ declares a generic instance method named \id,
with a method signature corresponding to a generic function type $G$,
formal type parameters \TypeParametersStd,
and formal parameter declarations \metavar{parameters}.
Let \metavar{arguments} denote the corresponding actual argument list,
passing these parameters.

\commentary{%
  For instance, \metavar{parameters} could be

  \noindent
  \code{$\PairList{T}{p}{1}{n},\ $\{$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$\}}

  \noindent
  in which case \metavar{arguments} would be
  \code{\List{p}{1}{n},\ $p_{n+1}$:\ $p_{n+1}$,\ $p_{n+k}$:\ $p_{n+k}$}.%
}

\LMHash{}%
Let $G'$ be the same function type as $G$,
except that it omits the formal type parameter declarations.
\commentary{%
  For instance, if $G$ is
  \FunctionTypeSimpleGeneric{\VOID}{$X$, $Y$ \EXTENDS\ num}{X x, List<Y> ys}
  then $G'$ is
  \FunctionTypeSimple{\VOID}{X x, List<Y> ys}.
  Note that $G'$ will typically contain free type variables.%
}

\LMHash{}%
An instance method with the name \gmiName{} is then implicitly induced,
with the same behavior as the following declaration
(except for equality of the returned function object,
which is specified below):

% Use `\THIS.\id..` because there could be a parameter named \id.
\begin{normativeDartCode}
$G'$ \gmiName<\TypeParametersStd{}>() \{
\ \ \RETURN{} (\metavar{parameters}) => \THIS.\id<\List{X}{1}{s}>(\metavar{arguments});
\}
\end{normativeDartCode}

\LMHash{}%
Let $o$ be an instance of a class which contains
an implicitly induced declaration of \gmiName{}
as described above.
%
Consider the situation where the program evaluates
two invocations of this method with the same receiver $o$,
and with actual type arguments whose actual values are
%% TODO(eernst): Refer to nnbd notion of 'same type'.
the same types \List{t}{1}{s} for both invocations,
and assume that the invocations returned
the instances $o_1$ respectively $o_2$.
%
It is then guaranteed that $o_1$ and $o_2$ are equal
according to operator \lit{==}.
It is unspecified whether
\code{identical($o_1$, $o_2$)}
evaluates to \TRUE{} or \FALSE.

} % End of scope for \gmiName.

\rationale{%
  No notion of equality is appropriate with different receivers,
  nor when different type arguments are provided,
  because execution of two function objects that differ in these ways
  can have different side-effects and return different results
  when executed starting from exactly the same state.%
}


\subsection{Assignment}
\LMLabel{assignment}

\LMHash{}%
An assignment changes the value associated with a variable,
or invokes a setter.

\begin{grammar}
<assignmentOperator> ::= `='
  \alt <compoundAssignmentOperator>

<compoundAssignmentOperator> ::= `*='
  \alt `/='
  \alt `~/='
  \alt `\%='
  \alt `+='
  \alt `-='
  \alt `\ltlt='
  \alt `\gtgtgt='
  \alt `\gtgt='
  \alt `\&='
  \alt `^='
  \alt `|='
  \alt `??='
\end{grammar}

\LMHash{}%
\Case{\code{\id{} = $e$}}
Consider an assignment $a$ of the form \code{\id{} = $e$},
where \id{} is an identifier.
Perform a lexical lookup of \code{\id=} from the location of \id.

\begin{itemize}
\item
  When the lexical lookup yields a declaration $D$ of a local variable $v$
  \commentary{(which may be a formal parameter)},
  a compile-time error occurs if $v$ is final
  or if the static type of $e$ is not assignable to the declared type of $v$.
\item
  When the lexical lookup yields a declaration $D$
  which is not a local variable,
  it is guaranteed to be a setter
  \commentary{(that may be explicit or induced implicitly by a variable)}
  because other declarations do not have a name
  of the form \code{\id=}.

  If $D$ is the declaration of a static setter in class or mixin $C$
  then $a$ is treated as
  (\ref{notation})
  the assignment \code{$C$.\id{} = $e$}.

  \commentary{%
    Further analysis as well as evaluation of \code{$C$.\id{} = $e$}
    proceeds as specified elsewhere.%
  }

  Otherwise, a compile-time error occurs,
  unless the static type of $e$ is assignable to the parameter type of $D$.
\item
  When the lexical lookup yields nothing,
  $a$ is treated as
  (\ref{notation})
  \code{\THIS.\id{} = $e$}.

  \commentary{%
    In this case it is known that $a$ has access to \THIS{}
    (\ref{classes}),
    and the interface of the enclosing class has a member named \code{\id=},
    or there is an applicable extension with a member named \code{\id=}.
    Both the static analysis and evaluation proceeds with
    \code{\THIS.\id{} = $e$},
    so there is no need to further specify the treatment of $a$.%
  }
\item
  \commentary{%
    The lexical lookup can never yield an import prefix,
    because they never have a name of the form \code{\id=}.%
  }
\end{itemize}

\LMHash{}%
In all cases
\commentary{(whether or not \id{} is a local variable, etc.)},
the static type of $a$ is the static type of $e$.

\LMHash{}%
Evaluation of an assignment $a$ of the form \code{\id{} = $e$}
proceeds as follows.
Perform a lexical lookup of \code{\id=} from the location of \id.

\begin{itemize}
\item
  In the case where the lexical lookup yields
  a declaration $D$ of a local variable $v$,
  \commentary{(which may be a formal parameter)},
  the expression $e$ is evaluated to an object $o$,
  and the variable $v$ is bound to $o$.
  Then $a$ evaluates to the object $o$
  (\ref{expressionEvaluation}).
\item
  In the case where the lexical lookup of \code{\id=}
  from the location of \id{}
  yields a declaration $D$,
  $D$ is necessarily a top level setter $s$
  \commentary{(possibly implicitly induced by a variable)}.

  The expression $e$ is evaluated to an object $o$.
  Then the setter $s$ is invoked
  with its formal parameter bound to $o$.
  Then $a$ evaluates to the object $o$.

  \commentary{%
    $D$ cannot be a static setter in a class $C$,
    because $a$ is then treated as
    \code{$C$.\id{} = $e$},
    which is specified elsewhere.%
  }
\item
  \commentary{%
    The case where the lexical lookup of \code{\id=}
    yields nothing cannot occur,
    because that case is treated as
    \code{\THIS.\id{} = $e$},
    whose evaluation is specified elsewhere.%
  }
\end{itemize}
\EndCase

\LMHash{}%
\Case{\code{$p$.\id{} = $e$}}
Consider an assignment $a$ of the form \code{$p$.\id{} = $e$},
where $p$ is an import prefix and \id{} is an identifier.

\LMHash{}%
A compile-time error occurs,
unless $p$ has a member which is a setter $s$ named \code{id=}
\commentary{(which may be implicitly induced by a variable declaration)}
such that the static type of $e$
is assignable to the parameter type of $s$.

\LMHash{}%
The static type of $a$ is the static type of $e$.

\LMHash{}%
Evaluation of an assignment $a$ of the form \code{$p$.\id{} = $e$}
proceeds as follows:
The expression $e$ is evaluated to an object $o$.
Then the setter denoted by \code{$p$.\id} is invoked
with its formal parameter bound to $o$.
Then $a$ evaluates to the object $o$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$?.$v$ = $e_2$}}
Consider an assignment $a$ of the form \code{$e_1$?.$v$ = $e_2$}.
Exactly the same compile-time errors that would be caused by
\code{$e_1$.$v$ = $e_2$} are also generated in the case of $a$.
The static type of $a$ is the static type of $e_2$.

\LMHash{}%
Evaluation of an assignment $a$ of the form \code{$e_1$?.$v$ = $e_2$}
proceeds as follows:
If $e_1$ is a type literal, $a$ is equivalent to \code{$e_1$.$v$ = $e_2$}.
Otherwise evaluate $e_1$ to an object $o$.
If $o$ is the null object, $a$ evaluates to the null object (\ref{null}).
Otherwise let $x$ be a fresh variable bound to $o$
and evaluate \code{$x$.$v$ = $e_2$} to an object $r$.
Then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$.$v$ = $e_2$}}
Consider an assignment $a$ of the form \code{$e_1$.$v$ = $e_2$}.
Let $T$ be the static type of $e_1$.
If $T$ is \DYNAMIC, no further checks are performed.
Otherwise, it is a compile-time error unless
$T$ has an accessible instance setter named \code{$v$=}.
It is a compile-time error unless the static type of $e_2$
may be assigned to the declared type of the formal parameter of said setter.
Whether or not $T$ is \DYNAMIC,
the static type of $a$ is the static type of $e_2$.

\LMHash{}%
Evaluation of an assignment of the form \code{$e_1$.$v$ = $e_2$}
proceeds as follows:
The expression $e_1$ is evaluated to an object $o_1$.
Then, the expression $e_2$ is evaluated to an object $o_2$.
Then, the setter \code{$v$=} is looked up (\ref{lookup})
in $o_1$ with respect to the current library.
% This error can occur due to implicit casts and dynamic calls.
It is a dynamic type error if the dynamic type of $o_2$
is not a subtype of the actual parameter type of said setter
(\ref{actualTypes}).
Otherwise, the body of the setter is executed with
its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$.

\LMHash{}%
If the setter lookup has failed, then a new instance $im$ of
the predefined class \code{Invocation} is created, such that:

\begin{itemize}
\item \code{$im$.isSetter} evaluates to \TRUE.
\item \code{$im$.memberName} evaluates to the symbol \code{v=}.
\item \code{$im$.positionalArguments} evaluates to an object
  whose dynamic type implements \code{List<Object>},
  which is unmodifiable, and which contains the same objects as
  $\code{<Object>}[o_2]$.
\item \code{$im$.namedArguments} evaluates to an object
  whose dynamic type implements \code{Map<Symbol, Object>},
  and which is empty and unmodifiable.
\item \code{$im$.typeArguments} evaluates to an object
  whose dynamic type implements \code{List<Type>},
  and which is empty and unmodifiable.
\end{itemize}

\LMHash{}%
Then the method \code{noSuchMethod()} is looked up in $o_1$
and invoked with argument $im$.

\commentary{%
  The situation where \code{noSuchMethod} is invoked can only arise
  when the static type of $e_1$ is \DYNAMIC.%
}

\LMHash{}%
The value of the assignment expression is $o_2$
irrespective of whether setter lookup has failed or succeeded.
\EndCase

\LMHash{}%
\Case{\code{\SUPER.$v$ = $e$}}
Consider an assignment $a$ of the form \code{\SUPER.$v$ = $e$}.
Let $S_{static}$ be the superclass of the immediately enclosing class.
It is a compile-time error if $S_{static}$ does not have
a concrete accessible instance setter named \code{$v$=}.
Otherwise, it is a compile-time error if the static type of $e$
may not be assigned to the static type of the formal parameter of said setter.
The static type of $a$ is the static type of $e$.

\LMHash{}%
Evaluation of an assignment of the form \code{\SUPER.$v$ = $e$}
proceeds as follows:
Let $g$ be the currently executing method, and let $C$ be
the class in which $g$ was looked up.
Let $S_{dynamic}$ be the superclass of $C$.
The expression $e$ is evaluated to an object $o$.
Then, the setter \code{$v$=} is looked up (\ref{lookup})
in $S_{dynamic}$ with respect to the current library.
The body of \code{$v$=} is executed with its formal parameter bound to $o$
and \THIS{} bound to the current value of \THIS.

\commentary{%
  The setter lookup will not fail, because it is a compile-time error
  when no concrete setter named \code{$v$=} exists in $S_{static}$.%
}

\LMHash{}%
The value of the assignment expression is $o$.

\LMHash{}%
% This error can occur due to implicit casts and mixin+covariance.
It is a dynamic type error if $o$ is not the null object (\ref{null})
and the dynamic type of $o$ is
not a subtype of the actual type of the formal parameter of \code{$v$=}
(\ref{actualTypes}) in $S_{static}$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$[$e_2$] = $e_3$}}
Consider an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}.
Let $T$ be the static type of $e_1$.
If $T$ is \DYNAMIC, no further checks are performed.
Otherwise, it is a compile-time error unless
$T$ has a method named \code{[]=}.
Let $S_2$ be the static type of the
first formal parameter of the method \code{[]=},
and $S_3$ the static type of the second.
It is a compile-time error unless the static type of $e_2$ respectively $e_3$
may be assigned to $S_2$ respectively $S_3$.
Whether or not $T$ is \DYNAMIC,
the static type of $a$ is the static type of $e_3$.

\LMHash{}%
Evaluation of an assignment $a$ of the form \code{$e_1$[$e_2$] = $e_3$}
proceeds as follows:
Evaluate $e_1$ to an object $o$,
then evaluate $e_2$ to an object $i$,
and finally evaluate $e_3$ to an object $v$.
Call the method \code{[]=} on $o$
with $i$ as first argument and $v$ as second argument.
Then $a$ evaluates to $v$.
% Should we add: It is a dynamic error if $e_1$ evaluates to
% a constant list or map?
\EndCase

\LMHash{}%
\Case{\code{\SUPER[$e_1$] = $e_2$}}
Consider an assignment $a$ of the form \code{\SUPER[$e_1$] = $e_2$}.
Let $S_{static}$ be the superclass of the immediately enclosing class.
It is a compile-time error if $S_{static}$ does not have a method \code{[]=}.
Otherwise, let $S_1$ be the static type of the
first formal parameter of the method \code{[]=},
and $S_2$ the static type of the second.
It is a compile-time error if the static type of $e_1$ respectively $e_2$
may not be assigned to $S_1$ respectively $S_2$.
The static type of $a$ is the static type of $e_2$.

\LMHash{}%
For evaluation, an assignment of the form \code{\SUPER[$e_1$] = $e_2$}
is equivalent to the expression \code{\SUPER.[$e_1$] = $e_2$}.
\EndCase


\subsubsection{Compound Assignment}
\LMLabel{compoundAssignment}

\LMHash{}%
\Case{\code{$v$ ??= $e$}}
Consider a compound assignment $a$ of the form \code{$v$ ??= $e$}
where $v$ is an identifier or an identifier qualified by an import prefix.
Exactly the same compile-time errors that would be caused by
\code{$v$ = $e$}
are also generated in the case of $a$.
The static type of $a$ is
the least upper bound of the static type of $v$ and the static type of $e$.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form \code{$v$ ??= $e$}
proceeds as follows:
Evaluate $v$ to an object $o$.
If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
Otherwise evaluate \code{$v$ = $e$} to an object $r$,
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$C$.$v$ ??= $e$}}
Consider a compound assignment $a$ of the form \code{$C$.$v$ ??= $e$}
where $C$ is a type literal
that may or may not be qualified by an import prefix.
Exactly the same compile-time errors that would be caused by
\code{$C$.$v$ = $e$}
are also generated in the case of $a$.
The static type of $a$ is the least upper bound of
the static type of \code{$C$.$v$} and the static type of $e$.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form \code{$C$.$v$ ??= $e$}
where $C$ is a type literal proceeds as follow:
Evaluate \code{$C$.$v$} to an object $o$.
If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
Otherwise evaluate \code{$C$.$v$ = $e$} to an object $r$,
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$.$v$ ??= $e_2$}}
Consider a compound assignment $a$ of the form \code{$e_1$.$v$ ??= $e_2$}.
Let $T$ be the static type of $e_1$ and let $x$ be a fresh variable of type $T$.
Except for errors inside $e_1$ and references to the name $x$,
exactly the same compile-time errors that would be caused by
\code{$x$.$v$ = $e_2$}
are also generated in the case of $a$.
Moreover, it is a compile-time error if $T$ does not have a getter named $v$.
The static type of $a$ is the least upper bound of
the static type of \code{$e_1$.$v$} and the static type of $e_2$.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ ??= $e_2$}
proceeds as follows:
Evaluate $e_1$ to an object $u$.
Let $x$ be a fresh variable bound to $u$.
Evaluate \code{$x$.$v$} to an object $o$.
If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
Otherwise evaluate \code{$x$.$v$ = $e_2$} to an object $r$,
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$[$e_2$] ??= $e_3$}}
Consider a compound assignment $a$ of the form \code{$e_1$[$e_2$] ??= $e_3$}.
Exactly the same compile-time errors that would be caused by
\code{$e_1$[$e_2$] = $e_3$}
are also generated in the case of $a$.
Moreover, it is a compile-time error
if the static type of $e_1$ does not have an `\code{operator []}'.
The static type of $a$ is the least upper bound of
the static type of \code{$e_1$[$e_2$]} and the static type of $e_3$.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form
\code{$e_1$[$e_2$] ??= $e_3$}
proceeds as follows:
Evaluate $e_1$ to an object $u$ and then evaluate $e_2$ to an object $i$.
Call the \code{[]} method on $u$ with argument $i$,
and let $o$ be the returned object.
If $o$ is not the null object (\ref{null}), $a$ evaluates to $o$.
Otherwise evaluate $e_3$ to an object $v$
and then call the \code{[]=} method on $u$
with $i$ as first argument and $v$ as second argument.
Then $a$ evaluates to $v$.
\EndCase

\LMHash{}%
\Case{\code{\SUPER.$v$ ??= $e$}}
Consider a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$}.
Exactly the same compile-time errors that would be caused by
\code{\SUPER.$v$ = $e$}
are also generated in the case of $a$.
Moreover, exactly the same compile-time errors that would be caused by
evaluation of the expression \code{\SUPER.$v$}
are also generated in the case of $a$.
The static type of $a$ is the least upper bound of
the static type of \code{\SUPER.$v$} and the static type of $e$.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form \code{\SUPER.$v$ ??= $e$}
proceeds as follows:
Evaluate \code{\SUPER.$v$} to an object $o$.
If $o$ is not the null object (\ref{null}) then $a$ evaluates to $o$.
Otherwise evaluate \code{\SUPER.$v$ = $e$} to an object $r$,
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$?.$v$ ??= $e_2$}}
Consider a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$}.
Exactly the same compile-time errors that would be caused by
\code{$e_1$.$v$ ??= $e_2$}
are also generated in the case of $a$.
% Note: We use the static type of \code{$e_1$?.$v$} rather than
% \code{$e_1$.$v$} even though the latter would be simpler. This is because
% the former will remain correct if NNBD is introduced, and because it reduces
% the amount of synthetic syntax.
The static type of $a$ is the least upper bound of
the static type of \code{$e_1$?.$v$} and the static type of $e_2$.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form \code{$e_1$?.$v$ ??= $e_2$}
proceeds as follows:
Evaluate $e_1$ to an object $u$.
If $u$ is the null object (\ref{null}) then $a$ evaluates to the null object.
Otherwise, let $x$ be a fresh variable bound to $u$.
Evaluate \code{$x$.$v$} to an object $o$.
If $o$ is not the null object (\ref{null}) then $a$ evaluates to $o$.
Otherwise evaluate \code{$x$.$v$ = $e_2$} to an object $r$,
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$C$?.$v$ ??= $e_2$}}
A compound assignment of the form \code{$C$?.$v$ ??= $e_2$}
where $C$ is a type literal
that may or may not be qualified by an import prefix
is equivalent to the expression \code{$C$.$v$ ??= $e$}.
\EndCase

\LMHash{}%
\Case{\code{$v$ $op$= $e$}}
For any other valid operator $op$,
a compound assignment of the form \code{$v$ $op$= $e$}
is equivalent to \code{$v$ = $v$ $op$ $e$},
where $v$ is an identifier or an identifier qualified by an import prefix.
\EndCase

\LMHash{}%
\Case{\code{$C$.$v$ $op$= $e$}}
A compound assignment of the form \code{$C$.$v$ $op$= $e$}
where $C$ is a type literal
that may or may not be qualified by an import prefix
is equivalent to \code{$C$.$v$ = $C$.$v$ $op$ $e$}.
\EndCase

\LMHash{}%
\Case{\code{$e_1$.$v$ $op$= $e_2$}}
Consider a compound assignment $a$ of the form \code{$e_1$.$v$ $op$= $e_2$}.
Let $x$ be a fresh variable whose static type is the static type of $e_1$.
Except for errors inside $e_1$ and references to the name $x$,
exactly the same compile-time errors that would be caused by
\code{$x$.$v$ = $x$.$v$ $op$ $e_2$}
are also generated in the case of $a$.
The static type of $a$ is the static type of \code{$e_1$.$v$ $op$ $e_2$}.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form \code{$e_1$.$v$ $op$= $e_2$}
proceeds as follows:
Evaluate $e_1$ to an object $u$ and let $x$ be a fresh variable bound to $u$.
Evaluate \code{$x$.$v$ = $x$.$v$ $op$ $e_2$} to an object $r$
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$[$e_2$] $op$= $e_3$}}
Consider a compound assignment $a$ of the form \code{$e_1$[$e_2$] $op$= $e_3$}.
Let $x$ and $i$ be fresh variables
where the static type of the former is the static type of $e_1$
and the static type of the latter is the static type of $e_2$.
Except for errors inside $e_1$ and $e_2$ and references to
the names $x$ and $i$,
exactly the same compile-time errors that would be caused by
\code{$x$[$i$] = $x$[$i$] $op$ $e_3$}
are also generated in the case of $a$.
The static type of $a$ is the static type of \code{$x$[$i$] $op$ $e_3$}.

\LMHash{}%
Evaluation of s compound assignment $a$ of the form
\code{$e_1$[$e_2$] $op$= $e_3$}
proceeds as follows:
Evaluate $e_1$ to an object $u$ and evaluate $e_2$ to an object $v$.
Let $x$ and $i$ be fresh variables bound to $u$ and $v$ respectively.
Evaluate \code{$x$[$i$] = $x$[$i$] $op$ $e_3$} to an object $r$,
and then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$?.$v$ $op$= $e_2$}}
Consider a compound assignment $a$ of the form \code{$e_1$?.$v$ $op$= $e_2$}.
Exactly the same compile-time errors that would be caused by
\code{$e_1$.$v$ $op$= $e_2$}
are also generated in the case of $a$.
The static type of $a$ is the static type of \code{$e_1$.$v$ $op$= $e_2$}.

\LMHash{}%
Evaluation of a compound assignment $a$ of the form
\code{$e_1$?.$v$ $op$= $e_2$}
proceeds as follows:
Evaluate $e_1$ to an object $u$.
If $u$ is the null object, then $a$ evaluates to the null object (\ref{null}).
Otherwise let $x$ be a fresh variable bound to $u$.
Evaluate \code{$x$.$v$ $op$= $e_2$} to an object $r$.
Then $a$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$C$?.$v$ $op$ = $e_2$}}
A compound assignment of the form \code{$C$?.$v$ $op$ = $e_2$}
where $C$ is a type literal
is equivalent to the expression \code{$C$.$v$ $op$ = $e_2$}.
\EndCase


\subsection{Conditional}
\LMLabel{conditional}

\LMHash{}%
A \Index{conditional expression} evaluates one of two expressions
based on a boolean condition.

\begin{grammar}
<conditionalExpression> ::= <ifNullExpression>
  \gnewline{} (`?' <expressionWithoutCascade> `:' <expressionWithoutCascade>)?
\end{grammar}

\LMHash{}%
Evaluation of a conditional expression $c$ of the form $e_1 ? e_2 : e_3$
proceeds as follows:

\LMHash{}%
First, $e_1$ is evaluated to an object $o_1$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o_1$ is not \code{bool}.
If $r$ is \TRUE, then the value of $c$ is
the result of evaluating the expression $e_2$.
Otherwise the value of $c$ is the result of evaluating the expression $e_3$.

\LMHash{}%
If $e_1$ shows that a local variable $v$ has type $T$,
then the type of $v$ is known to be $T$ in $e_2$,
unless any of the following are true:

\begin{itemize}
\item $v$ is potentially mutated in $e_2$,
\item $v$ is potentially mutated within a function other
  than the one where $v$ is declared, or
\item $v$ is accessed by a function defined in $e_2$ and
  $v$ is potentially mutated anywhere in the scope of $v$.
\end{itemize}

\LMHash{}%
It is a compile-time error if
the static type of $e_1$ may not be assigned to \code{bool}.
The static type of $c$ is the least upper bound (\ref{leastUpperBounds}) of
the static type of $e_2$ and the static type of $e_3$.


\subsection{If-null Expressions}
\LMLabel{ifNull}

\LMHash{}%
An \Index{if-null expression} evaluates an expression and
if the result is the null object (\ref{null}), evaluates another.

\begin{grammar}
<ifNullExpression> ::= <logicalOrExpression> (`??' <logicalOrExpression>)*
\end{grammar}

\LMHash{}%
Evaluation of an if-null expression $e$ of the form \code{$e_1$ ?? $e_2$}
proceeds as follows:

\LMHash{}%
Evaluate $e_1$ to an object $o$.
If $o$ is not the null object (\ref{null}), then $e$ evaluates to $o$.
Otherwise evaluate $e_2$ to an object $r$,
and then $e$ evaluates to $r$.

\LMHash{}%
The static type of $e$ is the least upper bound (\ref{leastUpperBounds}) of
the static type of $e_1$ and the static type of $e_2$.


\subsection{Logical Boolean Expressions}
\LMLabel{logicalBooleanExpressions}

\LMHash{}%
The logical boolean expressions combine boolean objects using
the boolean conjunction and disjunction operators.

\begin{grammar}
<logicalOrExpression> ::= \gnewline{}
  <logicalAndExpression> (`||' <logicalAndExpression>)*

<logicalAndExpression> ::= <equalityExpression> (`\&\&' <equalityExpression>)*
\end{grammar}

\LMHash{}%
A \Index{logical boolean expression} is either an equality expression
(\ref{equality}),
or an invocation of a logical boolean operator on
an expression $e_1$ with argument $e_2$.

\LMHash{}%
Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes
the evaluation of $e_1$ to an object $o_1$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o_1$ is not \code{bool}.
If $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE,
otherwise $e_2$ is evaluated to an object $o_2$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o_2$ is not \code{bool}.
Otherwise the result of evaluating $b$ is $o_2$.

\LMHash{}%
Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$
causes the evaluation of $e_1$ producing an object $o_1$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o_1$ is not \code{bool}.
If $o_1$ is \FALSE, the result of evaluating $b$ is \FALSE,
otherwise $e_2$ is evaluated to an object $o_2$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o_2$ is not \code{bool}.
Otherwise the result of evaluating $b$ is $o_2$.

\LMHash{}%
A logical boolean expression $b$ of the form $e_1 \&\& e_2$
shows that a local variable $v$ has type $T$
if both of the following conditions hold:

\begin{itemize}
\item Either $e_1$ shows that $v$ has type $T$
  or $e_2$ shows that $v$ has type $T$.
\item $v$ is not mutated in $e_2$ or within a function
  other than the one where $v$ is declared.
\end{itemize}

\LMHash{}%
If $e_1$ shows that a local variable $v$ has type $T$,
then the type of $v$ is known to be $T$ in $e_2$,
unless any of the following are true:

\begin{itemize}
%% The first item here is unnecessary for soundness,
%% and is retained mainly for backwards compatibility.
%% If $e_1$ shows that $v$ has type $T$, then any assignment
%% in $e_1$ does not invalidate that.
%% Removing the line is visible in the semantics, though, because:
%%  num x;
%%  (x ??= 42) != null && x is int & x.toRadixString(16) != ""
%% is allowed without the line, and disallowed with.
%% At time of writing, the analyzer disallows the code.
\item $v$ is potentially mutated in $e_1$,
\item $v$ is potentially mutated in $e_2$,
\item $v$ is potentially mutated within a function other
  than the one where $v$ is declared, or
\item $v$ is accessed by a function defined in $e_2$ and
  $v$ is potentially mutated anywhere in the scope of $v$.
\end{itemize}

\LMHash{}%
It is a compile-time error if
the static type of $e_1$ may not be assigned to \code{bool}
or if the static type of $e_2$ may not be assigned to \code{bool}.
The static type of a logical boolean expression is \code{bool}.


\subsection{Equality}
\LMLabel{equality}

\LMHash{}%
Equality expressions test objects for equality.

\begin{grammar}
<equalityExpression> ::= \gnewline{}
  <relationalExpression> (<equalityOperator> <relationalExpression>)?
  \alt \SUPER{} <equalityOperator> <relationalExpression>

<equalityOperator> ::= `=='
  \alt `!='
\end{grammar}

\LMHash{}%
An \Index{equality expression} is either a relational expression
(\ref{relationalExpressions}),
or an invocation of an equality operator on either \SUPER{}
or an expression $e_1$, with argument $e_2$.

\LMHash{}%
Evaluation of an equality expression $ee$ of the form \code{$e_1$ == $e_2$}
proceeds as follows:

\begin{itemize}
\item The expression $e_1$ is evaluated to an object $o_1$.
\item The expression $e_2$ is evaluated to an object $o_2$.
\item If either $o_1$ or $o_2$ is the null object (\ref{null}),
  then $ee$ evaluates to \TRUE{} if both $o_1$ and $o_2$ are the null object
  and to \FALSE{} otherwise.
Otherwise,
\item evaluation of $ee$ is equivalent to the method invocation
  \code{$o_1$.==($o_2$)}.
\end{itemize}

\LMHash{}%
Evaluation of an equality expression $ee$ of the form
\code{\SUPER{} == $e$}
proceeds as follows:

\begin{itemize}
\item The expression $e$ is evaluated to an object $o$.
\item If either \THIS{} or $o$ is the null object (\ref{null}),
  then $ee$ evaluates to evaluates to \TRUE{}
  if both \THIS{} and $o$ are the null object
  and to \FALSE{} otherwise.
Otherwise,
\item evaluation of $ee$ is equivalent to the method invocation
  \code{\SUPER.==($o$)}.
\end{itemize}

\commentary{%
  As a result of the above definition,
  user defined \lit{==} methods can assume that their argument is non-null,
  and avoid the standard boiler-plate prelude:

  \code{if (identical(\NULL, arg)) return \FALSE;}

  Another implication is that there is never a need
  to use \code{identical()} to test against \NULL,
  nor should anyone ever worry about whether to write
  \NULL{} == $e$ or $e$ == \NULL.%
}

\LMHash{}%
An equality expression of the form \code{$e_1$ != $e_2$} is equivalent to
the expression \code{!($e_1$ == $e_2$)}.
An equality expression of the form \code{\SUPER{} != $e$} is equivalent to
the expression \code{!(\SUPER{} == $e$)}.

%The expression $e_1$ is evaluated to an object $o_1$;
% then the expression $e_2$ is evaluated to an object $o_2$.
% Next, if $o_1$ and $o_2$ are the same object,
% then $ee$ evaluates to \TRUE, otherwise $ee$ evaluates to \FALSE.

\LMHash{}%
The static type of an equality expression is \code{bool}.


\subsection{Relational Expressions}
\LMLabel{relationalExpressions}

\LMHash{}%
Relational expressions invoke the relational operators on objects.

\begin{grammar}
<relationalExpression> ::= <bitwiseOrExpression> \gnewline{}
  (<typeTest> | <typeCast> | <relationalOperator> <bitwiseOrExpression>)?
  \alt \SUPER{} <relationalOperator> <bitwiseOrExpression>

<relationalOperator> ::= `>='
  \alt `>'
  \alt `<='
  \alt `<'
\end{grammar}

\LMHash{}%
A \Index{relational expression} is either a bitwise expression
(\ref{bitwiseExpressions}),
or an invocation of a relational operator on either \SUPER{}
or an expression $e_1$, with argument $e_2$.

\LMHash{}%
A relational expression of the form $e_1$ $op$ $e_2$ is equivalent to
the method invocation \code{$e_1$.$op$($e_2$)}.
A relational expression of the form \SUPER{} $op$ $e_2$ is equivalent to
the method invocation \code{\SUPER.$op$($e_2$)}.


\subsection{Bitwise Expressions}
\LMLabel{bitwiseExpressions}

\LMHash{}%
Bitwise expressions invoke the bitwise operators on objects.

\begin{grammar}
<bitwiseOrExpression> ::= \gnewline{}
  <bitwiseXorExpression> (`|' <bitwiseXorExpression>)*
  \alt \SUPER{} (`|' <bitwiseXorExpression>)+

<bitwiseXorExpression> ::= \gnewline{}
  <bitwiseAndExpression> (`^' <bitwiseAndExpression>)*
  \alt \SUPER{} (`^' <bitwiseAndExpression>)+

<bitwiseAndExpression> ::= <shiftExpression> (`\&' <shiftExpression>)*
  \alt \SUPER{} (`\&' <shiftExpression>)+

<bitwiseOperator> ::= `\&'
  \alt `^'
  \alt `|'
\end{grammar}

\LMHash{}%
A \Index{bitwise expression} is either a shift expression (\ref{shift}),
or an invocation of a bitwise operator
on either \SUPER{} or an expression $e_1$,
with argument $e_2$.

\LMHash{}%
A bitwise expression of the form \code{$e_1$ $op$ $e_2$} is equivalent to
the method invocation $e_1.op(e_2)$.
A bitwise expression of the form \code{\SUPER{} $op$ $e_2$} is equivalent to
the method invocation \code{\SUPER.$op$($e_2$)}.

\commentary{%
  It should be obvious that the static type rules for these expressions
  are defined by the equivalence above---ergo,
  by the type rules for method invocation and
  the signatures of the operators on the type $e_1$.
  The same holds in similar situations throughout this specification.%
}


\subsection{Shift}
\LMLabel{shift}

\LMHash{}%
Shift expressions invoke the shift operators on objects.

\begin{grammar}
<shiftExpression> ::= \gnewline{}
  <additiveExpression> (<shiftOperator> <additiveExpression>)*
  \alt \SUPER{} (<shiftOperator> <additiveExpression>)+

<shiftOperator> ::= `\ltlt'
  \alt `\gtgtgt'
  \alt `\gtgt'
\end{grammar}

\LMHash{}%
A \Index{shift expression} is either an additive expression
(\ref{additiveExpressions}),
or an invocation of a shift operator
on either \SUPER{} or an expression $e_1$,
with argument $e_2$.

\LMHash{}%
A shift expression of the form $e_1$ $op$ $e_2$ is equivalent to
the method invocation \code{$e_1$.$op$($e_2$)}.
A shift expression of the form \SUPER{} $op$ $e_2$ is equivalent to
the method invocation \code{\SUPER.$op$($e_2$)}.

\commentary{%
  Note that this definition implies left-to-right evaluation order
  among shift expressions:
  \code{$e_1$\,<\mbox<\,$e_2$\,<\mbox<\,$e_3$}
  is evaluated as
  \code{($e_1$\,<\mbox<\,$e_2$).<\mbox< ($e_3$)} which is equivalent to
  \code{($e_1$\,<\mbox<\,$e_2$)\,<\mbox<\,$e_3$}.
  The same holds for additive and multiplicative expressions.%
}


\subsection{Additive Expressions}
\LMLabel{additiveExpressions}

\LMHash{}%
Additive expressions invoke the addition operators on objects.

\begin{grammar}
<additiveExpression> ::= <multiplicativeExpression>
  \gnewline{} (<additiveOperator> <multiplicativeExpression>)*
  \alt \SUPER{} (<additiveOperator> <multiplicativeExpression>)+

<additiveOperator> ::= `+'
  \alt `-'
\end{grammar}

\LMHash{}%
An \Index{additive expression} is either a multiplicative expression
(\ref{multiplicativeExpressions}),
or an invocation of an additive operator
on either \SUPER{} or an expression $e_1$,
with argument $e_2$.

\LMHash{}%
An additive expression of the form $e_1$ $op$ $e_2$ is equivalent to
the method invocation \code{$e_1$.$op$($e_2$)}.
An additive expression of the form \SUPER{} $op$ $e_2$ is equivalent to
the method invocation \code{\SUPER.$op$($e_2$)}.

\LMHash{}%
The static type of an additive expression is usually determined
by the signature given in the declaration of the operator used.
However, invocations of the operators \code{+} and \code{-} of
class \code{int}, \code{double} and \code{num}
are treated specially by the typechecker.

\LMHash{}%
Let $e$ be an additive expression of the form \code{$e_1$ $op$ $e_2$},
let $T$ be the static type of $e_1$,
and let $C$ be the context type of $e$.

If \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}}, then
the context type of $e_2$ is determined as follows:

\begin{itemize}
  \item{} If \SubtypeNE{\code{int}}{C} and not \SubtypeNE{\code{num}}{C},
      and \SubtypeNE{T}{\code{int}}
      then the context type of $e_2$ is \code{int}.
  \item{} If \SubtypeNE{\code{double}}{C} and not \SubtypeNE{\code{num}}{C},
      and not \SubtypeNE{T}{\code{double}}
     then the context type of $e_2$ is \code{double}.
  \item{} Otherwise the context type of $e_2$ is \code{num}.
\end{itemize}

\LMHash{}%
Let further $S$ be the static type of $e_2$.
If \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}}
and $S$ is assignable to \code{num},
then the static type of $e$ is determined as follows:

\begin{itemize}
  \item{} If \SubtypeNE{T}{\code{double}}
    then the static type of $e$ is $T$.
  \item{} Otherwise, if \SubtypeNE{S}{\code{double}}
    and not \SubtypeNE{S}{\code{Never}},
    then the static type of $e$ is \code{double}.
  \item{} Otherwise, if \SubtypeNE{T}{\code{int}},
    \SubtypeNE{S}{\code{int}} and not \SubtypeNE{S}{\code{Never}},
    then the static type of $e$ is \code{int}.
  \item{} Otherwise the static type of $e$ is \code{num}.
\end{itemize}

\subsection{Multiplicative Expressions}
\LMLabel{multiplicativeExpressions}

\LMHash{}%
Multiplicative expressions invoke the multiplication operators on objects.

\begin{grammar}
<multiplicativeExpression> ::= \gnewline{}
  <unaryExpression> (<multiplicativeOperator> <unaryExpression>)*
  \alt \SUPER{} (<multiplicativeOperator> <unaryExpression>)+

<multiplicativeOperator> ::= `*'
  \alt `/'
  \alt `\%'
  \alt `~/'
\end{grammar}

\LMHash{}%
A \Index{multiplicative expression} is either a unary expression
(\ref{unaryExpressions}),
or an invocation of a multiplicative operator
on either \SUPER{} or an expression $e_1$,
with argument $e_2$.

\LMHash{}%
A multiplicative expression of the form $e_1$ $op$ $e_2$ is equivalent to
the method invocation \code{$e_1$.$op$($e_2$)}.
A multiplicative expression of the form \SUPER{} $op$ $e_2$ is equivalent to
the method invocation \code{\SUPER.$op$($e_2$)}.

\LMHash{}%
The static type of an multiplicative expression is usually determined
by the signature given in the declaration of the operator used.
However, invocations of the operators \code{*} and \code{\%} of
class \code{int}, \code{double} and \code{num}
are treated specially by the typechecker.

\LMHash{}%
Let $e$ be a multiplicative expression of the form \code{$e_1$ $op$ $e_2$}
where $op$ is one of \code{*} or \code{\%},
let $T$ be the static type of $e_1$,
and let $C$ be the context type of $e$.

If \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}}, then
the context type of $e_2$ is determined as follows:

\begin{itemize}
  \item{} If \SubtypeNE{\code{int}}{C} and not \SubtypeNE{\code{num}}{C},
      and \SubtypeNE{T}{\code{int}}
      then the context type of $e_2$ is \code{int}.
  \item{} If \SubtypeNE{\code{double}}{C} and not \SubtypeNE{\code{num}}{C},
      and not \SubtypeNE{T}{\code{double}}
     then the context type of $e_2$ is \code{double}.
  \item{} Otherwise the context type of $e_2$ is \code{num}.
\end{itemize}

\LMHash{}%
Let further $S$ be the static type of $e_2$.
If \SubtypeNE{T}{\code{num}} and not \SubtypeNE{T}{\code{Never}}
and $S$ is assignable to \code{num},
then the static type of $e$ is determined as follows:

\begin{itemize}
  \item{} If \SubtypeNE{T}{\code{double}}
    then the static type of $e$ is $T$.
  \item{} Otherwise, if \SubtypeNE{S}{\code{double}}
    and not \SubtypeNE{S}{\code{Never}},
    then the static type of $e$ is \code{double}.
  \item{} Otherwise, if \SubtypeNE{T}{\code{int}},
    \SubtypeNE{S}{\code{int}} and not \SubtypeNE{S}{\code{Never}},
    then the static type of $e$ is \code{int}.
  \item{} Otherwise the static type of $e$ is \code{num}.
\end{itemize}


\subsection{Unary Expressions}
\LMLabel{unaryExpressions}

\LMHash{}%
Unary expressions invoke unary operators on objects.

\begin{grammar}
<unaryExpression> ::= <prefixOperator> <unaryExpression>
  \alt <awaitExpression>
  \alt <postfixExpression>
  \alt (<minusOperator> | <tildeOperator>) \SUPER{}
  \alt <incrementOperator> <assignableExpression>

<prefixOperator> ::= <minusOperator>
  \alt <negationOperator>
  \alt <tildeOperator>

<minusOperator> ::= `-'

<negationOperator> ::= `!'

<tildeOperator> ::= `~'
\end{grammar}

\LMHash{}%
A \Index{unary expression} is either a postfix expression
(\ref{postfixExpressions}),
an await expression (\ref{awaitExpressions})
or an invocation of a prefix operator on an expression
or an invocation of a unary operator on either \SUPER{} or an expression $e$.

\LMHash{}%
The expression $!e$ is treated as
(\ref{notation})
\code{($e$\,?\,\FALSE\,:\,\TRUE)}.

\LMHash{}%
An expression of the form \code{++$e$} is treated as
\code{($e$\,+=\,1)}.
An expression of the form \code{-{}-$e$} is treated as
\code{($e$\,-=\,1)}.

\LMHash{}%
Let $e$ be an expression of the form \code{-$l$}
where $l$ is an integer literal (\ref{numbers}) with numeric integer value $i$,
and with static context type $T$.
If \code{double} is assignable to $T$ and \code{int} is not assignable to $T$,
then the static type of $e$ is \code{double};
otherwise the static type of $e$ is \code{int}.

\LMHash{}%
If the static type of $e$ is \code{int} then $e$ evaluates to
an instance of the \code{int} class representing the numeric value $-i$.
If $i$ is zero and the \code{int} class can represent a negative zero value,
then the resulting instance instead represents that negative zero value.
It is a compile-time error if the integer $-i$ cannot be represented
exactly by an instance of \code{int}.

\LMHash{}%
If the static type of $e$ is \code{double} then $e$ evaluates to
to an instance of the \code{double} class representing the numeric value $-i$.
If $i$ is zero, the resulting instance instead represents the
\emph{negative} zero double value, \code{-0.0}.
It is a compile-time error if the integer $-i$ cannot be represented
exactly by an instance of \code{double}.
\commentary{%
  We treat \code{-$l$} \emph{as if} it is a single integer literal
  with a negative numeric value.
  We do not evaluate $l$ individually as an expression,
  or concern ourselves with its static type.%
}

\LMHash{}%
Any other expression of the form \code{$op$ $e$} is equivalent to
the method invocation \code{$e.op()$}.
An expression of the form \code{$op$ \SUPER} is equivalent to
the method invocation (\ref{superInvocations}) \code{\SUPER.$op()$}.


\subsection{Await Expressions}
\LMLabel{awaitExpressions}

\LMHash{}%
An \Index{await expression} allows code to
yield control until an asynchronous operation
(\ref{functions})
completes.

\begin{grammar}
<awaitExpression> ::= \AWAIT{} <unaryExpression>
\end{grammar}

\LMHash{}%
\BlindDefineSymbol{a, e, S}%
Let $a$ be an expression of the form \code{\AWAIT\,\,$e$}.
Let $S$ be the static type of $e$.
The static type of $a$ is then \flatten{S}
(\ref{functionExpressions}).

\LMHash{}%
Evaluation of $a$ proceeds as follows:
First, the expression $e$ is evaluated to an object $o$.
Let \DefineSymbol{T} be \flatten{S}.
If the run-time type of $o$ is a subtype of \code{Future<$T$>},
then let \DefineSymbol{f} be $o$;
otherwise let $f$ be the result of creating
a new object using the constructor \code{Future<$T$>.value()}
with $o$ as its argument.

\LMHash{}%
Next, the stream associated with
the innermost enclosing asynchronous \FOR{} loop
(\ref{asynchronousFor-in}),
if any, is paused.
The current invocation of the function body immediately enclosing $a$
is suspended until after $f$ completes.
At some time after $f$ is completed, control returns to the current invocation.
If $f$ has completed with an error $x$ and stack trace $t$,
$a$ throws $x$ and $t$
(\ref{expressionEvaluation}).
If $f$ completes with an object $v$, $a$ evaluates to $v$.

\rationale{%
  The use of \flattenName{} to find $T$
  and hence determine the dynamic type test
  implies that we await a future in every case where this choice is sound.%
}

\commentary{%
  An interesting case on the edge of this trade-off is when $e$
  has the static type \code{FutureOr<Object>?}.
  You could say that the intention behind this type is that
  the value of $e$ is a \code{Future<Object>},
  or it is an \code{Object} which is not a future,
  or it is \NULL.
  So, presumably, we should await the first kind,
  and we should pass on the second and third kind unchanged.
  However, the second kind could be a \code{Future<Object?>}.
  This object isn't a \code{Future<Object>}, and it isn't \NULL,
  so it \emph{must} be considered to be in the second group.
  Nevertheless, \flatten{\code{FutureOr<Object>?}} is \code{Object?},
  so we \emph{will} await a \code{Future<Object?>}.
  We have chosen this semantics because it was the smallest breaking change
  relative to the semantics in earlier versions of Dart,
  and also because it allows for a simple rule:
  The type of \code{\AWAIT\,\,$e$} is used to decide whether or not
  the future (if any) is awaited, and there are no exceptions---even
  in cases like this example, where the type seems to imply that
  a \code{Future<Object?>} should not be awaited.
  In summary, we await every future that we can soundly await.%
}

\commentary{%
  An await expression can only occur in a function which is declared
  asynchronous. The \AWAIT{} identifier has has no special meaning
  in the context of a normal function, so occurrences of \AWAIT{}
  in those functions does not introduce an await expression.
  However, \code{\AWAIT ($e$)} can be a valid function invocation in
  non-asynchronous functions.%
}

\rationale{%
  An await expression could not meaningfully occur in a synchronous function.
  If such a function were to suspend waiting for a future,
  it would no longer be synchronous.%
}

\commentary{%
  It is not a compile-time error if the type of $e$ is not
  a supertype or subtype of \code{Future}.
  Tools may choose to give a hint in such cases.%
}


\subsection{Postfix Expressions}
\LMLabel{postfixExpressions}

\LMHash{}%
Postfix expressions invoke the postfix operators on objects.

\begin{grammar}
<postfixExpression> ::= <assignableExpression> <postfixOperator>
  \alt <primary> <selector>*

<postfixOperator> ::= <incrementOperator>

<constructorInvocation> ::= \gnewline{}
  <typeName> <typeArguments> `.' <identifier> <arguments>

<selector> ::= `!'
  \alt <assignableSelector>
  \alt <argumentPart>

<argumentPart> ::=
  <typeArguments>? <arguments>

<incrementOperator> ::= `++'
  \alt `-\mbox-'
\end{grammar}

\LMHash{}%
A \Index{postfix expression} is either a primary expression;
a function, method or getter invocation;
an invocation of a named constructor;
or an invocation of a postfix operator on an expression $e$.
All but the latter two are specified elsewhere.

\LMHash{}%
\Case{Constructor Invocations}
Consider a \synt{constructorInvocation} $e$ of the form
\code{$n$<\metavar{typeArguments}>.\id(\metavar{arguments})}.
If $n$ does not denote a class $C$
that declares a constructor named \code{$C$.\id},
a compile-time error occurs.

\LMHash{}%
Otherwise, if $e$ occurs in a constant context
(\ref{constantContexts})
then $e$ is treated as \code{\CONST\,\,$e$},
and if $e$ does not occur in a constant context
then $e$ is treated as \code{\NEW\,\,$e$}.

% We might add support for passing type arguments to static methods,
% but that is not a feature which is coming any time soon.
\commentary{%
  Note that $e$ cannot be anything other than an instance creation
  (constant or not)
  because $e$ provides actual type arguments to $n$,
  which is not supported if $n$ denotes a library prefix,
  nor if $e$ is a static method invocation.%
}
\EndCase

\LMHash{}%
\Case{\code{$v$++}, \code{$v$-{}-}}
Consider a postfix expression $e$ of the form \code{$v$\,\op},
where $v$ is an identifier and \op{} is either \lit{++} or \lit{-{}-}.
A compile-time error occurs unless $v$ denotes a variable,
or $v$ denotes a getter and there is an associated setter \code{$v$=}.
Let $T$ be the static type of the variable $v$ or the return type of the getter.
A compile-time error occurs if $T$ is not \DYNAMIC{}
and $T$ does not have an operator \lit{+} (when \op{} is \lit{++})
or operator \lit{-} (when \op{} is \lit{-{}-}),
or if the return type of this operator is not assignable to
the variable respectively the argument type of the setter.
A compile-time error occurs if \code{int} is not assignable to
the parameter type of said operator.
The static type of $e$ is $T$.

\LMHash{}%
Evaluation of a postfix expression $e$
of the form \code{$v$++} respectively \code{$v$-{}-},
where $v$ is an identifier, proceeds as follows:
Evaluate $v$ to an object $r$ and let $y$ be a fresh variable bound to $r$.
%% TODO(eernst): In order to eliminate syntactic sugar, we should probably
%% rewrite this to specify the effect directly (cases to remember: `v` is a
%% local variable/parameter, instance/static/global/imported getter).
Evaluate \code{$v$ = $y$ + 1} respectively \code{$v$ = $y$ - 1}.
Then $e$ evaluates to $r$.

\rationale{%
  The above ensures that if the evaluation involves a getter,
  it gets called exactly once.
  Likewise in the cases below.%
}
\EndCase

\LMHash{}%
\Case{\code{$C$.$v$++}, \code{$C$.$v$-{}-}}
Consider a postfix expression $e$ of the form \code{$C$.$v$\,\op},
where $C$ is a type literal and \op{} is either \lit{++} or \lit{-{}-}.
A compile-time error occurs unless \code{$C$.$v$} denotes a static getter
and there is an associated static setter \code{$v$=}
\commentary{(possibly implicitly induced by a static variable)}.
Let $T$ be the return type of said getter.
A compile-time error occurs if $T$ is not \DYNAMIC{}
and $T$ does not have an operator \lit{+} (when \op{} is \lit{++})
or operator \lit{-} (when \op{} is \lit{-{}-}),
or if the return type of this operator is not assignable to
the argument type of the setter.
A compile-time error occurs if \code{int} is not assignable to
the parameter type of said operator.
The static type of $e$ is $T$.

\LMHash{}%
Evaluation of a postfix expression $e$
of the form \code{$C$.$v$++} respectively \code{$C$.$v$-{}-}
where $C$ is a type literal proceeds as follows:
Evaluate \code{$C$.$v$} to an object $r$
and let $y$ be a fresh variable bound to $r$.
Evaluate \code{$C$.$v$ = $y$ + 1} respectively \code{$C$.$v$ = $y$ - 1}.
Then $e$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$.$v$++}, \code{$e_1$.$v$-{}-}}
Consider a postfix expression $e$ of the form \code{$e_1$.$v$\,\op}
where \op{} is either \lit{++} or \lit{-{}-}.
Let $S$ be the static type of $e_1$.
A compile-time error occurs unless $S$ has
a getter named $v$ and a setter named \code{$v$=}
\commentary{(possibly implicitly induced by an instance variable)}.
Let $T$ be the return type of said getter.
A compile-time error occurs if $T$ is not \DYNAMIC{}
and $T$ does not have an operator \lit{+} (when \op{} is \lit{++})
or operator \lit{-} (when \op{} is \lit{-{}-}),
or if the return type of this operator is not assignable to
the argument type of the setter.
A compile-time error occurs if \code{int} is not assignable to
the parameter type of said operator.
The static type of $e$ is $T$.

\LMHash{}%
Evaluation of a postfix expression $e$
of the form \code{$e_1$.$v$++} respectively \code{$e_1$.$v$-{}-}
proceeds as follows:
Evaluate $e_1$ to an object $u$ and let $x$ be a fresh variable bound to $u$.
Evaluate \code{$x$.$v$} to an object $r$
and let $y$ be a fresh variable bound to $r$.
Evaluate \code{$x$.$v$ = $y$ + 1} respectively \code{$x$.$v$ = $y$ - 1}.
Then $e$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$[$e_2$]++}, \code{$e_1$[$e_2$]-{}-}}
Consider a postfix expression $e$ of the form \code{$e_1$[$e_2$]\,\op}
where \op{} is either \lit{++} or \lit{-{}-}.
Let $S_1$ be the static type of $e_1$
and $S_2$ be the static type of $e_2$.
A compile-time error occurs unless $S_1$ has
an operator \lit{[]} and an operator \lit{[]=}.
Let $T$ be the return type of the former.
A compile-time error occurs unless $S_2$ is assignable to
the first parameter type of said operator \lit{[]=}.
A compile-time error occurs if $T$ is not \DYNAMIC{}
and $T$ does not have an operator \lit{+} (when \op{} is \lit{++})
or operator \lit{-} (when \op{} is \lit{-{}-}),
or if the return type of this operator is not assignable to
the second argument type of said operator \lit{[]=}.
% We allow `e1[e2]++;` also when the entry has static type double,
% so we can't just say `assignable'.
A compile-time error occurs if passing the integer literal \code{1}
as an argument to said operator \lit{+} or \lit{-} would be an error.
The static type of $e$ is $T$.

\LMHash{}%
Evaluation of a postfix expression $e$
of the form \code{$e_1$[$e_2$]++} respectively \code{$e_1$[$e_2$]-{}-}
proceeds as follows:
Evaluate $e_1$ to an object $u$ and $e_2$ to an object $v$.
Let $a$ and $i$ be fresh variables bound to $u$ and $v$ respectively.
Evaluate \code{$a$[$i$]} to an object $r$
and let $y$ be a fresh variable bound to $r$.
Evaluate \code{$a$[$i$] = $y$ + 1} respectively \code{$a$[$i$] = $y$ - 1}.
Then $e$ evaluates to $r$.
\EndCase

\LMHash{}%
\Case{\code{$e_1$?.$v$++}, \code{$e_1$?.$v$-{}-}}
Consider a postfix expression $e$ of the form \code{$e_1$?.$v$\,\op}
where \op{} is either \lit{++} or \lit{-{}-}.
Exactly the same compile-time errors that would be caused by
\code{$e_1$.$v$\,\op}
are also generated in the case of \code{$e_1$?.$v$\,\op}.
The static type of $e$ is the static type of \code{$e_1$.$v$}.

\LMHash{}%
Evaluation of a postfix expression $e$
of the form \code{$e_1$?.$v$++} respectively \code{$e_1$?.$v$-{}-}
proceeds as follows:
If $e_1$ is a type literal, evaluation of $e$ is equivalent to
evaluation of \code{$e_1$.$v$++} respectively \code{$e_1$.$v$-{}-}.
Otherwise evaluate $e_1$ to an object $u$.
if $u$ is the null object, $e$ evaluates to the null object (\ref{null}).
Otherwise let $x$ be a fresh variable bound to $u$.
Evaluate \code{$x$.$v$++} respectively \code{$x$.$v$-{}-} to an object $o$.
Then $e$ evaluates to $o$.
\EndCase


\subsection{Assignable Expressions}
\LMLabel{assignableExpressions}

\LMHash{}%
\IndexCustom{Assignable expressions}{assignable expression} are terms
that can appear on the left hand side of an assignment.
This section describes how to evaluate subterms of these terms when needed.
The semantics of an assignment as a whole is described elsewhere
(\ref{assignment}).

\commentary{%
  The grammar of assignable expressions includes very general forms
  like an identifier \id{} or a qualified identifier \code{$\id_1$.$\id_2$}.
  Hence, an assignable expression can have many different meanings,
  depending on the binding of those identifiers in the context.

  For example, the term \code{x.y.z} is an assignable expression.
  \code{x.y} may refer to a getter \code{y} on
  an object referenced by a variable \code{x},
  in which case \code{x.y} will be evaluated to an object
  before accessing the \code{z} member of that object.
  The term \code{x.y} could also denote a class \code{y} referenced through
  an import prefix \code{x},
  with \code{z} denoting a static variable of that class.
  In this case \code{x.y} will not be evaluated to a value.%
}

\begin{grammar}
<assignableExpression> ::= <primary> <assignableSelectorPart>
  \alt \SUPER{} <unconditionalAssignableSelector>
  \alt <identifier>

<assignableSelectorPart> ::= <selector>* <assignableSelector>

<unconditionalAssignableSelector> ::= `[' <expression> `]'
  \alt `.' <identifier>

<assignableSelector> ::= <unconditionalAssignableSelector>
  \alt `?.' <identifier>
  \alt `?' `[' <expression> `]'

\end{grammar}

\LMHash{}%
The section about assignments
(\ref{assignment})
specifies the static analysis and dynamic semantics of
various forms of assignment.
Each of those cases is applicable when the specified subterms satisfy
the given side conditions
\commentary{%
  (e.g., one case of the form \code{$e_1$.$v$\,\,??=\,\,$e_2$} requires $e_1$
  to be an expression, whereas \code{$C$.$v$\,\,??=\,\,$e$}
  requires $C$ to be a type literal)%
}.
The cases requiring subterms to be expressions are considered least specific,
that is, they are only used if no other case matches
\commentary{%
  (so the case containing $C$ is used
  if the corresponding term is a type literal)%
}.

\commentary{%
  Syntactically, these expressions are not derived from \synt{expression},
  but they are derivable from \synt{expression}, e.g., because
  an \synt{assignableExpression} may contain a \synt{primary}
  which is derivable from \synt{expression}.
  We use the following rule to find such expressions:%
}

\LMHash{}%
\BlindDefineSymbol{e, t}%
Let $e$ be an \synt{assignableExpression}.
Assume that $t$ is a term such that $e$ can be derived from
\syntax{$t$ <assignableSelector>}.
In this case we say that $t$ is the
\IndexCustom{receiver term}{assignable expression!receiver term}
of $e$.
When $t$ is an expression, we say that $t$ is the
\IndexCustom{receiver expression}{assignable expression!receiver expression}
of $e$.

\commentary{%
  In short, we obtain $t$ by cutting off an assignable selector
  from the end of $e$.
  It is easy to see that only some \synt{assignableExpression}s
  have a receiver term.
  For instance, a plain \synt{identifier} does not.%
}

\LMHash{}%
Let $e$ be an assignable expression.
Assume that $e$ has a receiver expression $t$.
Evaluation of $t$ proceeds in the same way as
evaluation of any other expression.


\subsection{Lexical Lookup}
\LMLabel{lexicalLookup}

\LMHash{}%
This section specifies how to look up a name
based on the enclosing lexical scopes.
This is known as a \Index{lexical lookup}.
When \id{} is an identifier,
it may look up a name $n$ of the form \id{} as well as of the form \code{\id=}.

\LMHash{}%
A lexical lookup can yield a declaration or an import prefix,
and it can yield nothing.

\commentary{%
  It is not a compile-time error when the lexical lookup yields nothing.
  In this situation the given name $n$ will be transformed into
  \code{\THIS.$n$},
  and the static analysis of the resulting expression
  may or may not have any compile-time errors.%
}

\LMHash{}%
A lexical lookup may incur a compile-time error,
as specified below.
However, that is different from a result yielded by the lexical lookup,
because this specification never specifies the propagation of errors.

\commentary{%
  In other words, when other parts of this specification indicate that
  a lexical lookup is performed,
  they need to consider the further steps taken
  when the lookup yields a declaration,
  when it yields an import prefix,
  and when it yields nothing.
  But they do not mention that, e.g., \code{\id.m} is an error
  because the lexical lookup for \id{} incurred an error.%
}

\commentary{%
  A lexical lookup differs from a lookup of an instance member
  (\ref{lookup})
  because that operation searches through a sequence of superclasses,
  whereas a lexical lookup searches through a sequence of enclosing scopes.
  A lexical lookup differs from a straightforward lookup in the enclosing scopes
  because the lexical lookup ``bundles'' getters and setters,
  as detailed below.%
}

\LMHash{}%
\BlindDefineSymbol{n, id}%
Consider the situation where a name $n$
has basename \id{}
(\ref{classMemberConflicts})
where \id{} is an identifier,
and a lexical lookup of $n$ is performed from a given location
\DefineSymbol{\ell}.

\commentary{%
  We specify a name and a location from where a lexical lookup is performed.
  The location is not always redundant:
  In some situations we perform a lookup for a setter named \code{\id=},
  but the token \code{\id=} does not occur in the program.
  To handle such situations we must specify both
  the name which is being looked up,
  and the location that determines which scopes are the enclosing ones.%
}

\LMHash{}%
When we say that a lexical lookup of the identifier \id{} is performed,
it is understood that the lookup is performed from
the location of the given occurrence of \id.

\LMHash{}%
Let $S$ be the innermost lexical scope containing $\ell$
which has a declaration with basename \id.
In the case where $S$ has
a declaration named \id{} as well as a declaration named \code{\id=},
let \DefineSymbol{D} be the declaration named $n$.
In the situation where $S$ has
exactly one declaration with basename \id,
let $D$ be that declaration.

\commentary{%
  A non-local variable declaration named \id{} will implicitly induce
  a getter \id{} and possibly a setter \code{\id=} into the current scope.
  This means that $D$ may denote an implicitly induced getter or setter
  rather than the underlying variable declaration.
  That is significant in the case where an error must arise
  because the lookup was for one kind, but only the other kind exists.%
}

\commentary{%
  If we are looking up a name $n$ with basename \id,
  we stop searching if we find any declaration named \id{} or \code{\id=}.
  If, in that scope, there are declarations for both \id{} and \code{\id=},
  we return the one which has the requested name $n$.
  In the case where only one declaration is present, we return it,
  even though it may have the name \id{} when $n$ is \code{\id=}, or vice versa.
  That situation may cause an error, as specified below.%
}

\LMHash{}%
In the first step, we check for several potential errors.

% Even when we have found a declaration, it may have the wrong name.
\LMHash{}%
\Case{$D$ exists}
In this case, at least one declaration with basename \id{}
is in scope at the location $\ell$.
It is a compile-time error if the name of $D$ is not $n$,
unless $D$ is an instance member or a local variable
\commentary{(which may be a formal parameter)}.

\commentary{%
  That is, it is an error if we look for a setter and find a getter,
  or vice versa,
  but not an error if we look for a setter and find a local variable.
  If we look for a setter and find an instance getter, or vice versa,
  it is not an error,
  because the setter could be inherited.
  That is checked after yielding nothing
  (which implies that \THIS{} will be prepended).%
}

\LMHash{}%
If $D$ is an instance member,
it is a compile-time error if $\ell$ does not have access to \THIS.
\EndCase

\LMHash{}%
\Case{$D$ does not exist}
It is a compile-time error if $\ell$ does not have access to \THIS{}
(\ref{classes}).
\EndCase

\rationale{%
  We are always looking up \emph{both} \id{} and \code{\id=},
  no matter whether $n$ is \id{} or \code{\id=}.
  This approach creates a tighter connection between a pair of declarations
  where one is a getter named \id{}
  and the other is a setter named \code{\id=}.
  This allows developers to think about
  a getter and setter that are declared together as a single entity,
  rather than two independent declarations.%
}

\commentary{%
  For example, if a term refers to \id{} and needs a setter,
  and the innermost declaration named \id{} or \code{\id=} is a getter $g$
  and there is no corresponding setter,
  it is a compile-time error.
  This error occurs even in the case where a more remote enclosing scope has
  a declaration of a setter $s$ named \code{\id=},
  because we already committed to using $g$
  (so that's actually ``a setter/getter pair where the setter is missing''),
  and we could say that this ``pair'' shadows $s$:%
}

\begin{dartCode}
\SET{} id(int value) \{\} // \comment{This is $s$}
\\
\CLASS{} A \{
  int \GET{} id => 42; // \comment{This is $g$}
  user() \{
    id = 0; // \comment{Compile-time error}
  \}
\}
\end{dartCode}

\LMHash{}%
In the second and last step, if no error occurred,
proceed as described in the first applicable case from the following list:

\begin{itemize}
\item
  When $D$ does not exist,
  the lexical lookup yields nothing.
  \commentary{%
    In this case it is guaranteed that $\ell$ has access to \THIS,
    and $n$ will be treated as \code{\THIS.$n$}.
    But errors may still occur, e.g.,
    because there is no member of the interface of \THIS{} named $n$,
    and also no accessible and applicable extension method.%
  }
\item
  Consider the case where $D$ is a formal type parameter declaration
  of a class or a mixin.
  It is a compile-time error if $\ell$ occurs inside
  a static method, static getter, or static setter,
  or inside a static variable initializer.
  % NB: There is _no_ error when it occurs in an instance variable initializer,
  % which means that it is allowed "to access `this`" in that particular case.
  % This may seem inconsistent, but it should not be harmful.
  Otherwise, the lexical lookup yields $D$.
\item
  Consider the case where $D$ is an instance member declaration in
  a class or mixin $A$.
  The lexical lookup then yields nothing.
  \commentary{%
    In this case it is guaranteed that $\ell$ has access to \THIS.%
  }
\item
  % Cases covered here: $D$ is
  % - an import with prefix \id;
  % - a class or type alias; % whose name must be \id, no need to say that..
  % - a library variable, getter, or setter;
  % - a static method/getter/setter of a class, mixin, enum, or extension;
  % - an instance method of an extension;
  % - a local variable (which may be a formal parameter);
  % - a local function.
  Otherwise, the lexical lookup yields $D$.
\end{itemize}

\rationale{%
  Note that a lexical lookup will never yield a declaration of
  an instance member.
  In each case where it is determined that there is no error,
  and an instance member is the result of the lookup,
  the lexical lookup yields nothing.

  The reason for this is that there may not be a declaration in scope,
  but the interface of the class could have the required member,
  or an extension method could be applicable.
  So, for uniformity,
  in these situations we always report that nothing was found,
  which implies that \THIS{} should be added.%
}


\subsection{Identifier Reference}
\LMLabel{identifierReference}

\LMHash{}%
An \Index{identifier expression} consists of a single identifier;
it provides access to an object via an unqualified name.
A \synt{typeIdentifier} is an identifier which can be used
as the name of a type declaration.

\commentary{%
A \synt{qualifiedName} is not an identifier expression,
but we specify its syntax here because it is used in several different contexts,
and it is more closely related to the plain identifier
than it is to any single one of those grammar rules where it is used.%
}

\begin{grammar}
<identifier> ::= <IDENTIFIER>
  \alt <BUILT\_IN\_IDENTIFIER>
  \alt <OTHER\_IDENTIFIER>

<typeIdentifierNotType> ::= <IDENTIFIER>
  \alt <OTHER\_IDENTIFIER\_NOT\_TYPE>
  \alt \DYNAMIC{}

<typeIdentifier> ::= <typeIdentifierNotType>
  \alt \TYPE{}

<qualifiedName> ::= <typeIdentifier> `.' <identifier>
  \alt <typeIdentifier> `.' <typeIdentifier> `.' <identifier>

<BUILT\_IN\_IDENTIFIER> ::= \ABSTRACT{} | \AS{} | \COVARIANT{} | \DEFERRED{}
  \alt\hspace{-3mm} \DYNAMIC{} | \EXPORT{} | \EXTERNAL{} | \EXTENSION{} |
    \FACTORY{} | \FUNCTION{} | \GET{}
  \alt\hspace{-3mm} \IMPLEMENTS{} | \IMPORT{} | \INTERFACE{} | \LATE{} |
    \LIBRARY{} | \MIXIN{} | \OPERATOR{}
  \alt\hspace{-3mm} \PART{} | \REQUIRED{} | \SET{} | \STATIC{} | \TYPEDEF{}

<OTHER\_IDENTIFIER\_NOT\_TYPE> ::= \gnewline{}
  \ASYNC{} | \HIDE{} | \OF{} | \ON{} | \SHOW{} | \SYNC{} |
  \AWAIT{} | \YIELD{}

<OTHER\_IDENTIFIER> ::= \gnewline{}
  <OTHER\_IDENTIFIER\_NOT\_TYPE> | \TYPE{}

<IDENTIFIER\_NO\_DOLLAR> ::= <IDENTIFIER\_START\_NO\_DOLLAR>
  \gnewline{} <IDENTIFIER\_PART\_NO\_DOLLAR>*

<IDENTIFIER\_START\_NO\_DOLLAR> ::= <LETTER> | `_'

<IDENTIFIER\_PART\_NO\_DOLLAR> ::= \gnewline{}
  <IDENTIFIER\_START\_NO\_DOLLAR> | <DIGIT>

<IDENTIFIER> ::= <IDENTIFIER\_START> <IDENTIFIER\_PART>*

<IDENTIFIER\_START> ::= <IDENTIFIER\_START\_NO\_DOLLAR> | `$'

<IDENTIFIER\_PART> ::= <IDENTIFIER\_START> | <DIGIT>

<LETTER> ::= `a' .. `z' | `A' .. `Z'

<DIGIT> ::= `0' .. `9'

<WHITESPACE> ::= (`\\t' | ` ' | <LINE\_BREAK>)+
\end{grammar}

\LMHash{}%
The ordering of the lexical rules above ensure that \synt{IDENTIFIER}
and \synt{IDENTIFIER\_NO\_DOLLAR} do not derive any built-in identifiers.
Similarly, the lexical rule for reserved words (\ref{reservedWords})
must be considered to come before the rule for \synt{BUILT\_IN\_IDENTIFIER},
such that \synt{IDENTIFIER} and \synt{IDENTIFIER\_NO\_DOLLAR}
also do not derive any reserved words.

\LMHash{}%
A \Index{built-in identifier} is one of
the identifiers produced by the production \synt{BUILT\_IN\_IDENTIFIER}.

\commentary{%
  Note that it is a syntax error if a built-in identifier
  is used as the declared name of
  %% TODO(eernst): Come extension types, add them.
  a prefix, class, mixin, enum, type parameter, type alias, or extension.
  Similarly, it is a syntax error to use a built-in identifier
  other than \DYNAMIC{} or \FUNCTION{}
  as an identifier in a type annotation or a type parameter bound.%
}

\rationale{%
  Built-in identifiers are identifiers that are used as keywords in Dart,
  but are not reserved words.
  A built-in identifier may not be used to name a class or type.
  In other words, they are treated as reserved words when used as types.
  This eliminates many confusing situations,
  both for human readers and during parsing.%
}

\LMHash{}%
It is a compile-time error if either of the identifiers \AWAIT{} or \YIELD{}
is used as an \synt{identifier} in a function body
marked with either \ASYNC, \code{\ASYNC*}, or \code{\SYNC*}.

\rationale{%
  This makes the identifiers \AWAIT{} and \YIELD{} behave like reserved words
  in a limited context.
  This approach was chosen because it was less breaking than it would have been
  to make \AWAIT{} and \YIELD{} reserved words or built-in identifiers,
  at the time where these features were added to the language.%
}

\LMHash{}%
A \Index{qualified name} is two or three identifiers separated by \lit{.}.
All but the last one must be a \synt{typeIdentifier}.
It is used to denote a declaration which is imported with a prefix,
or a \STATIC{} declaration in a class, mixin, enum, or extension, or both.

\LMHash{}%
The static type of an identifier expression $e$ which is an identifier \id{}
is determined as follows.
Perform a lexical lookup of \id{}
(\ref{lexicalLookup})
from the location of $e$.

\LMHash{}%
\Case{Lexical lookup yields a declaration}
Let $D$ be the declaration yielded by the lexical lookup of \id.

\begin{itemize}
\item
  If $D$ declares a class, mixin, enum, type alias, an enumerated type,
  or a type parameter,
  the static type of $e$ is \code{Type}.
\item
  If $D$ is the declaration of a library getter
  \commentary{(which may be implicitly induced by a library variable)},
  the static type of $e$ is the static type of the
  library getter invocation \id{}
  (\ref{topLevelGetterInvocation}).
\item
  If $D$ is a static method, library function, or local function,
  the static type of $e$ is the function type of $D$.

  \commentary{%
    Note that $e$ may subsequently be subjected to
    generic function instantiation
    (\ref{genericFunctionInstantiation}).%
  }
\item
  If $D$ is the declaration of a static getter
  \commentary{(which may be implicitly induced by a static variable)}
  and $D$ occurs in the class $C$,
  the static type of $e$ is the return type of the getter
  \code{$C$.\id}.
\item
  If $D$ is a local variable declaration
  \commentary{(which can be a formal parameter)}
  the static type of $e$ is the type of the variable $v$ declared by $D$,
  unless $v$ is known to have some type $T$,
  where $T$ is a subtype of any other type $S$
  such that $v$ is known to have type $S$,
  in which case the static type of $e$ is $T$.
\item
  % Extension getter invocation by scope.
  If $D$ is a declaration of an instance getter
  in an extension declaration $E$,
  then the static type of $e$ is the return type of $D$.
\item
  % Extension method tear-off by scope.
  If $D$ is a declaration of an instance method
  in an extension declaration $E$,
  then the static type of $e$ is the function type of $D$.
\item
  \commentary{%
    A lexical lookup will never yield a declaration
    which is an instance member of a class.%
  }
\end{itemize}
\vspace{-1ex}
\EndCase

\LMHash{}%
\Case{Lexical lookup yields an import prefix}
In this case the lexical lookup
(\ref{lexicalLookup})
for \id{} yields an import prefix $p$.
% A prefix can never be used as a stand-alone expression.
In this case a compile-time error occurs,
unless the token immediately following $e$ is \lit{.}.
No static type is associated with $e$ in this case.

% A type is specified in \ref{imports}, so it would be consistent to report
% it. However, no usage will be made of that type, because the static type
% of every construct of the form $p$.something is specified without referring
% to the static type of $p$. So we do not mention that type here.
\commentary{%
  No such type is needed, because every construct where
  an import prefix $p$ is used and followed by \lit{.} is specified
  in such a way that the type of $p$ is not used.%
}
\EndCase

\LMHash{}%
\Case{Lexical lookup yields nothing}
When the lexical lookup
(\ref{lexicalLookup})
for \id{} yields nothing,
$e$ is treated as
(\ref{notation})
\code{\THIS.\id}.

\commentary{%
  In this case it is known that $e$ has access to \THIS{}
  (\ref{classes}).
  Both the static analysis and evaluation proceeds with
  \code{\THIS.\id},
  so there is no need to further specify the treatment of $e$.%
}
\EndCase

\LMHash{}%
Evaluation of an identifier expression $e$ of the form \id{}
proceeds as follows:

\LMHash{}%
\Case{Lexical lookup yields a declaration}
In this case the lexical lookup
(\ref{lexicalLookup})
for \id{} yields a declaration $D$.
The evaluation of $e$ proceeds as follows:

\begin{itemize}
\item
  If $D$ is a class, mixin, enum, or type alias,
  the value of $e$ is an object implementing the class \code{Type}
  which reifies the corresponding type.
\item
  If $D$ is a type parameter $X$ then the value of $e$ is
  the value of the actual type argument corresponding to $X$
  that was passed to the generative constructor that created
  the current binding of \THIS.
\item
  If $D$ is the declaration of a library getter
  \commentary{(which may be implicitly induced by a library variable)},
  evaluation of $e$ is equivalent to evaluation of an invocation of
  the library getter \id{}
  (\ref{topLevelGetterInvocation}).
\item
  % We could say 'getter induced by a constant variable'; but there will always
  % be a variable because a getter declaration cannot yield a constant, so we
  % use the shortcut and omit mentioning the getter entirely here.
  If $D$ is a library, class, or local constant variable of one of the forms
  \code{\CONST{} $v$ = $e'$;} or \code{\CONST{} $T$ $v$ = $e'$;}
  then the value of $e$ is the value of the constant expression $e'$.
\item
  If $D$ is a declaration of
  a top-level function, static method, or local function,
  then $e$ evaluates to the function object obtained by closurization
  (\ref{functionClosurization})
  of $D$.
\item
  If $D$ is an instance getter declaration in an extension declaration $E$,
  then $e$ evaluates to the result of invoking said getter
  with the current binding of \THIS, and
  the current bindings of the type parameters declared by $D$.
\item
  If $D$ is an instance method declaration in an extension declaration $E$
  with type parameters \List{X}{1}{s},
  then $e$ evaluates to the result of the extension method closurization
  \code{$E$<\List{X}{1}{s}>(\THIS).\id}
  (\ref{extensionMethodClosurization}).
\item
  If $D$ is a local variable $v$
  \commentary{(which can be a formal parameter)}
  then $e$ evaluates to the current binding of $v$.
\end{itemize}

\commentary{%
  Note that $D$ cannot be the declaration of
  a static variable, static getter or static setter declared in a class $C$,
  because in that case $e$ is treated as
  (\ref{notation})
  the property extraction
  (\ref{propertyExtraction})
  \code{$C$.\id},
  which also determines the evaluation of $e$.%
}
\EndCase

\LMHash{}%
\Case{Lexical lookup yields an import prefix}
This situation cannot arise,
because it is a compile-time error
to evaluate an import prefix as an expression,
and no constructs involving an import prefix
\commentary{(e.g., such as a property extraction \code{$p$.$m$})}
will evaluate the import prefix.
\EndCase

\LMHash{}%
\Case{Lexical lookup yields nothing}
This situation cannot arise,
because this only occurs when $e$ is treated as
\code{\THIS.\id},
whose evaluation is specified elsewhere
(\ref{propertyExtraction}).
\EndCase


\subsection{Type Test}
\LMLabel{typeTest}

\LMHash{}%
The \Index{is-expression} tests if an object is a member of a type.

\begin{grammar}
<typeTest> ::= <isOperator> <typeNotVoid>

<isOperator> ::= \IS{} `!'?
\end{grammar}

\LMHash{}%
Evaluation of the is-expression \code{$e$ \IS{} $T$} proceeds as follows:

\LMHash{}%
The expression $e$ is evaluated to an object $v$.
If the dynamic type of $v$ is a subtype of $T$,
the is-expression evaluates to \TRUE.
Otherwise it evaluates to \FALSE.

\commentary{%
  It follows that \code{$e$ \IS{} Object} is always true.
  This makes sense in a language where everything is an object.

  Also note that \code{\NULL{} \IS{} $T$} is false
  unless $T = \code{Object}$, $T = \code{\DYNAMIC}$ or $T = \code{Null}$.
  The former two are useless, as is anything
  of the form \code{$e$ \IS{} Object} or \code{$e$ \IS{} \DYNAMIC}.
  Users should test for the null object (\ref{null}) directly
  rather than via type tests.%
}

\LMHash{}%
The is-expression \code{$e$ \IS{}! $T$} is equivalent to
\code{!($e$ \IS{} $T$)}.

\LMHash{}%
Let $v$ be a local variable
\commentary{(which can be a formal parameter)}.
An is-expression of the form \code{$v$ \IS{} $T$}
shows that $v$ has type $T$
if $T$ is a subtype of the type of the expression $v$.
%
Otherwise,
if the declared type of $v$ is the type variable $X$,
and $T$ is a subtype of the bound of $X$,
and $X \& T$ is a subtype of the type of the expression $v$,
then $e$ shows that $v$ has type $X \& T$.
%
Otherwise $e$ does not show that $v$ has type $T$ for any $T$.

\rationale{%
  The motivation for the ``shows that v has type T'' relation is
  to reduce spurious errors thereby enabling a more natural coding style.
  The rules in the current specification are deliberately kept simple.
  It would be upwardly compatible to refine these rules in the future;
  such a refinement would accept more code without errors,
  but not reject any code now error-free.

  The rule only applies to locals and parameters,
  as non-local variables could be modified
  via side-effecting functions or methods that are not accessible
  to a local analysis.

  It is pointless to deduce a weaker type than what is already known.
  Furthermore, this would lead to a situation where multiple types are
  associated with a variable at a given point,
  which complicates the specification.
  Hence the requirement that the promoted type is a subtype of the current type.

  In any case, it is not an error when a type test does not show
  that a given variable does not have a ``better'' type than previously known,
  but tools may choose to give a hint in such cases,
  if suitable heuristics indicate that a promotion is likely to be intended.%
}

\LMHash{}%
The static type of an is-expression is \code{bool}.


\subsection{Type Cast}
\LMLabel{typeCast}

\LMHash{}%
The \Index{cast expression} ensures that an object is a member of a type.

\begin{grammar}
<typeCast> ::= <asOperator> <typeNotVoid>

<asOperator> ::= \AS{}
\end{grammar}

\LMHash{}%
 Evaluation of the cast expression \code{$e$ \AS{} $T$} proceeds as follows:

\LMHash{}%
The expression $e$ is evaluated to an object $v$.
% This error can occur, by design of `as`.
It is a dynamic type error if $o$ is not the null object (\ref{null}),
and the dynamic type of $o$ is not a subtype of $T$.
Otherwise $e$ evaluates to $v$.

\LMHash{}%
The static type of a cast expression \code{$e$ \AS{} $T$} is $T$.


\section{Statements}
\LMLabel{statements}

\LMHash{}%
A \Index{statement} is a fragment of Dart code that can be executed at run time.
Statements, unlike expressions, do not evaluate to an object,
but are instead executed for their effect on the program state and control flow.

\begin{grammar}
<statements> ::= <statement>*

<statement> ::= <label>* <nonLabelledStatement>

<nonLabelledStatement> ::= <block>
  \alt <localVariableDeclaration>
  \alt <forStatement>
  \alt <whileStatement>
  \alt <doStatement>
  \alt <switchStatement>
  \alt <ifStatement>
  \alt <rethrowStatement>
  \alt <tryStatement>
  \alt <breakStatement>
  \alt <continueStatement>
  \alt <returnStatement>
  \alt <yieldStatement>
  \alt <yieldEachStatement>
  \alt <expressionStatement>
  \alt <assertStatement>
  \alt <localFunctionDeclaration>
\end{grammar}


\subsubsection{Statement Completion}
\LMLabel{statementCompletion}

\LMHash{}%
Execution of a statement \IndexCustom{completes}{completion}
in one of five ways:
either it
\IndexCustom{completes normally}{completion!normally},
it \IndexCustom{breaks}{completion!breaks}
or it \IndexCustom{continues}{completion!continues}
(either to a label or without a label),
it \IndexCustom{returns}{completion!returns} (with or without an object),
or it \IndexCustom{throws}{completion!throws}
an exception object and an associated stack trace.

\LMHash{}%
In descriptions of statement execution the default is that
the execution completes normally unless otherwise stated.

\LMHash{}%
If the execution of a statement, $s$,
is defined in terms of executing another statement,
and the execution of that other statement does not complete normally,
then, unless otherwise stated, the execution of $s$ stops
at that point and completes in the same way.
\commentary{%
  For example, if execution of the body of a \DO{} loop returns an object,
  so does execution of the \DO{} loop statement itself.%
}

\LMHash{}%
If the execution of a statement is defined in terms of evaluating an expression
and the evaluation of that expression throws,
then, unless otherwise stated, the execution of the statement stops
at that point and throws the same exception object and stack trace.
\commentary{%
  For example,
  if evaluation of the condition expression of an \IF{} statement throws,
  then so does execution of the \IF{} statement.
  Likewise, if evaluation of the expression of a \RETURN{} statement throws,
  so does execution of the \RETURN{} statement.%
}

%% TODO(eernst): Use proposal from Lasse to add a definition of the concept of
%% a statement for which it is 'statically known that it will not complete
%% normally': Cf. https://github.com/dart-lang/language/issues/139.
%% That definition should probably be located here.


\subsection{Blocks}
\LMLabel{blocks}

\LMHash{}%
A \Index{block statement} supports sequencing of code.

\LMHash{}%
Execution of a block statement $\{s_1, \ldots, s_n\}$ proceeds as follows:

\LMHash{}%
For $i \in 1 .. n, s_i$ is executed.

\LMHash{}%
A block statement introduces a new scope,
whose enclosing scope is the current scope of the block statement.


\subsection{Expression Statements}
\LMLabel{expressionStatements}

\LMHash{}%
An \Index{expression statement} consists of an expression that does not
begin with a \lit{\{} character.

\begin{grammar}
<expressionStatement> ::= <expression>? `;'
\end{grammar}

\LMHash{}%
The expression of an expression statement is not allowed
to begin with a \lit{\{}.
\commentary{%
  This means that if some source text could otherwise be
  parsed as an expression followed by a \lit{;},
  then this grammar production does not apply
  when the expression starts with a \lit{\{}.%
}
\rationale{%
  The restriction resolves an ambiguity while parsing where a
  \lit{\{} can start either a block (\ref{blocks}) or
  a map literal (\ref{maps}).
  By disallowing the latter from starting an expression statement,
  the parser does not need to look further ahead
  before deciding that it is parsing a block statement.%
}

\LMHash{}%
Execution of an expression statement \code{$e$;} proceeds by evaluating $e$.
If the expression evaluates to an object,
then the object is ignored and the execution completes normally.


\subsection{Local Variable Declaration}
\LMLabel{localVariableDeclaration}

\LMHash{}%
A \Index{variable declaration statement},
also known as a \Index{local variable declaration},
has the following form:

\begin{grammar}
<localVariableDeclaration> ::= <metadata> <initializedVariableDeclaration> `;'
\end{grammar}

\LMHash{}%
Each local variable declaration introduces
a \IndexCustom{local variable}{variable!local}
into the current scope.

\commentary{%
  Local variables do not induce getters and setters.
  Note that a formal parameter declaration also introduces
  a local variable into the associated formal parameter scope
  (\ref{formalParameters}).%
}

\LMHash{}%
The properties of being
\IndexCustom{initialized}{variable!initialized} or
\IndexCustom{constant}{variable!constant}
apply to local variables with the same definitions as for other variables
(\ref{variables}).

%% TODO(eernst): May need updates/deletion when flow analysis is integrated.
\LMHash{}%
We say that a local variable $v$ is \Index{potentially mutated}
in some scope $s$
if $v$ is not final, and an assignment to $v$ occurs in $s$.

\LMHash{}%
A local variable declaration of the form \code{\VAR{} $v$;} is equivalent to
\code{\VAR{} $v$ = \NULL;}.
If $T$ is a nullable type
(\ref{typeNullability})
then a local variable declaration of the form \code{$T$ $v$;}
is equivalent to \code{$T$ $v$ = \NULL;}.

%% TODO(eernst): Revise when flow analysis is added.
\commentary{%
  If $T$ is a potentially non-nullable type
  then a local variable declaration of the form \code{$T$ $v$;} is allowed,
  but an expression that gives rise to evaluation of $v$
  is a compile-time error unless flow analysis
  (\ref{flowAnalysis})
  shows that the variable is guaranteed to have been initialized.%
}

\LMHash{}%
A local variable has an associated
\IndexCustom{declared type}{local variable!declared type}
which is determined from its declaration.
A local variable also has an associated
\IndexCustom{type}{local variable!type}
which is determined by flow analysis
(\ref{flowAnalysis})
via a process known as type promotion
(\ref{typePromotion}).

\LMHash{}%
The declared type of a local variable with a declaration of one of the forms
\code{\LATE?\,\,$T$\,\,$v$ = $e$;}
\code{\LATE?\,\,\FINAL\,\,$T$\,\,$v$ = $e$;}
\code{\CONST\,\,$T$\,\,$v$ = $e$;}
is $T$.

\LMHash{}%
The declared type of a local variable with a declaration of one of the forms
\code{\LATE?\,\,\VAR\,\,$v$ = $e$;}
\code{\LATE?\,\,\FINAL\,\,$v$ = $e$;}
\code{\CONST\,\,$v$ = $e$;}
is determined as follows:

\begin{itemize}
\item
  If the static type of $e$ is \code{Null} then
  the declared type of $v$ is \DYNAMIC.
\item
  If the static type of $e$ is of the form \code{$X$\,\&\,$T$}
  where $X$ is a type variable
  (\ref{intersectionTypes}),
  the declared type of $v$ is \code{X}.
  \commentary{%
    In this case $v$ is immediately promoted to \code{$X$\,\&\,$T$}
    (\ref{typePromotion}).%
  }
\item
  Otherwise, the declared type of $v$ is the static type of $e$.
\end{itemize}

\LMHash{}%
Let $v$ be a local variable declared by an initializing variable declaration,
and let $e$ be the associated initializing expression.
It is a
\Error{compile-time error} if the static type of $e$ is not assignable to
the declared type of $v$.

%% TODO(eernst): Revise when flow analysis is added.
\commentary{%
  If a local variable $v$ is \FINAL{} and not \LATE,
  it is not a compile-time error if the declaration of $v$ is
  not an initializing variable declaration,
  but an expression that gives rise to evaluation of $v$
  is a compile-time error unless flow analysis shows that
  the variable is guaranteed to have been initialized.
  Similarly, an expression that gives rise to an assignment to $v$
  is a compile-time error unless flow analysis shows that
  it is guaranteed that the variable has \emph{not} been initialized.%

  In every situation which is not covered by the previous paragraph,
  it is a compile-time error to assign to a local variable
  which is \FINAL{} and not \LATE{}
  (\ref{assignment}).%
}

\LMHash{}%
Assume that $D$ is a local variable declaration with the modifier \LATE{}
that declares a variable $v$,
which has an initializing expression $e$.
It is a \Error{compile-time error} if $e$ contains an \AWAIT{} expression $a$
(\ref{awaitExpressions}),
unless there is a function $f$ which is
the immediately enclosing function for $a$,
and $f$ is not the immediately enclosing function for $D$.

\commentary{%
  In other words,
  the initializing expression cannot await an expression directly,
  any await expressions must be syntactically nested inside some other function,
  that is, a function literal.%
}

\LMHash{}%
It is a \Error{compile-time error} if
a local variable is referenced at a source code location that is before
the end of its initializing expression, if any,
and otherwise before the declaring occurrence of
the identifier which names the variable.

\commentary{%
  The example below illustrates the expected behavior.
  A variable `\code{x}' is declared at the library level,
  and another `\code{x}' is declared inside the function `\code{f}'.%
}

\begin{dartCode}
\VAR{} x = 0;
\\
f(y) \{
  \VAR{} z = x; // \comment{compile-time error}
  if (y) \{
    x = x + 1; // \comment{two compile-time errors}
    print(x); // \comment{compile-time error}
  \}
  \VAR{} x = x++; // \comment{compile-time error}
  print(x);
\}
\end{dartCode}

\commentary{%
  The declaration inside `\code{f}' hides the enclosing one.
  So all references to `\code{x}' inside `\code{f}'
  refer to the inner declaration of `\code{x}'.
  However, many of these references are illegal,
  because they appear before the declaration.
  The assignment to `\code{z}' is one such case.
  The assignment to `\code{x}' in the \IF{} statement
  suffers from multiple problems.
  The right hand side reads `\code{x}' before its declaration,
  and the left hand side assigns to `\code{x}' before its declaration.
  Each of these are, independently, compile-time errors.
  The print statement inside the \IF{} is also illegal.

  The inner declaration of `\code{x}' is itself erroneous
  because its right hand side attempts to
  read `\code{x}' before the declaration has terminated.
  The occurrence of `\code{x}' that declares and names the variable
  (that is, the one to the left of `\code{=}' in the inner declaration)
  is not a reference, and so is legal.
  The last print statement is perfectly legal as well.%
}

\commentary{%
  As another example \code{\VAR{} x = 3, y = x;} is legal,
  because \code{x} is referenced after its initializer.

  A particularly perverse example involves
  a local variable name shadowing a type.
  This is possible because Dart has a
  single namespace for types, functions and variables.%
}

\begin{dartCode}
\CLASS{} C \{\}
perverse() \{
  \VAR{} v = \NEW{} C(); // \comment{compile-time error}
  C aC; // \comment{compile-time error}
  \VAR{} C = 10;
\}
\end{dartCode}

\commentary{%
  Inside \code{perverse()}, `\code{C}' denotes a local variable.
  The type `\code{C}' is hidden by the variable of the same name.
  The attempt to instantiate `\code{C}' causes a compile-time error
  because it references a local variable prior to its declaration.
  Similarly, for the declaration of `\code{aC}'.%
}

\LMHash{}%
Execution of a variable declaration statement of one of the forms
\code{\VAR{} $v$ = $e$;}
\code{$T$ $v$ = $e$;}
\code{\CONST{} $v$ = $e$;}
\code{\CONST{} $T$ $v$ = $e$;}
\code{\FINAL{} $v$ = $e$;} or
\code{\FINAL{} $T$ $v$ = $e$;}
proceeds as follows:

\LMHash{}%
The expression $e$ is evaluated to an object $o$.
% The following error can occur due to implicit casts.
A dynamic type error occurs
if the dynamic type of $o$ is not a subtype of the actual declared type
(\ref{actualTypes})
of $v$.
Otherwise, the variable $v$ is bound to $o$.

\commentary{%
  Note that $e$ could have been transformed due to implicit coercions.
  For example, \code{myFunction} could be transformed into
  \code{myFunction<int>} due to generic function instantiation
  (\ref{genericFunctionInstantiation}).
  Such transformations are assumed to have taken place already
  in the declarations above.%
}

\LMHash{}%
Let $D$ be a \LATE{} and \FINAL{} local variable declaration
that declares a variable $v$.
If an object $o$ is assigned to $v$
in a situation where $v$ is unbound
then $v$ is bound to $o$.
If an object $o$ is assigned to $v$
in a situation where $v$ is bound to an object $o'$
then a dynamic error occurs
\commentary{(it does not matter whether $o$ is the same object as $o'$)}.


\subsection{Local Function Declaration}
\LMLabel{localFunctionDeclaration}

\LMHash{}%
A function declaration statement declares a new local function
(\ref{functionDeclarations}).

\begin{grammar}
<localFunctionDeclaration> ::= <metadata> <functionSignature> <functionBody>
\end{grammar}

\LMHash{}%
A function declaration statement of one of the forms
\code{\id{} \metavar{signature} \{ \metavar{statements} \}}
or
\code{$T$ \id{} \metavar{signature} \{ \metavar{statements} \}}
causes a new function named \id{} to be added to the current scope.
It is a compile-time error to reference a local function before its declaration.

\commentary{%
  This implies that local functions can be directly recursive,
  but not mutually recursive.
  Consider these examples:%
}

\begin{dartCode}
f(x) => x++; // \comment{a top level function}
\\
top() \{ // \comment{another top level function}
  f(3); // \comment{illegal}
  f(x) => x > 0? x*f(x-1): 1; // \comment{recursion is legal}
  g1(x) => h(x, 1); // \comment{error: h is not declared yet}
  h(x, n) => x > 1? h(x-1, n*x): n; // \comment{again, recursion is fine}
  g2(x) => h(x, 1); // \comment{legal}
\\
  p1(x) => q(x,x); // \comment{illegal}
  q1(a, b)$ =>$ a > 0 ? p1(a-1): b; // \comment{fine}
\\
  q2(a, b) => a > 0 ? p2(a-1): b; // \comment{illegal}
  p1(x) => q2(x,x); // \comment{fine}
\}
\end{dartCode}

\commentary{%
  There is no way to write a pair of mutually recursive local functions,
  because one always has to come before the other is declared.
  These cases are quite rare,
  and can always be managed by defining a pair of variables first,
  then assigning them appropriate function literals:%
}

\begin{dartCode}
top2() \{ // \comment{a top level function}
  \VAR{} p, q;
  p = (x) => q(x,x);
  q = (a, b) => a > 0 ? p(a-1): b;
\}
\end{dartCode}

\rationale{%
  The rules for local functions differ slightly from those for local variables
  in that a function can be accessed within its declaration
  but a variable can only be accessed after its declaration.
  This is because recursive functions are useful
  whereas recursively defined variables are almost always errors.
  It therefore makes sense to harmonize the rules for local functions
  with those for functions in general rather than
  with the rules for local variables.%
}


\subsection{If}
\LMLabel{if}

\LMHash{}%
The \Index{if statement} allows for conditional execution of statements.

\begin{grammar}
<ifStatement> ::= \IF{} `(' <expression> `)' <statement> (\ELSE{} <statement>)?
\end{grammar}

\LMHash{}%
An if statement of the form
\code{\IF{} ($e$) $s_1$ \ELSE{} $s_2$}
where $s_1$ is not a block statement is equivalent to the statement
\code{\IF{} ($e$) \{$s_1$\} \ELSE{} $s_2$}.
An if statement of the form
\code{\IF{} ($e$) $s_1$ \ELSE{} $s_2$}
where $s_2$ is not a block statement is equivalent to the statement
\code{\IF{} ($e$) $s_1$ \ELSE{} \{$s_2$\}}.

\rationale{%
  The reason for this equivalence is to catch errors such as%
}

\begin{dartCode}
\VOID{} main() \{
  \IF{} (somePredicate)
    \VAR{} v = 2;
  print(v);
\}
\end{dartCode}

\rationale{%
  Under reasonable scope rules such code is problematic.
  If we assume that \code{v} is declared
  in the scope of the method \code{main()},
  then when \code{somePredicate} is false,
  \code{v} will be uninitialized when accessed.
  The cleanest approach would be to require a block following the test,
  rather than an arbitrary statement.
  However, this goes against long standing custom,
  undermining Dart's goal of familiarity.
  Instead, we choose to insert a block, introducing a scope,
  around the statement following the predicate
  (and similarly for \ELSE{} and loops).
  This will cause a compile-time error in the case above.
  Of course, if there is a declaration of \code{v} in the surrounding scope,
  programmers might still be surprised.
  We expect tools to highlight cases of shadowing
  to help avoid such situations.%
}

\LMHash{}%
Execution of an if statement of the form
\code{\IF{} ($b$) $s_1$ \ELSE{} $s_2$}
where $s_1$ and $s_2$ are block statements,
proceeds as follows:

\LMHash{}%
First, the expression $b$ is evaluated to an object $o$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o$ is not \code{bool}.
If $o$ is \TRUE, then the block statement $s_1$ is executed,
otherwise the block statement $s_2$ is executed.

\LMHash{}%
It is a compile-time error if the type of the expression $b$
may not be assigned to \code{bool}.

\LMHash{}%
If $b$ shows that a local variable $v$ has type $T$,
then the type of $v$ is known to be $T$ in $s_1$,
unless any of the following are true

\begin{itemize}
\item $v$ is potentially mutated in $s_1$,
\item $v$ is potentially mutated within a function other
  than the one where $v$ is declared, or
\item $v$ is accessed by a function defined in $s_1$ and
  $v$ is potentially mutated anywhere in the scope of $v$.
\end{itemize}

\LMHash{}%
An if statement of the form \code{\IF{} ($e$) $s$} is equivalent to
the if statement \code{\IF{} ($e$) $s$ \ELSE{} \{\}}.


\subsection{For}
\LMLabel{for}

\LMHash{}%
The \Index{for statement} supports iteration.

\begin{grammar}
<forStatement> ::= \AWAIT? \FOR{} `(' <forLoopParts> `)' <statement>

<forLoopParts> ::= <forInitializerStatement> <expression>? `;' <expressionList>?
  \alt <forInLoopPrefix> \IN{} <expression>

<forInLoopPrefix> ::= <metadata> <declaredIdentifier>
  \alt <identifier>

<forInitializerStatement> ::= <localVariableDeclaration>
  \alt <expression>? `;'
\end{grammar}

\LMHash{}%
The for statement has three forms - the traditional for loop
and two forms of the for-in statement - synchronous and asynchronous.


\subsubsection{For Loop}
\LMLabel{forLoop}

\LMHash{}%
Execution of a for statement of the form
\code{\FOR{} (\VAR{} $v$ = $e_0$; $c$; $e$) $s$} proceeds as follows:

\LMHash{}%
If $c$ is empty then let $c'$ be \TRUE{} otherwise let $c'$ be $c$.

\LMHash{}%
First the variable declaration statement \VAR{} $v = e_0$ is executed.
Then:

\begin{enumerate}
\item
  \label{beginFor}
  If this is the first iteration of the for loop, let $v'$ be $v$.
  Otherwise, let $v'$ be the variable $v''$ created in
  the previous execution of step \ref{allocateFreshVar}.
\item
  The expression $[v'/v]c$ is evaluated to an object $o$.
  % This error can occur due to implicit casts and null.
  It is a dynamic error if the run-time type of $o$ is not \code{bool}.
  If $o$ is \FALSE, the for loop completes normally.
  Otherwise, execution continues at step \ref{beginIteration}.
\item
  \label{beginIteration}
  The statement $[v'/v]\{s\}$ is executed.

  If this execution completes normally, continues without a label,
  or continues to a label (\ref{labels})
  that prefixes this \FOR{} statement (\ref{statementCompletion}),
  then execution of the statement is treated as if it had completed normally.

  \label{allocateFreshVar}
  Let $v''$ be a fresh variable.
  $v''$ is bound to the value of $v'$.
\item
  The expression $[v''/v]e$ is evaluated, and
  the process recurses at step \ref{beginFor}.
\end{enumerate}

\rationale{%
  The definition above is intended to prevent the common error
  where users create a function object inside a for loop,
  intending to close over the current binding of the loop variable, and find
  (usually after a painful process of debugging and learning)
  that all the created function objects have captured
  the same value---the one current in the last iteration executed.

  Instead, each iteration has its own distinct variable.
  The first iteration uses the variable created by the initial declaration.
  The expression executed at the end of each iteration uses
  a fresh variable $v''$,
  bound to the value of the current iteration variable,
  and then modifies $v''$ as required for the next iteration.%
}

\LMHash{}%
It is a compile-time error if the static type of $c$
may not be assigned to \code{bool}.

%A for statement of the form \code{\FOR{} ($d$ ; $c$; $e$) $s$}
%is equivalent to the following code:

%\code{
%\{$d$;
%\WHILE{} ($c$) \{
%   \{$s$\}
%   $e$;
%\}\}
%}

%If $c$ is empty, it is interpreted as \TRUE.


\subsubsection{For-in}
\LMLabel{for-in}

\LMHash{}%
Let $D$ be derived from \syntax{<finalConstVarOrType>?}.
A for statement of the form \code{\FOR{} ($D$ \id{} \IN{} $e$)\,\,$S$}
is then treated as the following code,
where $\id_1$ and $\id_2$ are fresh identifiers:

\begin{normativeDartCode}
$T$ $\id_1$ = $e$;
\VAR{} $\id_2$ = $id_1$.iterator;
\WHILE{} ($\id_2$.moveNext()) \{
\ \ $D$ \id{} = $\id_2$.current;
\ \ \{ $S$ \}
\}
\end{normativeDartCode}

\LMHash{}%
If the static type of $e$ is a top type
(\ref{superBoundedTypes})
then $T$ is \code{Iterable<\DYNAMIC>},
otherwise $T$ is the static type of $e$.
It is a compile-time error if $T$ is not assignable to
\code{Iterable<\DYNAMIC>}.

\commentary{%
  It follows that it is a compile-time error
  % The following error exists also in the case where \id{} is definitely
  % unassigned before the loop: The loop could run >1 time.
  if $D$ is empty and \id{} is a final variable.
  Also, it is a dynamic error if $e$ has type \DYNAMIC,
  but $e$ evaluates to an instance of a type
  which is not a subtype of \code{Iterable<\DYNAMIC>}.%
}


\subsubsection{Asynchronous For-in}
\LMLabel{asynchronousFor-in}

\LMHash{}%
A for-in statement may be asynchronous.
The asynchronous form is designed to iterate over streams.
An asynchronous for loop is distinguished by
the keyword \AWAIT{} immediately preceding the keyword \FOR.

\LMHash{}%
Let $D$ be derived from \syntax{<finalConstVarOrType>?}.
Execution of a for-in statement, $f$, of the form
\code{\AWAIT{} \FOR{} ($D$ \id{} \IN{} $e$) $s$}
proceeds as follows:

\LMHash{}%
The expression $e$ is evaluated to an object $o$.
% This error can occur due to implicit casts and null.
It is a dynamic type error if $o$ is not an instance of
a class that implements \code{Stream}.
It is a compile-time error if $D$ is empty
and \id{} is a final or constant variable.

\LMHash{}%
The stream associated with the innermost enclosing asynchronous for loop,
if any, is paused.
The stream $o$ is listened to, producing a stream subscription $u$,
and execution of the asynchronous for-in loop is suspended
until a stream event is available.
\commentary{%
  This allows other asynchronous events to execute
  while this loop is waiting for stream events.%
}

Pausing an asynchronous for loop means pausing
the associated stream subscription.
A stream subscription is paused by calling its \code{pause} method.
If the subscription is already paused, an implementation may omit
further calls to \code{pause}.

\commentary{%
  The \code{pause} call can throw, although that should never happen
  for a correctly implemented stream.%
}

\LMHash{}%
For each \Index{data event} from $u$,
the statement $s$ is executed with \id{} bound to
the value of the current data event.

\commentary{%
  Either execution of $s$ is completely synchronous, or it contains an
  asynchronous construct (\AWAIT, \code{\AWAIT\,\,\FOR}, \YIELD, or \YIELD*)
  which will pause the stream subscription of its surrounding asynchronous loop.
  This ensures that no other event of $u$ occurs
  before execution of $s$ is complete,
  if $o$ is a correctly implemented stream.
  If $o$ doesn't act as a valid stream,
  for example by not respecting pause requests,
  the behavior of the asynchronous loop may become unpredictable.%
}

\LMHash{}%
If execution of $s$ continues without a label,
or to a label (\ref{labels})
that prefixes the asynchronous for statement (\ref{statementCompletion}),
then the execution of $s$ is treated as if it had completed normally.

\LMHash{}%
If execution of $s$ otherwise does not complete normally,
the subscription $u$ is canceled by evaluating \code{\AWAIT{} $v$.cancel()}
where $v$ is a fresh variable referencing the stream subscription $u$.
If that evaluation throws,
execution of $f$ throws the same exception and stack trace.
Otherwise execution of $f$ completes in the same way as the execution of $s$.
% Notice: The previous specification was unclear about what happened when
% a subscripton is canceled. This text is explicit, and existing
% implementations may not properly await the cancel call.
Otherwise the execution of $f$ is suspended again, waiting for
the next stream subscription event,
and $u$ is resumed if it has been paused.
\commentary{%
  The \code{resume} call can throw, in which case the asynchronous for
  loop also throws.
  That should never happen for a correctly implemented stream.%
}

\LMHash{}%
On an \Index{error event} from $u$,
with error object $e$ and stack trace $st$,
the subscription $u$ is canceled by evaluating \code{\AWAIT{} v.cancel()}
where $v$ is a fresh variable referencing the stream subscription $u$.
If that evaluation throws,
execution of $f$ throws the same exception object and stack trace.
Otherwise execution of $f$ throws
with $e$ as exception object and $st$ as stack trace.

\LMHash{}%
When $u$ is done, execution of $f$ completes normally.

\LMHash{}%
It is a compile-time error if an asynchronous for-in statement appears
inside a synchronous function (\ref{functions}).
It is a compile-time error if a traditional for loop (\ref{forLoop}) is
prefixed by the \AWAIT{} keyword.

\rationale{%
  An asynchronous loop would make no sense within a synchronous function,
  for the same reasons that an await expression makes no sense
  in a synchronous function.%
}


\subsection{While}
\LMLabel{while}

\LMHash{}%
The while statement supports conditional iteration,
where the condition is evaluated prior to the loop.

\begin{grammar}
<whileStatement> ::= \WHILE{} `(' <expression> `)' <statement>
\end{grammar}

\LMHash{}%
Execution of a while statement of the form \code{\WHILE{} ($e$) $s$;}
proceeds as follows:

\LMHash{}%
The expression $e$ is evaluated to an object $o$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o$ is not \code{bool}.

\LMHash{}%
If $o$ is \FALSE, then execution of the while statement completes normally
(\ref{statementCompletion}).

\LMHash{}%
Otherwise $o$ is \TRUE{} and then the statement $\{s\}$ is executed.
If that execution completes normally or it continues with no label
or to a label (\ref{labels}) that prefixes the \WHILE{} statement
(\ref{statementCompletion}),
then the while statement is re-executed.
If the execution breaks without a label,
execution of the while statement completes normally.
\commentary{%
  If the execution breaks with a label that prefixes the \WHILE{} statement,
  it does end execution of the loop,
  but the break itself is handled by
  the surrounding labeled statement (\ref{labels}).%
}

\LMHash{}%
It is a compile-time error if
the static type of $e$ may not be assigned to \code{bool}.


\subsection{Do}
\LMLabel{do}

\LMHash{}%
The do statement supports conditional iteration,
where the condition is evaluated after the loop.

\begin{grammar}
<doStatement> ::= \DO{} <statement> \WHILE{} `(' <expression> `)' `;'
\end{grammar}

\LMHash{}%
Execution of a do statement of the form \code{\DO{} $s$ \WHILE{} ($e$);}
proceeds as follows:

\LMHash{}%
The statement $\{s\}$ is executed.
If that execution continues with no label,
or to a label (\ref{labels}) that prefixes the do statement
(\ref{statementCompletion}),
then the execution of $s$ is treated as if it had completed normally.

\LMHash{}%
Then, the expression $e$ is evaluated to an object $o$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o$ is not \code{bool}.
If $o$ is \FALSE, execution of the do statement completes normally
(\ref{statementCompletion}).
If $o$ is \TRUE, then the do statement is re-executed.

\LMHash{}%
It is a compile-time error if the static type of $e$
may not be assigned to \code{bool}.


\subsection{Switch}
\LMLabel{switch}

\LMHash{}%
The \Index{switch statement} supports dispatching control among
a large number of cases.

\begin{grammar}
<switchStatement> ::= \gnewline{}
  \SWITCH{} `(' <expression> `)' `{' <switchCase>* <defaultCase>? `}'

<switchCase> ::= <label>* \CASE{} <expression> `:' <statements>

<defaultCase> ::= <label>* \DEFAULT{} `:' <statements>
\end{grammar}

\LMHash{}%
Consider a switch statement of the form

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\ \ $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$
\}
\end{normativeDartCode}

\noindent
or the form

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\}
\end{normativeDartCode}

\commentary{%
  Note that each expression $e_j, j \in 1 .. n$ occurs in a constant context
  (\ref{constantContexts}),
  which means that \CONST{} modifiers need not be specified explicitly.%
}

\LMHash{}%
It is a compile-time error unless each expression
$e_j, j \in 1 .. n$ is constant.
It is a compile-time error if the value of the expressions
$e_j, j \in 1 .. n$ are not either:

\begin{itemize}
\item instances of the same class $C$, for all $j \in 1 .. n$, or
\item instances of a class that implements \code{int},
  for all $j \in 1 .. n$, or
\item instances of a class that implements \code{String},
  for all $j \in 1 .. n$.
\end{itemize}

\commentary{%
  In other words, all the expressions in the cases evaluate to constants of
  the exact same user defined class or are of certain known types.
  %% TODO(eernst): Update when we specify inference: const List<int> xs = [];
  %% may be a counter-example: The value is a list that "knows" it is a
  %% `List<int>` independently of the type annotation, but it wouldn't be a
  %% `List<int>` if that type annotation hadn't been there.
  Note that the values of the expressions are known at compile time,
  and are independent of any type annotations.%
}

\LMHash{}%
It is a compile-time error if one or more of said instances of the class $C$
do not have primitive equality
(\ref{theOperatorEqualsEquals}).

\rationale{%
  The prohibition on user defined equality allows us to
  implement the switch efficiently for user defined types.
  We could formulate matching in terms of identity instead,
  with the same efficiency.
  However, if a type defines an equality operator,
  programmers would presumably find it quite surprising
  if equal objects did not match.%
}

\commentary{%
  The \SWITCH{} statement should only be used in
  very limited situations (e.g., interpreters or scanners).%
}

\LMHash{}%
Execution of a switch statement of the form

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\ \ $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$
\}
\end{normativeDartCode}

\noindent
or the form

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\}
\end{normativeDartCode}

\noindent
proceeds as follows:

\LMHash{}%
The statement \code{\VAR{} \id{} = $e$;} is evaluated,
where \id{} is a fresh variable.
% This error can occur due to implicit casts and standard subsumption.
%% TODO(eernst): But why couldn't $e$ be an instance of a subtype?!
It is a dynamic error if the value of $e$ is
not an instance of the same class as the constants $e_1, \ldots, e_n$.

\commentary{%
  Note that if there are no case clauses ($n = 0$),
  the type of $e$ does not matter.%
}

\LMHash{}%
Next, the case clause \CASE{} $e_{1}$: $s_{1}$ is matched against \id,
if $n > 0$.
Otherwise if there is a \DEFAULT{} clause,
the case statements $s_{n+1}$ are executed (\ref{case-execute}).

\LMHash{}%
Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\ \ $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$
\}
\end{normativeDartCode}

\noindent
against the value of a variable \id{} proceeds as follows:

\LMHash{}%
The expression \code{$e_k$ == \id} is evaluated to an object $o$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o$ is not \code{bool}.
If $o$ is \FALSE{} the following case,
\CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$,
and if $k = n$, then the \DEFAULT{} clause's statements are executed
(\ref{case-execute}).
If $o$ is \TRUE, let $h$ be the smallest number
such that $h \ge k$ and $s_h$ is non-empty.
If no such $h$ exists, let $h = n + 1$.
The case statements $s_h$ are then executed (\ref{case-execute}).

\LMHash{}%
Matching of a \CASE{} clause \CASE{} $e_{k}: s_{k}$ of a switch statement

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\}
\end{normativeDartCode}

\noindent
against the value of a variable \id{} proceeds as follows:

\LMHash{}%
The expression \code{$e_k$ == \id} is evaluated to an object $o$.
% This error can occur due to implicit casts and null.
It is a dynamic error if the run-time type of $o$ is not \code{bool}.
If $o$ is \FALSE{} the following case,
\CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$.
If $o$ is \TRUE, let $h$ be the smallest integer
such that $h \ge k$ and $s_h$ is non-empty.
If such a $h$ exists, the case statements $s_h$ are executed
(\ref{case-execute}).
Otherwise the switch statement completes normally
(\ref{statementCompletion}).

\LMHash{}%
It is a compile-time error if the type of $e$
may not be assigned to the type of $e_k$.
Let $s$ be the last statement of the statement sequence $s_k$.
If $s$ is a non-empty block statement, let $s$ instead be
the last statement of the block statement.
It is a compile-time error if $s$ is not
a \BREAK, \CONTINUE, \RETHROW, or \RETURN{} statement,
or an expression statement where the expression is a \THROW{} expression.

\rationale{%
  The behavior of switch cases intentionally differs from the C tradition.
  Implicit fall through is a known cause of programming errors
  and therefore disallowed.
  Why not simply break the flow implicitly at the end of every case,
  rather than requiring explicit code to do so?
  This would indeed be cleaner.
  It would also be cleaner to insist that each case have
  a single (possibly compound) statement.
  We have chosen not to do so in order to
  facilitate porting of switch statements from other languages.
  Implicitly breaking the control flow at the end of a case would silently
  alter the meaning of ported code that relied on fall-through,
  potentially forcing the programmer to deal with subtle bugs.
  Our design ensures that the difference is immediately brought to
  the coder's attention.
  The programmer will be notified at compile time if they forget to end a case
  with a statement that terminates the straight-line control flow.

  The sophistication of the analysis of fall-through is another issue.
  For now, we have opted for a very straightforward syntactic requirement.
  There are obviously situations where code does not fall through,
  and yet does not conform to these simple rules, e.g.:%
}

\begin{dartCode}
\SWITCH{} (x) \{
  \CASE{} 1: \TRY{} \{ $\ldots$ \RETURN; \} \FINALLY{} \{ $\ldots$ \RETURN; \}
\}
\end{dartCode}

\rationale{%
  Very elaborate code in a case clause is probably bad style in any case,
  and such code can always be refactored.%
}

\LMHash{}%
It is a static warning if all of the following conditions hold:

\begin{itemize}
\item The switch statement does not have a default clause.
\item The static type of $e$ is an enumerated
  type with elements $\id_1, \ldots, \id_n$.
\item The sets $\{e_1, \ldots, e_k\} $ and $\{\id_1, \ldots, \id_n\}$
  are not the same.
\end{itemize}

\commentary{%
  In other words, a static warning will be emitted
  if a switch statement over an enum is not exhaustive.%
}


\subsubsection{Switch case statements}
\LMLabel{case-execute}

\LMHash{}%
Execution of the case statements $s_h$ of a switch statement

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\}
\end{normativeDartCode}

\noindent
or a switch statement

\begin{normativeDartCode}
\SWITCH{} ($e$) \{
\ \ $label_{11} \ldots label_{1j_1}$ \CASE{} $e_1: s_1$
\ \ $\ldots$
\ \ $label_{n1} \ldots label_{nj_n}$ \CASE{} $e_n: s_n$
\ \ $label_{(n+1)1} \ldots label_{(n+1)j_{n+1}}$ \DEFAULT{}: $s_{n+1}$
\}
\end{normativeDartCode}

\noindent
proceeds as follows:

\LMHash{}%
Execute $\{s_h\}$.
If this execution completes normally,
and if $s_h$ is not the statements of the last case of the switch
($h = n$ if there is no \DEFAULT{} clause,
$h = n+1$ if there is a \DEFAULT{} clause),
then the execution of the switch case throws an error.
Otherwise $s_h$ are the last statements of the switch case,
and execution of the switch case completes normally.

\commentary{%
  In other words, there is no implicit fall-through between non-empty cases.
  The last case in a switch (default or otherwise) can `fall-through'
  to the end of the statement.%
}

If execution of $\{s_h\}$ breaks with no label (\ref{statementCompletion}),
then the execution of the switch statement completes normally.

If execution of $\{s_h\}$ continues to a label
(\ref{statementCompletion}),
and the label is $label_{ij}$,
where $1 \le i \le n+1$ if the \SWITCH{} statement has a \DEFAULT,
or $1 \le i \le n$ if there is no \DEFAULT,
and where $1 \le j \le j_{i}$,
then let $h$ be the smallest number such that $h \ge i$ and $s_h$ is non-empty.
If no such $h$ exists,
let $h = n + 1$ if the \SWITCH{} statement has a \DEFAULT,
otherwise let $h = n$.
The case statements $s_h$ are then executed (\ref{case-execute}).

If execution of $\{s_h\}$ completes in any other way,
execution of the \SWITCH{} statement completes in the same way.


\subsection{Rethrow}
\LMLabel{rethrow}

\LMHash{}%
The \Index{rethrow statement} is used to
re-throw an exception and its associated stack trace.

\begin{grammar}
<rethrowStatement> ::= \RETHROW{} `;'
\end{grammar}

\LMHash{}%
Consider a \RETHROW{} statement $S$.
% $f$ as defined below is guaranteed to exist: Every statement occurs in
% a <block> (a statement may be part of another statement $S_2$, but by
% induction hypothesis $S_2$ occurs in a <block>), and a <block> can only
% occur as a statement or in a statement (e.g., in a <finallyPart>), and this
% induction can only end in a <functionBody>.
Let $f$ be the immediately enclosing function of $S$.
A compile-time error occurs unless $S$ is located in an \ON-\CATCH{} clause
whose immediately enclosing function is $f$.

\LMHash{}%
Execution of a \code{\RETHROW} statement proceeds as follows:

\LMHash{}%
Let $f$ be the immediately enclosing function,
and let \code{\ON\,\,$T$\,\,\CATCH\,\,($p_1$,\,\,$p_2$)}
be the immediately enclosing catch clause (\ref{try}).

\rationale{%
  A \RETHROW{} statement always appears inside a \CATCH{} clause,
  and every \CATCH{} clause is treated as some \CATCH{} clause of the form
  \code{\ON\,\,$T$\,\,\CATCH\,\,(p1,\,\,p2)}.
  So we can consider the \RETHROW{} statement to be enclosed in
  a \CATCH{} clause of that form.%
}

\LMHash{}%
The \RETHROW{} statement then throws (\ref{statementCompletion})
with the value of $p_1$ as the exception object,
and the value of $p_2$ as the stack trace.


\subsection{Try}
\LMLabel{try}

\LMHash{}%
The try statement supports the definition of exception handling code
in a structured way.

\begin{grammar}
<tryStatement> ::= \TRY{} <block> (<onPart>+ <finallyPart>? | <finallyPart>)

<onPart> ::= <catchPart> <block>
  \alt \ON{} <typeNotVoid> <catchPart>? <block>

<catchPart> ::= \CATCH{} `(' <identifier> (`,' <identifier>)? `)'

<finallyPart> ::= \FINALLY{} <block>
\end{grammar}

\LMHash{}%
A try statement consists of a block statement, followed by at least one of:

\begin{enumerate}
\item
  A set of \ON{}-\CATCH{} clauses, each of which specifies
  (either explicitly or implicitly)
  the type of exception object to be handled,
  one or two exception parameters,
  and a block statement.
\item
A \FINALLY{} clause, which consists of a block statement.
\end{enumerate}

\rationale{%
  The syntax is designed to be upward compatible with
  existing Javascript programs.
  The \ON{} clause can be omitted,
  leaving what looks like a Javascript catch clause.%
}

\LMHash{}%
A try statement of the form
\code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$;}
is equivalent to the statement
\code{\TRY{} $s_1$ $on-catch_1 \ldots on-catch_n$ \FINALLY{} $\{\}$}.

\LMHash{}%
An \ON{}-\CATCH{} clause of the form
\code{\ON{} $T$ \CATCH{} ($p_1$) $s$}
is equivalent to an \ON{}-\CATCH{} clause
\code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$}
where $p_2$ is a fresh identifier.

\LMHash{}%
An \ON{}-\CATCH{} clause of the form
\code{\ON{} $T$ $s$}
is equivalent to an \ON{}-\CATCH{} clause
\code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$}
where $p_1$ and $p_2$ are fresh identifiers.

\LMHash{}%
An \ON{}-\CATCH{} clause of the form
\code{\CATCH{} ($p$) $s$}
is equivalent to an \ON{}-\CATCH{} clause
\code{\ON{} \DYNAMIC{} \CATCH{} ($p$, $p_2$) $s$}
where $p_2$ is a fresh identifier.

An \ON{}-\CATCH{} clause of the form
\code{\CATCH{} ($p_1$, $p_2$) $s$}
is equivalent to an \ON{}-\CATCH{} clause
\code{\ON{} \DYNAMIC{} \CATCH{} ($p_1$, $p_2$) $s$}.

\LMHash{}%
An \ON{}-\CATCH{} clause of the form
\code{\ON{} $T$ \CATCH{} ($p_1$, $p_2$) $s$}
introduces a new scope $CS$ in which final local variables
specified by $p_1$ and $p_2$ are defined.
The statement $s$ is enclosed within $CS$.
The static type of $p_1$ is $T$
and the static type of $p_2$ is \code{StackTrace}.

\LMHash{}%
Execution of a \TRY{} statement $s$ of the form:

\begin{normativeDartCode}
\TRY{} $b$
\ON{} $T_1$ \CATCH{} ($e_1$, $t_1$) $c_1$
\ldots{}
\ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) $c_n$
\FINALLY{} $f$
\end{normativeDartCode}

\noindent
proceeds as follows:

\LMHash{}%
First $b$ is executed.
If execution of $b$ throws (\ref{statementCompletion})
with exception object $e$ and stack trace $t$,
then $e$ and $t$ are matched against the \ON{}-\CATCH{} clauses
to yield a new completion (\ref{on-catch}).

Then, even if execution of $b$ did not complete normally
or matching against the \ON{}-\CATCH{} clauses did not complete normally,
the $f$ block is executed.

If execution of $f$ does not complete normally,
execution of the \TRY{} statement completes in the same way.
Otherwise if execution of $b$ threw (\ref{statementCompletion}),
the \TRY{} statement completes in the same way as
the matching against the \ON{}-\CATCH{} clauses.
Otherwise the \TRY{} statement completes in the same way as
the execution of $b$.

\LMHash{}%
It is a compile-time error if $T_i$, $1 \le i \le n$ is a deferred type.


\subsubsection{\ON{}-\CATCH{} clauses}
\LMLabel{on-catch}

\LMHash{}%
Matching an exception object $e$ and stack trace $t$ against
a (potentially empty) sequence of \ON{}-\CATCH{} clauses of the form

\begin{normativeDartCode}
\ON{} $T_1$ \CATCH{} ($e_1$, $st_1$) \{ $s_1$ \}
\ldots
\ON{} $T_n$ \CATCH{} ($e_n$, $st_n$) \{ $s_n$ \}
\end{normativeDartCode}
proceeds as follows:

\LMHash{}%
If there are no \ON{}-\CATCH{} clauses ($n = 0$), matching throws
the exception object $e$ and stack trace $t$
(\ref{statementCompletion}).

\LMHash{}%
Otherwise the exception is matched against the first clause.

\LMHash{}%
Otherwise, if the type of $e$ is a subtype of $T_1$,
then the first clause matches,
and then $e_1$ is bound to the exception object $e$
and $t_1$ is bound to the stack trace $t$,
and $s_1$ is executed in this scope.
The matching completes in the same way as this execution.

\LMHash{}%
Otherwise, if the first clause did not match $e$,
$e$ and $t$ are recursively matched against
the remaining \ON{}-\CATCH{} clauses:

\begin{normativeDartCode}
\ON{} $T_2$ \CATCH{} ($e_2$, $t_2$) \{ $s_2$ \}
\ldots
\ON{} $T_n$ \CATCH{} ($e_n$, $t_n$) \{ $s_n$ \}
\end{normativeDartCode}


\subsection{Return}
\LMLabel{return}

\LMHash{}%
The \Index{return statement}
returns a result to the caller of a synchronous function,
completes the future associated with an asynchronous function,
or terminates the stream or iterable associated with a generator
(\ref{functions}).

\begin{grammar}
<returnStatement> ::= \RETURN{} <expression>? `;'
\end{grammar}

\LMHash{}%
Consider a return statement $s$ of the form \code{\RETURN{} $e$?;}.
Let $S$ be the static type of $e$, if $e$ is present,
let $f$ be the immediately enclosing function,
and let $T$ be the declared return type of $f$.

\LMHash{}%
\Case{Synchronous non-generator functions}
Consider the case where $f$ is a synchronous non-generator function
(\ref{functions}).
%
% Returning without an object is only ok for "voidy" return types.
It is a compile-time error if $s$ is \code{\RETURN;},
unless $T$ is \VOID, \DYNAMIC, or \code{Null}.
%
% Returning with an object in a void function
% is only ok when the return type "voidy".
It is a compile-time error if $s$ is \code{\RETURN{} $e$;},
$T$ is \VOID,
and $S$ is neither \VOID, \DYNAMIC, nor \code{Null}.
%
% Returning void in a "non-voidy" function is an error.
It is a compile-time error if $s$ is \code{\RETURN{} $e$;},
$T$ is neither \VOID, \DYNAMIC, nor \code{Null},
and $S$ is \VOID.
%
% Otherwise, returning an unassignable value is an error.
It is a compile-time error if $s$ is \code{\RETURN{} $e$;},
$S$ is not \VOID,
and $S$ is not assignable to $T$.

\commentary{%
  Note that $T$ cannot be \VOID, \DYNAMIC, or \code{Null} in the last case,
  because all types are assignable to those types.
  An error will not be raised if $f$ has no declared return type,
  since the return type would be \DYNAMIC, to which every type is assignable.
  However, a synchronous non-generator function
  that declares a return type which is not ``voidy''
  must return an expression explicitly.%
}
\rationale{%
  This helps catch situations where users forget
  to return an object in a return statement.%
}
\EndCase

\LMHash{}%
\Case{Asynchronous non-generator functions}
Consider the case where $f$ is an asynchronous non-generator function
(\ref{functions}).
%
% Returning without an object is only ok for async-"voidy" return types.
It is a compile-time error if $s$ is \code{\RETURN;},
unless \flatten{T}
(\ref{functionExpressions})
is \VOID, \DYNAMIC, or \code{Null}.
%
\rationale{%
  An asynchronous non-generator always returns a future of some sort.
  If no expression is given, the future will be completed with the null object
  (\ref{null})
  which motivates this rule.%
}
% Returning with an object in an void async function only ok
% when that value is async-"voidy".
It is a compile-time error if $s$ is \code{\RETURN{} $e$;},
\flatten{T} is \VOID,
and \flatten{S} is neither \VOID, \DYNAMIC, nor \code{Null}.
%
% Returning async-void in a "non-async-voidy" function is an error.
It is a compile-time error if $s$ is \code{\RETURN{} $e$;},
\flatten{T} is neither \VOID, \DYNAMIC, nor \code{Null},
and \flatten{S} is \VOID.
%
% Otherwise, returning an un-deasync-assignable value is an error.
It is a compile-time error if $s$ is \code{\RETURN{} $e$;},
\flatten{S} is not \VOID,
and \code{Future<\flatten{S}>} is not assignable to $T$.

\commentary{%
  Note that \flatten{T} cannot be \VOID, \DYNAMIC, or \code{Null}
  in the last case,
  because then \code{Future<$U$>} is assignable to $T$ for \emph{all} $U$.
  In particular, when $T$ is \code{FutureOr<Null>}
  (which is equivalent to \code{Future<Null>}),
  \code{Future<\flatten{S}>} is assignable to $T$ for all $S$.
  This means that no compile-time error is raised,
  but \emph{only} the null object (\ref{null})
  or an instance of \code{Future<Null>}
  can successfully be returned at run time.
  This is not an anomaly,
  it corresponds to the treatment of a synchronous function
  with return type \code{Null};
  but tools may choose to give a hint that a downcast is unlikely to succeed.

  An error will not be raised if $f$ has no declared return type,
  since the return type would be \DYNAMIC,
  and \code{Future<\flatten{S}>} is assignable to \DYNAMIC{} for all $S$.
  However, an asynchronous non-generator function
  that declares a return type which is not ``voidy''
  must return an expression explicitly.%
}
\rationale{%
  This helps catch situations where users forget
  to return an object in a return statement of an asynchronous function.%
}
\EndCase

\LMHash{}%
\Case{Generator functions}
It is a compile-time error if a return statement of
the form \code{\RETURN{} $e$;} appears in a generator function.

\rationale{%
  In the case of a generator function, the object returned by the function is
  the iterable or stream associated with it,
  and individual elements are added to that iterable using yield statements,
  and so returning an object makes no sense.%
}
\EndCase

\LMHash{}%
\Case{Generative constructors}
It is a compile-time error if a return statement of
the form \code{\RETURN{} $e$;} appears in a generative constructor
(\ref{generativeConstructors}).

\rationale{%
  It is quite easy to forget to add the \FACTORY{} modifier for a constructor,
  accidentally converting a factory into a generative constructor.
  The static checker may detect a type mismatch
  in some, but not all, of these cases.
  The rule above helps catch such errors,
  which can otherwise be very hard to recognize.
  There is no real downside to it,
  as returning an object from a generative constructor is meaningless.%
}
\EndCase

\LMHash{}%
Executing a return statement \code{\RETURN{} $e$;} proceeds as follows:

\LMHash{}%
First the expression $e$ is evaluated, producing an object $o$.
Let $S$ be the run-time type of $o$ and
let $T$ be the actual return type of $f$
(\ref{actualTypes}).
If the body of $f$ is marked \ASYNC{} (\ref{functions})
and $S$ is a subtype of \code{Future<\flatten{T}>}
then let $r$ be the result of evaluating \code{await $v$}
where $v$ is a fresh variable bound to $o$.
Otherwise let $r$ be $o$.
Then the return statement returns the object $r$
(\ref{statementCompletion}).

%% TODO(eernst): We have some special cases with the dynamic semantics
%% specified above that we may wish to consider:
%%
%% Future<int> foo() async {
%%   return new Future<Object>.value(42);
%% }
%%
%% Statically we will allow this because `Future<flatten(Future<Object>)>`,
%% i.e., `Future<Object>`, is assignable to `Future<int>`. But at run time
%% we get an error because `Future<Object>` is is not a subtype of
%% `Future<flatten(Future<int>)>` = `Future<int>`. We could have awaited
%% the value just because we're about to return a `Future`, and it would
%% then have succeeded. Are we doing the right thing? Might be fine, but
%% it seems surprising that the compiler will sometimes insert `await`,
%% and here we have to do it explicitly in order to succeed.
%%
%% Object /* or dynamic, etc. */ foo() async {
%%   Object o;
%%   if (someCondition) o = 42; else o = new Future<S>.value(42);
%%   return o;
%% }
%%
%% Here we will interject an `await` on the returned value whenever
%% we return a future (for all `S`). This means that we will `await o`
%% in some situations and not in others. It may surprise developers
%% that we can have this dynamic variation at a location in the code
%% where there is no static justification for expecting a future.

\LMHash{}%
Let $U$ be the run-time type of $r$.

\begin{itemize}
\item
  If the body of $f$ is marked \ASYNC{} (\ref{functions})
  % This error can occur due to implicit casts.
  it is a dynamic type error if \code{Future<$U$>} is not a subtype of $T$.
\item
  % This error can occur due to implicit casts.
  Otherwise, it is a dynamic type error if $U$ is not a subtype of $T$.
\end{itemize}

\LMHash{}%
Executing a return statement with no expression,
\code{\RETURN;}
returns without an object
(\ref{statementCompletion}).


\subsection{Labels}
\LMLabel{labels}

\LMHash{}%
A \Index{label} is an identifier followed by a colon.
A \Index{labeled statement} is a statement prefixed by a label $L$.
A \Index{labeled case clause} is a case clause within a switch statement
(\ref{switch})
prefixed by a label $L$.

\rationale{%
  The sole role of labels is to provide targets for
  the break (\ref{break}) and continue (\ref{continue}) statements.%
}

\begin{grammar}
<label> ::= <identifier> `:'
\end{grammar}

\LMHash{}%
Execution a labeled statement $s$, $label: s_l$, consists of executing $s_l$.
If execution of $s_l$ breaks to the label $label$ (\ref{statementCompletion}),
then execution of $s$ completes normally,
otherwise execution of $s$ completes in the same ways as the execution of $s_l$.

\LMHash{}%
The namespace of labels is distinct from the one used for
types, functions and variables.

\LMHash{}%
The scope of a label that labels a statement $s$ is $s$.
The scope of a label that labels a case clause of a switch statement $s$ is $s$.

\rationale{%
  Labels should be avoided by programmers at all costs.
  The motivation for including labels in the language
  is primarily making Dart a better target for code generation.%
}


\subsection{Break}
\LMLabel{break}

\LMHash{}%
The \Index{break statement} consists of
the reserved word \BREAK{} and an optional label (\ref{labels}).

\begin{grammar}
<breakStatement> ::= \BREAK{} <identifier>? `;'
\end{grammar}

\LMHash{}%
Let $s_b$ be a \BREAK{} statement.
If $s_b$ is of the form \code{\BREAK{} $L$;},
then it is a compile-time error if $s_b$ is not enclosed in a labeled statement
with the label $L$ within the innermost function in which $s_b$ occurs.
If $s_b$ is of the form \code{\BREAK;},
then it is a compile-time error if $s_b$ is not enclosed in an
\code{\AWAIT{} \FOR} (\ref{asynchronousFor-in}),
\DO{} (\ref{do}), \FOR{} (\ref{for}), \SWITCH{} (\ref{switch})
or \WHILE{} (\ref{while}) statement within
the innermost function in which $s_b$ occurs.

\LMHash{}%
Execution of a \BREAK{} statement \code{\BREAK{} $L$;} breaks to the label $L$
(\ref{statementCompletion}).
Execution of a \BREAK{} statement \code{\BREAK;} breaks without a label
(\ref{statementCompletion}).


\subsection{Continue}
\LMLabel{continue}

\LMHash{}%
The \Index{continue statement} consists of the reserved word \CONTINUE{}
and an optional label (\ref{labels}).

\begin{grammar}
<continueStatement> ::= \CONTINUE{} <identifier>? `;'
\end{grammar}

\LMHash{}%
Let $s_c$ be a \CONTINUE{} statement.
If $s_c$ is of the form \code{\CONTINUE{} $L$;},
then it is a compile-time error if $s_c$ is not enclosed in either an
\code{\AWAIT{} \FOR} (\ref{asynchronousFor-in}),
\DO{} (\ref{do}), \FOR{} (\ref{for}), or \WHILE{} (\ref{while})
statement labeled with $L$, or in a \SWITCH{} statement with a case clause
labeled with $L$, within the innermost function in which $s_c$ occurs.
If $s_c$ is of the form \code{\CONTINUE;}
then it is a compile-time error if $s_c$ is not enclosed in an
\code{\AWAIT{} \FOR} (\ref{asynchronousFor-in})
\DO{} (\ref{do}), \FOR{} (\ref{for}), or \WHILE{} (\ref{while}) statement
within the innermost function in which $s_c$ occurs.

\LMHash{}%
Execution of a \CONTINUE{} statement \code{\CONTINUE{} $L$;} continues
to the label $L$ (\ref{statementCompletion}).
Execution of a \CONTINUE{} statement \code{\CONTINUE;} continues
without a label (\ref{statementCompletion}).


\subsection{Yield}
\LMLabel{yield}

\LMHash{}%
The \Index{yield statement} adds an object to
the result of a generator function
(\ref{functions}).

\begin{grammar}
<yieldStatement> ::= \YIELD{} <expression> `;'
\end{grammar}

\LMHash{}%
Let $s$ be a yield statement of the form \code{\YIELD\,\,$e$;}.
Let $f$ be the immediately enclosing function of $s$.
It is a compile-time error if there is no such function,
or it is not a generator.
It is a compile-time error if the static type of $e$
may not be assigned to the element type of $f$
(\ref{functions}).

\LMHash{}%
Execution of a statement $s$ of the form \code{\YIELD\,\,$e$;}
proceeds as follows:

\LMHash{}%
First, the expression $e$ is evaluated to an object $o$.
If the enclosing function $m$ is marked \code{\ASYNC*}
(\ref{functions})
and the stream $u$ associated with $m$ has been paused,
then the nearest enclosing asynchronous for loop
(\ref{asynchronousFor-in}),
if any, is paused and execution of $m$ is suspended
until $u$ is resumed or canceled.

\LMHash{}%
Next, $o$ is added to the iterable or stream associated
with the immediately enclosing function.

\commentary{%
  Note that a dynamic error occurs if the dynamic type of $o$
  is not a subtype of the element type of said iterable or stream.%
}

\LMHash{}%
If the enclosing function $m$ is marked \code{\ASYNC*}
and the stream $u$ associated with $m$ has been canceled,
then the \YIELD{} statement returns without an object
(\ref{statementCompletion}),
otherwise it completes normally.

\rationale{%
  The stream associated with an asynchronous generator could be canceled
  by any code with a reference to that stream at any point
  where the generator was passivated.
  Such a cancellation constitutes an irretrievable error for the generator.
  At this point, the only plausible action for the generator is
  to clean up after itself via its \FINALLY{} clauses.%
}

\LMHash{}%
Otherwise, if the enclosing function $m$ is marked \code{\ASYNC*}
(\ref{functions})
then the enclosing function may suspend,
in which case the nearest enclosing asynchronous for loop
(\ref{asynchronousFor-in}),
if any, is paused first.

\rationale{%
  If a \YIELD{} occurred inside an infinite loop
  and the enclosing function never suspended,
  there might not be an opportunity for consumers of the enclosing stream
  to run and access the data in the stream.
  The stream might then accumulate an unbounded number of elements.
  Such a situation is untenable.
  Therefore, we allow the enclosing function to be suspended
  when a new object is added to its associated stream.
  However, it is not essential (and in fact, can be quite costly)
  to suspend the function on every \YIELD.
  The implementation is free to decide
  how often to suspend the enclosing function.
  The only requirement is that consumers are not blocked indefinitely.%
}

\LMHash{}%
If the enclosing function $m$ is marked \code{\SYNC*} (\ref{functions}) then:

\begin{itemize}
\item
  Execution of the function $m$ immediately enclosing $s$ is suspended
  until the nullary method \code{moveNext()} is invoked upon
  the iterator used to initiate the current invocation of $m$.
\item
  The current call to \code{moveNext()} returns \TRUE.
\end{itemize}


\subsection{Yield-Each}
\LMLabel{yieldEach}

\LMHash{}%
The \Index{yield-each statement} adds a series of objects to
the result of a generator function
(\ref{functions}).

\begin{grammar}
<yieldEachStatement> ::= \YIELD{} `*' <expression> `;'
\end{grammar}

\LMHash{}%
Let $s$ be a yield-each statement of the form `\code{\YIELD*\,\,$e$;}'.
Let $f$ be the immediately enclosing function of $s$.
It is a compile-time error if there is no such function,
or it is not a generator.

\LMHash{}%
Let $T_f$ be the element type of $f$
(\ref{functions}),
and let $T$ be the static type of $e$.
If $f$ is a synchronous generator,
it is a compile-time error if $T$ may not be assigned to
\code{Iterable<$T_f$>}.
Otherwise $f$ is an asynchronous generator,
and it is a compile-time error if $T$ may not be assigned to
\code{Stream<$T_f$>}.

\LMHash{}%
Execution of a statement $s$ of the form `\code{\YIELD*\,\,$e$;}'
proceeds as follows:

\LMHash{}%
First, the expression $e$ is evaluated to an object $o$.

\LMHash{}%
If the immediately enclosing function $m$ is marked \code{\SYNC*}
(\ref{functions}),
then:

\begin{enumerate}
\item
  % This error can occur due to implicit casts.
  It is a dynamic type error
  if the class of $o$ is not a subtype of \code{Iterable<$T_f$>}.
  Otherwise
\item
  The method \code{iterator} is invoked upon $o$ returning an object $i$.
\item
  \label{moveNext} The \code{moveNext} method of $i$ is invoked on it
  with no arguments.
  If \code{moveNext} returns \FALSE{} execution of $s$ is complete.
  Otherwise
\item
  The getter \code{current} is invoked on $i$.
  If the invocation throws
  (\ref{expressionEvaluation}),
  execution of $s$ throws the same exception object and stack trace
  (\ref{statementCompletion}).
  Otherwise, the result $x$ of the getter invocation is added to
  the iterable associated with $m$.
  \commentary{%
    Note that a dynamic error occurs if the dynamic type of $x$ is
    not a subtype of the element type of said iterable.%
  }
  Execution of the function $m$ immediately enclosing $s$ is suspended
  until the nullary method \code{moveNext()} is invoked
  upon the iterator used to initiate the current invocation of $m$,
  at which point execution of $s$ continues at \ref{moveNext}.
\item
The current call to \code{moveNext()} returns \TRUE.
\end{enumerate}

\LMHash{}%
If $m$ is marked \code{\ASYNC*} (\ref{functions}), then:
\begin{itemize}
\item
  % This error can occur due to implicit casts.
  It is a dynamic type error if the class of $o$
  is not a subtype of \code{Stream<$T_f$>}.
  Otherwise
\item
  The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}),
  if any, is paused.
\item
  If the stream subscription $u$ associated with this execution of $m$
  has been paused, suspend execution of $m$ until $u$ has been resumed or
  cancelled.
\item
  If $u$ has been cancelled, execution of $s$ returns without a value.
\item
  The $o$ stream is listened to by calling its \code{listen} method,
  creating a subscription $r$.
\item
  Execution of $m$ is suspended. Until execution of $s$ completes in one of
  the ways specified below, execution of $m$ occurs in the following cases:
  \begin{itemize}
  \item If $u$ is cancelled, whether while waiting for an event from $r$,
    to deliver an event to $u$ or to be resumed from pause:
    Cancel $r$ by invoking its \code{cancel} method with no arguments,
    returning a future $d$.
    \commentary{%
      A stream cannot become paused or resumed after being cancelled,
      and a stream subscription must not emit events after its \code{cancel}
      function has been called, so no items below may apply after this.
    }
    Execution of $m$ is suspended until $d$ completes.
    If $d$ completed with an error \metavar{err} and a stack trace \metavar{st},
    execution of $s$ throws the error \metavar{err} and stack trace \metavar{st}.
    Otherwise execution of $s$ completes by returning without a value.
  \item If $u$ becomes paused, then $r$ is paused.
    If $r$ is not already paused, then pause $r$ by invoking its \code{pause}
    method with no arguments. If $r$ is already paused, then invoking
    \code{pause} again is allowed, but not required.
    Then suspend execution of $m$ again.
    \commentary{%
      A stream must not emit events while it's paused, so no event from $r$
      may occur until $r$ is resumed.
      The $r$ subscription may already be paused if it's delivering an
      event asynchronously.
    }
  \item If $u$ resumes from being paused, and $r$ is not currently paused
    while asynchronously delivering an event to $u$, then resume $r$
    by invoking its \code{resume} method with no arguments.
    If $r$ is also paused while delivering an event, then calling \code{resume}
    is allowed, as long as that call does not make $r$ stop being paused.
    \commentary{%
      Stream subscriptions remember how many times they have been paused
      by calling their \code{pause} method, and requires as many calls to
      their \code{resume} method before they stop being paused.
    }
    Then suspend execution of $m$ again.
  \item If $r$ emits a value event with value $v$, then $u$ emits
    a value event with value $v$,
    and if $r$ emits an error event with error \metavar{err}
    and stack trace \metavar{st},
    then $u$ emits an error event with error \metavar{err}
    and stack trace \metavar{st}.
    If the event of $u$ is not delivered \emph{synchronously} to the listener
    of $u$, immediately when it is received from $r$, then:
    \begin{itemize}
      \item $r$ is paused by invoking its \code{pause} method with no arguments.
      \item Execution of $m$ is suspended until the event has been delivered
         or $u$ is cancelled.
      \item When that event has been delievered, if $u$ is not paused or
         cancelled then $r$ is resumed by invoking its \code{resume} method
         with no arguments. \commentary{If the event is never delivered,
         then $u$ is cancelled or perpetually paused, in which case this.}
    \end{itemize}
    Then suspend execution of $m$ again.
  \item If $r$ emits a done event then $s$ completes normally.
  \end{itemize}
\end{itemize}

\commentary{%
  The semantics here propagates pause and cancel requests directly
  to the nested stream subscription of the \code{\YIELD*}.
  That ensures that a pause or cancel request is responded to as soon as possible,
  to avoid the inner stream doing a larger computation to create a value that
  the outer stream already knows it doesn't need, or if paused,
  that it may not need.
}

\subsection{Assert}
\LMLabel{assert}

\LMHash{}%
An \Index{assert statement} is used to disrupt normal execution
if a given boolean condition does not hold.

\begin{grammar}
<assertStatement> ::= <assertion> `;'

<assertion> ::= \ASSERT{} `(' <expression> (`,' <expression> )? `,'? `)'
\end{grammar}

\LMHash{}%
The grammar allows a trailing comma before the closing parenthesis,
similarly to an argument list.
That comma, if present, has no effect.
An assertion with a trailing comma is equivalent to one with that comma removed.

\LMHash{}%
An assertion of the form \code{\ASSERT($e$)} is equivalent to
an assertion of the form \code{\ASSERT($e$, \NULL{})}.

\LMHash{}%
Execution of an assert statement executes the assertion as described below
and completes in the same way as the assertion.

\LMHash{}%
When assertions are not enabled,
execution of an assertion immediately completes normally
(\ref{statementCompletion}).
\commentary{That is, no subexpressions of the assertion are evaluated.}
When assertions are enabled,
execution of an assertion \code{\ASSERT{}($c$, $e$)} proceeds as follows:

\LMHash{}%
The expression $c$ is evaluated to an object $r$.
% This error can occur due to implicit casts and null.
It is a dynamic type error if $r$ is not of type \code{bool}.
\commentary{%
  Hence it is a compile-time error if that situation arises
  during evaluation of an assertion in a \CONST{} constructor invocation.%
}
If $r$ is \TRUE{} then execution of the assert statement completes normally
(\ref{statementCompletion}).
Otherwise, $e$ is evaluated to an object $m$
and then the execution of the assert statement throws
(\ref{statementCompletion})
an \code{AssertionError} containing $m$ and with
a stack trace corresponding to the current execution state at the assertion.

\LMHash{}%
It is a compile-time error if the type of $c$
may not be assigned to \code{bool}.

\rationale{%
  Why is this a statement, not a built in function call?
  Because it is handled magically
  so it has no effect and no overhead when assertions are disabled.
  Also, in the absence of final methods,
  one could not prevent it being overridden
  (though there is no real harm in that).
  It cannot be viewed as a function call that is being optimized away
  because the arguments might have side effects.%
}


\section{Libraries and Scripts}
\LMLabel{librariesAndScripts}

\LMHash{}%
A Dart program consists of one or more libraries,
and may be built out of one or more \Index{compilation units}.
A compilation unit may be a library or a part (\ref{parts}).

\LMHash{}%
A library consists of (a possibly empty) set of imports, a set of exports,
and a set of top-level declarations.
A top-level declaration is either a class (\ref{classes}),
a type alias declaration (\ref{typedef}),
a function (\ref{functions})
or a variable declaration (\ref{variables}).
The members of a library $L$ are those top level declarations given within $L$.

\begin{grammar}
<topLevelDeclaration> ::= <classDeclaration>
  \alt <mixinDeclaration>
  \alt <extensionDeclaration>
  \alt <enumType>
  \alt <typeAlias>
  \alt \EXTERNAL{} <functionSignature> `;'
  \alt \EXTERNAL{} <getterSignature> `;'
  \alt \EXTERNAL{} <setterSignature> `;'
  \alt <functionSignature> <functionBody>
  \alt <getterSignature> <functionBody>
  \alt <setterSignature> <functionBody>
  \alt (\FINAL{} | \CONST{}) <type>? <staticFinalDeclarationList> `;'
  \alt \LATE{} \FINAL{} <type>? <initializedIdentifierList> `;'
  \alt \LATE? <varOrType> <initializedIdentifierList> `;'

<libraryDeclaration> ::= \gnewline{}
  <scriptTag>? <libraryName>? <importOrExport>* <partDirective>*
  \gnewline{} (<metadata> <topLevelDeclaration>)* <EOF>

<scriptTag> ::= `#!' (\gtilde(`\\r' | `\\n'))* <LINE\_BREAK>

<libraryName> ::= <metadata> \LIBRARY{} <dottedIdentifierList> `;'

<importOrExport> ::= <libraryImport>
  \alt <libraryExport>

<dottedIdentifierList> ::= <identifier> (`.' <identifier>)*
\end{grammar}

\LMHash{}%
A library contains a string which is derived from \synt{libraryDeclaration}.

\commentary{%
  We could say that \synt{libraryDeclaration} is a
  \Index{start symbol}
  of the grammar,
  because the syntactic derivation of any library starts from there.
  Unlike a traditional context free grammar,
  the Dart grammar does not have exactly one start symbol.
  In particular, \synt{partDeclaration}
  (\ref{parts})
  is used in the same manner to derive the contents of a part.
  There could be more, e.g.,
  a hypothetical Dart REPL (read-eval-print loop) could use
  \synt{expression} or \synt{statement} as a start symbol.
  So there is no grammar for Dart programs as such,
  only for some building blocks that are used to construct Dart programs.%
}

\LMHash{}%
Libraries may be explicitly named or implicitly named.
An \Index{explicitly named library} begins with the word \LIBRARY{}
(possibly prefaced with any applicable metadata annotations),
followed by a qualified identifier that gives the name of the library.

\commentary{%
  Technically, each dot and identifier is a separate token
  and so spaces between them are acceptable.
  However, the actual library name is the concatenation of
  the simple identifiers and dots and contains no spaces.%
}

\LMHash{}%
An implicitly named library has the empty string as its name.

\rationale{%
  The name of a library is used to tie it to
  separately compiled parts of the library (called parts) and
  can be used for printing and, more generally, reflection.
  The name may be relevant for further language evolution.%
}

\commentary{%
  Libraries intended for widespread use should avoid name collisions.
  Dart's \code{pub} package management system provides
  a mechanism for doing so.
  Each pub package is guaranteed a unique name,
  effectively enforcing a global namespace.%
}

\LMHash{}%
A library may optionally begin with a \Index{script tag}.
Script tags are intended for use with scripts (\ref{scripts}).
A script tag can be used to identify the interpreter of the script to
whatever computing environment the script is embedded in.
The script tag must appear before any whitespace or comments.
A script tag begins with \lit{\#!} and ends at the end of the line.
Any characters that follow \lit{\#!} in the script tag are ignored by
the Dart implementation.

\LMHash{}%
Libraries are units of privacy.
A private declaration declared within a library $L$
can only be accessed by code within $L$.

\commentary{%
  Since top level privates are not imported,
  using the top level privates of another library is never possible.%
}

\LMHash{}%
The \Index{public namespace} of library $L$ is the namespace that maps
the name of each public top-level member declaration $m$ of $L$ to $m$.
The \Index{local namespace} of library $L$ is the namespace that maps
the names introduced by each top-level declaration of $L$
to the corresponding declaration.
The \Index{library scope} of library $L$ is the outermost scope in $L$,
and its namespace is the library namespace of $L$
(\ref{theImportedNamespace}).

\LMHash{}%
% A setter can not be paired with a function, class, etc.
It is a compile-time error if the local namespace of library $L$
has two declarations with the same basename,
except when they are a getter and a setter.

\commentary{%
  Two distinct names $n_1$ and $n_2$ can only have the same basename
  when they are of the form \id{} and \code{\id=},
  so this kind of conflict \emph{always} involves a setter.
  But the other declaration could be a function, a class, etc.%
}


\subsection{Imports}
\LMLabel{imports}

\LMHash{}%
An \Index{import} specifies a library whose exported namespace
(or a subset of its mappings) is made available in the current library.

\begin{grammar}
<libraryImport> ::= <metadata> <importSpecification>

<importSpecification> ::= \gnewline{}
  \IMPORT{} <configurableUri>
  (\DEFERRED? \AS{} <typeIdentifier>)?
  <combinator>* `;'
\end{grammar}

\LMHash{}%
The interpretation of configurable URIs is described elsewhere
(\ref{uris}).
An import specifies a URI $s$
where the declaration of an imported library is to be found.
It is a compile-time error if the specified URI of an import
does not refer to a library declaration.

\LMHash{}%
The \Index{current library} is the library currently being compiled.
The import modifies the namespace of the current library
in a manner that is determined by the imported library and
by the optional elements of the import.

\LMHash{}%
Imports may be deferred or immediate.
A
\IndexCustom{deferred import}{import!deferred}
is distinguished by the occurrence of
the built-in identifier \DEFERRED{} after the URI.
An
\IndexCustom{immediate import}{import!immediate}
is an import that is not deferred.

\LMHash{}%
An immediate import directive $I$ may optionally include
a \Index{prefix clause} of the form `\code{\AS\,\,\id}' used to prefix
names imported by $I$.
In this case we say that \id{} is an \Index{import prefix},
or simply a \Index{prefix}.

\commentary{%
  Note that the grammar enforces that a deferred import
  includes a prefix clause,
  so we can refer to \emph{the} prefix clause of a deferred import.%
}

\LMHash{}%
It is a compile-time error if the prefix used in a deferred import
is also used as the prefix of another import clause.
It is a compile-time error if \id{} is an import prefix,
and the current library declares a top-level member with basename \id.

\LMHash{}%
An import directive $I$ may optionally include namespace combinator clauses
used to restrict the set of names imported by $I$.
Their syntax, usage, and effect on namespaces is described elsewhere
(\ref{namespaceCombinators}, \ref{theImportedNamespace},
\ref{exports}).

\LMHash{}%
The dart core library \code{dart:core}
is implicitly imported into every dart library other than itself
via an import clause of the form
\code{\IMPORT{} 'dart:core';}
unless the importing library explicitly imports \code{dart:core}.
Any import of \code{dart:core},
even if restricted via \SHOW, \HIDE, or \AS,
preempts the automatic import.

\rationale{%
  It would be nice if there was nothing special about \code{dart:core}.
  However, its use is pervasive,
  which leads to the decision to import it automatically.
  On the other hand, some library $L$ may wish to define entities
  with names used by \code{dart:core}
  (which it can easily do, as the names declared by a library take precedence).
  Other libraries may wish to use $L$,
  and may want to use members of $L$ that conflict with the core library
  without having to use a prefix and without encountering errors.
  The above rule makes this possible,
  essentially canceling \code{dart:core}'s special treatment
  by means of yet another special rule.%
}

\subsubsection{The Imported Namespace}
\LMLabel{theImportedNamespace}

\LMHash{}%
In the following, we specify the imported namespace of a library $L$,
\NamespaceName{\metavar{import}},
and use that to define the namespace that defines the library scope of $L$.

\LMHash{}%
We need to introduce system libraries because they have special rules.
A \Index{system library} is a library that is part of the Dart implementation.
Any other library is a \Index{non-system library}.

\commentary{%
  A system library can generally be recognized by having
  a URI that starts with `\code{dart:}'.%
}

\rationale{%
  The special rules for system libraries exist for the following reason.
  Normal conflicts are resolved at deployment time,
  but the functionality of a system library is
  injected into an application at run time,
  and may vary over time as the platform is upgraded.
  Thus, conflicts with a system library can arise
  outside the developer's control.
  To avoid breaking deployed applications in this way,
  conflicts with the system libraries are treated specially.%
}

\LMHash{}%
Let $I$ be an import directive and let $L$ be the library imported by $I$.
The
\IndexCustom{namespace provided by}{%
  namespace!provided by an import directive}
by the import directive $I$ is the namespace obtained from applying
the namespace combinators of $I$
to the exported namespace of $L$
(\ref{namespaceCombinators}).

\commentary{%
  Note that the namespace provided by an import directive $I$ is not
  the same as the namespace imported from $I$.
  The latter includes conflict resolution,
  and is defined later in this section.%
}

\LMHash{}%
Let \NamespaceName{\metavar{local}} be the local namespace of $L$
(\ref{librariesAndScripts}).
Let \List{I}{1}{m} be the import directives of $L$,
and let \List{L}{1}{m} be libraries
such that $I_i$ refers to $L_i$ for all $i \in 1 .. m$.
\commentary{%
  It is not an error to have multiple imports of the same library.%
}

\LMHash{}%
Let $i \in 1 .. m$.

\LMHash{}%
{\bf Step one.}
In the first step we compute the namespace obtained from each imported library,
respectively by each group of libraries imported with the same prefix,
\NamespaceName{\metavar{one},i}.

\LMHash{}%
\Case{Step one for imports without a prefix}
When $I_i$ has no prefix, \NamespaceName{\metavar{one},i} is obtained
from the namespace provided by the import directive $I_i$
by eliminating every binding for a name whose basename is
the same as the basename of a top-level declaration in $L$,
or whose basename is the prefix of an import directive in $L$.

\commentary{%
  This step ensures that \SHOW{} and \HIDE{} directives are taken into account,
  and that an import prefix as well as a local declaration
  will shadow an imported name.%
}
\EndCase

\LMHash{}%
\Case{Step one for prefixed imports}
In this step we resolve name conflicts
among names imported with the same prefix.
When $I_i$ has prefix $p_i$,
let \List{I'}{1}{k} be the sublist of \List{I}{1}{m} that have prefix $p_i$,
and let \List{L'}{1}{k} be the corresponding libraries
\commentary{(which is a sublist of \List{L}{1}{m})}.
Let \NamespaceName{\metavar{exported},j}, $j \in 1 .. k$,
be the namespace provided by the import directive $I'_j$
\commentary{(which takes \SHOW{} and \HIDE{} into account)}.

\LMHash{}%
When $I_i$ is a non-deferred import:
Let \NamespaceName{\metavar{prefix},i} be the namespace obtained from applying
conflict merging to
\List{\metavar{NS}}{\metavar{exported},1}{\metavar{exported},k}
(\ref{conflictMergingOfNamespaces}).

\LMHash{}%
When $I_i$ is a deferred import:
In this case $k$ is 1
\commentary{(otherwise a compile-time error would occur)},
and \NamespaceName{\metavar{prefix},i} is the namespace obtained by
adding a binding of the name \code{loadLibrary}
to an implicitly induced declaration of a function with signature
\code{Future<\VOID> loadLibrary()}
to \NamespaceName{\metavar{exported},1}.

\LMHash{}%
Then \NamespaceName{\metavar{one},i} is a namespace that has
a single binding that maps $p_i$ to \NamespaceName{\metavar{prefix},i}.

\LMHash{}%
In this situation we say that \NamespaceName{\metavar{one},i} is a
\Index{prefix namespace},
because it maps a library prefix to a namespace.

\commentary{%
  A prefix namespace is not a Dart object,
  it is merely a device which is used to manage
  expressions of the form \synt{qualifiedName} and what they refer to
  during static analysis.
  Consequently, any attempt to use a prefix namespace as an object
  is a compile-time error, e.g.,
  it cannot be the result of an expression evaluation.

  Note that if $l$ and $q$ are such that
  $I_l$ and $I_q$ both have the same prefix $p$
  then
  $\NamespaceName{\metavar{one},l} = \NamespaceName{\metavar{one},q} =
  \NamespaceName{\metavar{one},l} \cup \NamespaceName{\metavar{one},q}$.%
}
\EndCase

\LMHash{}%
{\bf Step two.}
In the second step we resolve top level conflicts
among the namespaces obtained in the first step.

\LMHash{}%
The \Index{imported namespace} of $L$, \NamespaceName{\metavar{import}},
is then the result of applying conflict merging to the namespaces
\List{\metavar{NS}}{\metavar{one},1}{\metavar{one},m}.

\LMHash{}%
Let $\cal E$ be a set of extension declarations
(\ref{extensions})
with the following members:
An extension declaration $E$ is a member of $\cal E$
if there is an $i \in 1 .. m$ such that
$E$ is in the namespace provided by the import directive $I_i$
\commentary{%
  (note that this takes \SHOW{} and \HIDE{} into account,
  and it includes extensions imported both without and with a prefix)%
},
and $E$ is not declared in the current library
\commentary{(which could be the case if it imports itself)}.
Let \NamespaceName{\metavar{extensions}} be a namespace that
for each extension $E$ in $\cal E$ maps a fresh name to $E$.

\commentary{%
  \NamespaceName{\metavar{extensions}} provides a fresh name
  allowing implicit access to each extension exported by an imported library
  and not removed by \HIDE{} or \SHOW,
  even the ones that cannot be accessed using their declared name,
  because of a name clash.%
}

\LMHash{}%
The \Index{library namespace} of $L$ is then
$\NamespaceName{\metavar{local}} \cup
\NamespaceName{\metavar{import}} \cup
\NamespaceName{\metavar{extensions}}$.

\LMHash{}%
Let $i \in 1 .. m$.
If $L_i$ is imported without a prefix, the
\IndexCustom{namespace imported from}{library!namespace imported from}
$L_i$ is the conflict narrowed namespace
(\ref{conflictMergingOfNamespaces})
of \NamespaceName{\metavar{one},i}.
%
Otherwise $L_i$ is imported with a prefix $p$,
in which case the \NoIndex{namespace imported from} $L_i$
is the conflict narrowed namespace
of \NamespaceName{\metavar{exported},i}.

\commentary{%
  So the namespace imported by $L_i$ contains the bindings exported by $L_i$,
  except the ones removed by namespace combinators,
  and except the ones removed by conflict merging.%
}

\LMHash{}%
Let $L$ be a library with imported namespace \NamespaceName.
We say that a name is
\IndexCustom{imported by $L$}{imported!name}
if the name is a key of \NamespaceName.
We say that a declaration is
\IndexCustom{imported by $L$}{imported!declaration}
if the declaration is a value of \NamespaceName.
We say that a name is
\IndexCustom{imported by $L$ with prefix $p$}{imported!name, with prefix}
if the name is a key of \Namespace{}{p}.
We say that a declaration is
\IndexCustom{imported by $L$ with prefix $p$}{%
  imported!declaration, with prefix}
if the declaration is a value of \Namespace{}{p}.


\subsubsection{Semantics of Imports}
\LMLabel{semanticsOfImports}

\LMHash{}%
Let $I_i$ be an import directive that refers to a URI via the string $s_i$.
The semantics of $I_i$ is specified as follows:

\LMHash{}%
\Case{Semantics of deferred imports}
If $I_i$ is a deferred import with prefix $p$, a binding of $p$ to a
\Index{deferred prefix run-time namespace}
\NamespaceName{\metavar{deferred}} is
present in the library namespace of the current library $L$.
Let \NamespaceName{\metavar{import},i} be
the namespace imported from the library specified by $I_i$,
as defined previously
(\ref{theImportedNamespace}).
\NamespaceName{\metavar{deferred}} then has the following bindings:

\begin{itemize}
\item The name \code{loadLibrary} is bound to
  a function with signature \code{Future<\VOID> loadLibrary()}.
  This function returns a future $f$.
  When called, the function causes
  an immediate import $I'$ to be executed at some future time,
  where $I'$ is derived from $I_i$ by eliding the word \DEFERRED{}
  and adding a \HIDE{} \code{loadLibrary} combinator clause.
  The execution of the immediate import may fail
  for implementation specific reasons.
  \commentary{%
    For instance, $I'$ imports a different library than the one
    that the specified URI referred to at compile-time;
    or an OS level file read error occurs; etc.%
  }
  We say that the invocation of \code{loadLibrary}
  \IndexCustom{succeeds}{loadLibrary!succeeds} if $f$ completes with a value,
  and that the invocation
  \IndexCustom{fails}{loadLibrary!fails} if $f$ completes with an error.
\item
  For every top level function $f$ named \id{} in
  \NamespaceName{\metavar{import},i},
  a corresponding function named \id{} with the same signature as $f$.
  % This error can occur because being-loaded is a dynamic property.
  Calling the function results in a dynamic error that occurs before
  any actual arguments are evaluated.
  Closurizing the function
  (\ref{functionClosurization})
  also results in a dynamic error.
\item
  For every top level getter $g$ named \id{} in
  \NamespaceName{\metavar{import},i},
  a corresponding getter named \id{} with the same signature as $g$.
  % This error can occur because being-loaded is a dynamic property.
  Calling the getter results in a dynamic error.
\item
  For every top level setter $s$ named \code{\id=} in
  \NamespaceName{\metavar{import},i},
  a corresponding setter named \code{\id=} with the same signature as $s$.
  % This error can occur because being-loaded is a dynamic property.
  Calling the setter results in a dynamic error that occurs before
  the actual argument is evaluated.
\item
  For every class, mixin, enum, and type alias declaration named \id{} in
  \NamespaceName{\metavar{import},i},
  a corresponding getter named \id{} with return type \code{Type}.
  % This error can occur because being-loaded is a dynamic property.
  Calling the getter results in a dynamic error.
\end{itemize}

\rationale{%
  The purpose of having members of the imported library in
  \NamespaceName{\metavar{deferred}}
  is to ensure that usages of members that have not yet been loaded
  can be resolved normally and has a well-defined behavior,
  which will raise errors.%
}

\LMHash{}%
When an invocation of \code{$p$.loadLibrary()} succeeds,
the name $p$ is mapped to a non-deferred prefix run-time namespace
\NamespaceName{\metavar{loaded}},
with bindings as described below for immediate imports.
In addition, \NamespaceName{\metavar{loaded}}
maps \code{loadLibrary} to a function with the same signature as before,
and so it is possible to invoke \code{$p$.loadLibrary()} again,
which will always succeed.
If a call fails, the library has not been loaded,
and one has the option to invoke \code{$p$.loadLibrary()} again.
Whether a repeated call to \code{$p$.loadLibrary()} succeeds will vary,
as described below.

\commentary{%
  Note that it is a compile-time error for a deferred prefix
  to be used in more than one import,
  which means that the update of the binding of $p$
  does not interfere with other imports.%
}

\LMHash{}%
The effect of a repeated invocation of \code{$p$.loadLibrary()} is as follows:

\begin{itemize}
\item
  If another invocation of \code{$p$.loadLibrary()} has already succeeded,
  the repeated invocation also succeeds.
  Otherwise,
\item
  If another invocation of \code{$p$.loadLibrary()} has failed:

  \begin{itemize}
  \item
    If the failure is due to a compilation error,
    the repeated invocation fails for the same reason.
  \item
    If the failure is due to other causes,
    the repeated invocation behaves as if no previous call had been made.
  \end{itemize}
\end{itemize}

\commentary{%
  In other words, a successful \code{loadLibrary()} guarantees that
  the import can be successfully accessed through the import prefix.
  If an invocation of \code{loadLibrary()} is initiated after
  another invocation has completed successfully,
  it is guaranteed to also complete successfully (success is idempotent).
  We do not specify which object the returned future resolves to.%
}
\EndCase

\LMHash{}%
\Case{Semantics of immediate imports}
When $I_i$ is an immediate import with a library URI, $u_i$,
represented by the string $s_i$:
Let $L_i$ be the library obtained from the source code denoted by $s_i$.
We then say that the URI $u_i$ denotes the library $L_i$.
All imports and exports of the same URI in a Dart program denotes
the same library,
and imports or exports of different URIs denote distinct libraries.

\LMHash{}%
Let \NamespaceName{\metavar{import}, i} be the namespace imported from $L_i$.
The run-time namespace \NamespaceName{i} will then have the following bindings:

\begin{itemize}
\item
  For every top level function, getter, or setter $m$ named $n$ in
  \NamespaceName{\metavar{import}, i},
  a binding from $n$ to said function, getter, or setter.
\item
  For every name \id{} in \NamespaceName{\metavar{import}, i}
  that is bound to a class, mixin, enum, or type alias declaration
  introducing a type $T$,
  a binding from \id{} to the compiled representation of $T$.
\end{itemize}

\LMHash{}%
If $I_i$ has prefix $p$,
the run-time namespace of the current library
maps $p$ to a non-deferred prefix run-time namespace \NamespaceName{p}
containing the mappings of \NamespaceName{i}.

\commentary{%
  \NamespaceName{p} may have additional mappings
  because there can be several imports with the same prefix
  as long as they are all immediate.%
}

\LMHash{}%
Otherwise, when $I_i$ does not have a prefix,
the run-time library namespace of the current library
contains each mapping in \NamespaceName{i}.
\EndCase


\subsection{Exports}
\LMLabel{exports}

\LMHash{}%
A library $L$ exports a namespace (\ref{scoping}), meaning that
the declarations in the namespace are made available to other libraries
if they choose to import $L$ (\ref{imports}).
The namespace that $L$ exports is known as its
\IndexCustom{exported namespace}{library!exported namespace of}.

\LMHash{}%
A library always exports all names and all declarations in its public namespace.
In addition, a library may choose to re-export additional libraries
via \Index{export directives}, often referred to simply as \Index{exports}:

\begin{grammar}
<libraryExport> ::= <metadata> \EXPORT{} <configurableUri> <combinator>* `;'
\end{grammar}

\LMHash{}%
The interpretation of configurable URIs is described elsewhere
(\ref{uris}).
An export specifies a URI $s$
where the declaration of an exported library is to be found.
It is a compile-time error if the specified URI
does not refer to a library declaration.

\LMHash{}%
The
\Index{exported namespace}
of a library is determined as follows, in two steps.
Let $L$ be a library,
let \List{E}{1}{m} be the export directives of $L$,
and let \List{L}{1}{m} be libraries
such that $E_i$ refers to $L_i$ for all $i \in 1 .. m$.
Let \NamespaceName{\metavar{public}} be the public namespace of $L$
(\ref{librariesAndScripts}).

\commentary{%
  Note that private names and import prefixes are not present
  in \NamespaceName{\metavar{public}}.%
}

\LMHash{}%
In the first step we compute the namespace provided by each exported library:
For each $i \in 1 .. m$,
\NamespaceName{\metavar{exported},i} is
the namespace obtained from applying
the namespace combinators of $E_i$ to
the exported namespace of $L_i$
(\ref{namespaceCombinators}),
and removing each binding of a name $n$ such that
\NamespaceName{\metavar{public}} is defined at $n'$,
and $n$ and $n'$ have the same basename.
\commentary{Because local declarations will shadow re-exported ones.}

\LMHash{}%
The
\IndexCustom{namespace re-exported from}{library!namespace re-exported from}
$L_i$ is \NamespaceName{\metavar{exported},i}.

\LMHash{}%
In the second step we compute the exported namespace of $L$.
Let \NamespaceName{\metavar{merged}} be the result of applying
conflict merging
(\ref{conflictMergingOfNamespaces})
to \List{\metavar{NS}}{\metavar{exported},1}{\metavar{exported},m}.
A compile-time error occurs if any name in
\NamespaceName{\metavar{merged}}
is conflicted
(\ref{conflictMergingOfNamespaces}).

\rationale{%
  This rule is more strict than the corresponding rule for imports:
  When two imported declarations have a name clash, it is only an error to
  \emph{use} the conflicted name,
  it is not an error that the name clash exists.
  With exported names, it is an error that the name clash exists.
  The reason for this difference is that
  the conflict could silently break importers of the current library $L$,
  if we were to use the same approach for exports as for imports:
  If a library $L'$ imports $L$
  and uses a name $n$ which is re-exported by $L$ from $L_n$
  then the addition of a declaration named $n$
  to some other re-exported library
  will make the use of $n$ in $L'$ an error,
  and the maintainers of $L'$ may not be in a position to change $L$.%
}

\LMHash{}%
The
\IndexCustom{exported namespace}{library!exported namespace of}
of $L$ is
$\NamespaceName{\metavar{public}} \cup \NamespaceName{\metavar{merged}}$.

\LMHash{}%
We say that a name is \Index{exported by a library}
if the name is in the library's exported namespace.
We say that a declaration \Index{is exported by a library}
if the declaration is in the library's exported namespace.

\LMHash{}%
For a given $i$,
we say that $L$
\Index{re-exports library}
$L_i$, and also that $L$
\Index{re-exports namespace}
\NamespaceName{\metavar{exported},i}.
When no confusion can arise, we may simply state
that $L$ \NoIndex{re-exports} $L_i$, or
that $L$ \NoIndex{re-exports} \NamespaceName{\metavar{exported},i}.


\subsection{Namespace Combinators}
\LMLabel{namespaceCombinators}

\LMHash{}%
Imports (\ref{imports}) and exports (\ref{exports}) rely on
\Index{namespace combinators}
in order to adjust namespaces
(\ref{scoping})
and manage name clashes.
The supported namespace combinators are \SHOW{} and \HIDE.

\begin{grammar}
<combinator> ::= \SHOW{} <identifierList> | \HIDE{} <identifierList>

<identifierList> ::= <identifier> (`,' <identifier>)*
\end{grammar}

\LMHash{}%
We define several operations that compute namespaces.
The
\IndexCustom{union of two namespaces}{namespace!union},
\IndexCustom{$\NamespaceName{a}\cup\NamespaceName{b}$}{%
  $\cup$@$\NamespaceName{a} \cup \NamespaceName{b}$},
is defined when every key where both are defined is mapped to the same value.
This union is the namespace that maps
each key $n$ of \NamespaceName{a}
to the corresponding value \Namespace{a}{n},
and each key $n$ of \NamespaceName{b}
to \Namespace{b}{n}.

\commentary{%
  Note that this \emph{is} a namespace because the union is only defined
  when the mapping of any given key is unambiguous.%
}

\LMHash{}%
The function
\IndexCustom{\Hide{l}{\NamespaceName{a}}}{%
  hide(l,NSa)@\Hide{l}{\NamespaceName{}}}
takes a list of identifiers $l$ and a namespace \NamespaceName{a},
and produces a namespace \NamespaceName{b} that is
identical to \NamespaceName{a} except that for each identifier \id{} in $l$,
\NamespaceName{b} is undefined at \id{} and at \code{\id=}.

\LMHash{}%
The function
\IndexCustom{\Show{l}{\NamespaceName{a}}}{%
  show(l,NSa)@\Show{l}{\NamespaceName{}}}
takes a list of identifiers $l$ and a namespace \NamespaceName{a},
and produces a namespace \NamespaceName{b} that
maps each identifier \id{} in $l$
where \NamespaceName{a} is defined
to \Namespace{a}{n}.
Furthermore, for each identifier \id{} in $l$
where \NamespaceName{a} is defined at \code{\id=},
\NamespaceName{b} maps \code{\id=} to \Namespace{a}{\code{\id=}}.
Finally, \NamespaceName{b} is undefined at all other names.

\LMHash{}%
Let \List{C}{1}{n} be a sequence of combinator clauses.
\commentary{They would come from an import or export directive.}
The result of
\IndexCustom{applying the combinator clauses}{%
  combinator clauses!application to namespace}
to a given namespace \NamespaceName{\metavar{start}}
is a namespace \NamespaceName{\metavar{end}},
which is computed as follows.

\LMHash{}%
Let \NamespaceName{0} be \NamespaceName{\metavar{start}}.
For each combinator clause $C_j$, $j \in 1 .. n$:
If $C_j$ is of the form \code{\SHOW{} $\id_1, \ldots,\ \id_k$} then let
$\NamespaceName{j} = \Show{[\List{\id}{1}{k}]}{\NamespaceName{j-1}}$.
If $C_i$ is of the form \code{\HIDE{} $\id_1, \ldots,\ \id_k$} then let
$\NamespaceName{j} = \Hide{[\List{id}{1}{k}]}{\NamespaceName{j-1}}$.
Then \NamespaceName{\metavar{end}} is \NamespaceName{n}.

\commentary{%
  \NamespaceName{\metavar{end}} will always agree with
  \NamespaceName{\metavar{start}} wherever both are defined,
  and the set of names where \NamespaceName{\metavar{end}} is defined
  is always a subset of that of \NamespaceName{\metavar{start}}.
  In that sense, this is a \emph{narrowing} procedure.%
}

\commentary{%
  Note that it is possible to use \HIDE{} or \SHOW{} on an identifier
  which is not in the given namespace.%
}
\rationale{%
  Allowing this prevents situations where, e.g.,
  removing a declaration from a library $L$ would cause
  breakage in a library that imports $L$.%
}


\subsection{Conflict Merging of Namespaces}
\LMLabel{conflictMergingOfNamespaces}

\LMHash{}%
In this section we define an operation on namespaces
which eliminates certain bindings of names in case of name clashes,
and keeps track of such name clashes using a special value,
\Index{\ConflictValue}.

\LMHash{}%
When a name $n$ is mapped to \ConflictValue{} by a namespace,
we say that $n$ is
\IndexCustom{conflicted}{conflicted name}.
A lookup for a conflicted name will succeed according to
the normal rules for namespaces and lexical scoping,
but it is a compile-time error at the location where the name is used
that this name is conflicted.

\LMHash{}%
Let \List{\metavar{NS}}{1}{m} be a list of namespaces
\commentary{(the list may or may not contain duplicates)}.
The
\IndexCustom{conflict merging}{namespace!conflict merging}
of \List{\metavar{NS}}{1}{m} is then
$\NamespaceName{\metavar{conflict}} \cup
\NamespaceName{\metavar{narrowed},1} \cup\,
\ldots\ \NamespaceName{\metavar{narrowed},m}$,
where the namespaces \NamespaceName{\metavar{conflict}} and
\NamespaceName{\metavar{narrowed},i}, $i \in 1 .. m$,
are specified as follows:

\LMHash{}%
\NamespaceName{\metavar{conflict}} is empty except for the
bindings mentioned below.
For each $i \in 1 .. m$,
\NamespaceName{\metavar{narrowed},i} is identical to \NamespaceName{i},
except that the former is undefined at each name $n$ where
the latter is defined,
and one of the following conditions holds:

\begin{itemize}
\item There exists a $j \in 1 .. m$ and name $n'$ such that
  \NamespaceName{j} is defined at $n'$,
  $n$ and $n'$ have the same basename,
  \Namespace{i}{n} is a declaration in a system library,
  and \Namespace{j}{n'} is a declaration in a non-system library.
  \commentary{%
    So a declaration from a non-system library shadows
    declarations from system libraries.%
  }
\item Otherwise, there exists a $j \in 1 .. m$ and name $n'$ such that
  \NamespaceName{j} is defined at $n'$,
  $n$ and $n'$ have the same basename,
  \Namespace{i}{n} and \Namespace{j}{n'} are not the same declaration
  and not the same namespace
  and not a getter and a setter declared in the same library,
  and either none or both of
  \Namespace{i}{n} and \Namespace{j}{n'}
  are declarations in a system library.
  %
  \commentary{%
    So with two distinct declarations with the same basename,
    both are eliminated,
    except when it is a getter and a setter from the same library.
    Note that \Namespace{i}{n} and \Namespace{j}{n'}
    must both be declarations or must both be namespaces,
    because conflict merging is applied to namespaces where
    imported declarations that conflict with an import prefix
    have already been eliminated.
    When they are both namespaces there is no conflict,
    because it is then the same namespace.%
  }

  In this situation $n$ is mapped to \ConflictValue{}
  by \NamespaceName{\metavar{conflict}}.
  \commentary{%
    We can swap all names and use the rule again,
    so $n'$ is also conflicted.%
  }
\end{itemize}

\commentary{%
  In short, conflict merging takes a list of namespaces and produces
  a namespace that is the union of several disjoint namespaces
  (because all name clashes have been eliminated):
  A conflict namespace that records all unresolved name clashes,
  and a list of namespaces where clashing names have been removed.
  Some name clashes have been resolved by preferring
  declarations from non-system libraries
  over declarations from system libraries.%
}

\LMHash{}%
It is useful to be able to refer to the result of narrowing.
Let \List{\metavar{NS}}{1}{m} be a list of namespaces, $i \in 1 .. m$,
and consider the conflict merging as specified above.
The
\IndexCustom{conflict narrowed namespace}{namespace!conflict narrowed}
of \NamespaceName{i} is then \NamespaceName{\metavar{narrowed},i}.


\subsection{Parts}
\LMLabel{parts}

\LMHash{}%
A library may be divided into \Index{parts},
each of which can be stored in a separate location.
A library identifies its parts by listing them via \PART{} directives.

\LMHash{}%
A \Index{part directive} specifies a URI where
a Dart compilation unit that should be incorporated into the current library
may be found.

\begin{grammar}
<partDirective> ::= <metadata> \PART{} <uri> `;'

<partHeader> ::= <metadata> \PART{} \OF{} (<dottedIdentifierList> | <uri>) `;'

<partDeclaration> ::=
  <partHeader> (<metadata> <topLevelDeclaration>)* <EOF>
\end{grammar}

\LMHash{}%
A part contains a string which is derived from \synt{partDeclaration}.

\commentary{%
  So we could say that \synt{partDeclaration} is a start symbol of the grammar,
  as discussed in Sect.~\ref{librariesAndScripts}.%
}

\LMHash{}%
A \Index{part header} begins with \PART{} \OF{} followed by
the name of the library the part belongs to,
or a \synt{uri} denoting said library.
A part declaration consists of a part header followed by
a sequence of top-level declarations.

\LMHash{}%
Compiling a part directive of the form \code{\PART{} $s$;}
causes the Dart system to attempt to compile the contents of
the URI that is the value of $s$.
The top-level declarations at that URI are then compiled by the Dart compiler
in the scope of the current library.
It is a compile-time error if the contents of the URI are not
a valid part declaration.
It is a compile-time error if the referenced part declaration $p$ names
a library other than the current library as the library to which $p$ belongs.

\LMHash{}%
It is a compile-time error if a library contains
two part directives with the same URI.

\LMHash{}%
We say that a library $L_1$ is \Index{reachable from} a library $L$ if
any of the following is true (\ref{imports}, \ref{exports}):

\begin{itemize}
\item $L$ and $L_1$ is the same library.
\item $L$ imports or exports a library $L_2$, and $L_1$ is reachable from $L_2$.
\end{itemize}

\LMHash{}%
Let $L$ be a library, let $u$ be a URI,
and let $L_1$ and $L_2$ be distinct libraries which are reachable from $L$.
It is a compile-time error if $L_1$ and $L_2$ both contain
a part directive with URI $u$.

\commentary{%
  In particular, it is an error to use the same part twice
  in the same program
  (\ref{scripts}).
  Note that a relative URI is interpreted as relative to the location of the
  enclosing library (\ref{uris}), which means that $L_1$ and $L_2$ may both
  have a part identified by \code{'myPart.dart'}, but they are not the same
  URI unless $L_1$ and $L_2$ have the same location.%
}


\subsection{Scripts}
\LMLabel{scripts}

\LMHash{}%
A \Index{script} is a library whose exported namespace (\ref{exports}) includes
a top-level function declaration named \code{main}
that has either zero, one or two required arguments.

A script $S$ is executed as follows:

\LMHash{}%
First, $S$ is compiled as a library as specified above.
Then, the top-level function defined by \code{main}
in the exported namespace of $S$ is invoked (\ref{functionInvocation})
as follows:
If \code{main} can be called with with two positional arguments,
it is invoked with the following two actual arguments:

\begin{enumerate}
\item An object whose run-time type implements \code{List<String>}.
\item An object specified when the current isolate $i$ was created,
for example through the invocation of \code{Isolate.spawnUri} that spawned $i$,
or the null object (\ref{null}) if no such object was supplied.
\end{enumerate}

\LMHash{}%
If \code{main} cannot be called with two positional arguments,
but it can be called with one positional argument,
it is invoked with an object whose run-time type implements \code{List<String>}
as the only argument.
If \code{main} cannot be called with one or two positional arguments,
it is invoked with no arguments.

\commentary{%
  Note that if \code{main} requires more than two positional arguments,
  the library is not considered a script.%
}

\commentary{%
  A Dart program will typically be executed by executing a script.%
}

\LMHash{}%
It is a compile-time error if a library's export scope contains a declaration
named \code{main}, and the library is not a script.
\commentary{%
  This restriction ensures that all top-level \code{main} declarations
  introduce a script main-function, so there cannot be
  a top-level getter or field
  named \code{main}, nor can it be a function that requires more than two
  arguments. The restriction allows tools to fail early on invalid \code{main}
  methods, without needing to know whether a library will be used as the entry
  point of a Dart program. It is possible that this restriction will be removed
  in the future.%
}


\subsection{URIs}
\LMLabel{uris}

\LMHash{}%
URIs are specified by means of string literals:

\begin{grammar}
<uri> ::= <stringLiteral>

<configurableUri> ::= <uri> <configurationUri>*

<configurationUri> ::= \IF{} `(' <uriTest> `)' <uri>

<uriTest> ::= <dottedIdentifierList> (`==' <stringLiteral>)?
\end{grammar}

\LMHash{}%
It is a compile-time error if a string literal that describes a URI
or a string literal that is used in a \synt{uriTest}
contains a string interpolation.

\LMHash{}%
A \Index{configurable URI} $c$ of the form
\code{\metavar{uri} $\metavar{configurationUri}_1$ \ldots $\metavar{configurationUri}_n$}
\IndexCustom{specifies a URI}{specify a URI} as follows:

\begin{itemize}
\item
  Let $u$ be \metavar{uri}.
\item
  For each of the following configuration URIs of the form
  \code{\IF{} ($\metavar{test}_i$) $\metavar{uri}_i$},
  in source order, do the following.

  \begin{itemize}
  \item
    If $\metavar{test}_i$ is \code{\metavar{ids}}
    with no \lit{==} clause, it is
    equivalent to \code{\metavar{ids} == "true"}.
  \item
    If $\metavar{test}_i$ is \code{\metavar{ids} == \metavar{string}},
    then create a string, \metavar{key}, from \metavar{ids}
    by concatenating the identfiers and dots,
    omitting any spaces between them that may occur in the source.
  \item
    Look up \metavar{key} in the available
    \Index{compilation environment}.
    \commentary{%
      The compilation environment is provided by the platform.
      It maps some string keys to string values,
      and can be accessed programmatically using the
      \code{const String.fromEnvironment} constructor.
      Tools may choose to only make some parts of the compilation environment
      available for choosing configuration URIs.%
    }
  \item
    If the environment contains an entry for \metavar{key} and the
    associated value is equal, as a constant string value, to the value of
    the string literal \metavar{string},
    then let $u$ be $\metavar{uri}_i$ and stop iterating the configuration URIs.
  \item
    Otherwise proceed to the next configuration URI.
  \end{itemize}
\item
  The URI specified by $c$ is $u$.
\end{itemize}

\LMHash{}%
This specification does not discuss the interpretation of URIs,
with the following exceptions.

\rationale{%
  The interpretation of URIs is mostly left to
  the surrounding computing environment.
  For example, if Dart is running in a web browser,
  that browser will likely interpret some URIs.
  While it might seem attractive to specify, say, that
  URIs are interpreted with respect to a standard such as IETF RFC 3986,
  in practice this will usually depend on the browser
  and cannot be relied upon.%
}

\LMHash{}%
A URI of the form \code{dart:$s$} is interpreted as
a reference to a system library (\ref{imports}) $s$.

\LMHash{}%
A URI of the form \code{package:$s$} is interpreted in
an implementation specific manner.

\rationale{%
  The intent is that, during development, Dart programmers can rely on
  a package manager to find elements of their program.%
}

\LMHash{}%
Otherwise, any relative URI is interpreted as relative to
the location of the current library.
All further interpretation of URIs is implementation dependent.

\commentary{This means it is dependent on the runtime.}


\section{Types}
\LMLabel{types}

\LMHash{}%
Dart supports static typing based on interface types.

\rationale{%
  The type system is sound in the sense that
  if a variable of type $T$ refers to an object of type $S$ at run time,
  then $S$ is a subtype of $T$.
  In other words, the contents of the heap satisfies the expectations
  expressed by static typing.

  However, type parameters are covariant
  (e.g., \SubtypeNE{\code{List<int>}}{\code{List<num>}})
  and this implies that certain operations are subject to dynamic type checks
  (such as \code{myList.add(1.5)}, which will throw at run time
  if \code{myList} has declared type \code{List<num>},
  but it is actually a \code{List<int>}).
  Hence, a program can be free of compile-time errors,
  and it may still incur a type error at run time.

  This choice was made deliberately during the early days of Dart
  (and it is undoubtedly controversial).
  It represents a trade-off where
  the potential for run-time type errors is the cost,
  and the benefit is simpler programs.
  In recent years, Dart has evolved to have more and more static type safety,
  e.g., null safety, and this trend is likely to continue.%
}


\subsection{Static Types}
\LMLabel{staticTypes}

\LMHash{}%
Type annotations can occur in variable declarations (\ref{variables}),
including formal parameters (\ref{formalParameters}),
in the return types of functions (\ref{functions}),
and in the bounds of type variables (\ref{generics}).
Type annotations are used during static checking and when running programs.
Types are specified using the following grammar rules.

\commentary{%
  A \synt{typeIdentifier} is an identifier which can be the name of a type,
  that is,
  it denotes an \synt{IDENTIFIER} which is not a \synt{BUILT\_IN\_IDENTIFIER}
  (\ref{identifierReference}).%
}

\commentary{%
  Non-terminals with names of the form \synt{\ldots{}NotFunction}
  derive terms which are types that are not function types.
  Note that it \emph{does} derive the type \FUNCTION,
  which is not itself a function type,
  but it is the least upper bound of all function types.%
}

\begin{grammar}

<type> ::= <functionType> `?'?
  \alt <typeNotFunction>

<typeNotVoid> ::= <functionType> `?'?
  \alt <typeNotVoidNotFunction> `?'?

<typeNotFunction> ::= \VOID{}
  \alt <typeNotVoidNotFunction> `?'?

<typeNotVoidNotFunction> ::= <typeName> <typeArguments>?
  \alt (<typeIdentifier> '.')? \FUNCTION{}

<typeName> ::= <typeIdentifier> (`.' <typeIdentifier>)?

<typeArguments> ::= `<' <typeList> `>'

<typeList> ::= <type> (`,' <type>)*

<typeNotVoidNotFunctionList> ::= \gnewline{}
  <typeNotVoidNotFunction> (`,' <typeNotVoidNotFunction>)*

<functionType> ::= <functionTypeTails>
  \alt <typeNotFunction> <functionTypeTails>

<functionTypeTails> ::= <functionTypeTail> `?'? <functionTypeTails>
  \alt <functionTypeTail>

<functionTypeTail> ::= \FUNCTION{} <typeParameters>? <parameterTypeList>

<parameterTypeList> ::= `(' `)'
  \alt `(' <normalParameterTypes> `,' <optionalParameterTypes> `)'
  \alt `(' <normalParameterTypes> `,'? `)'
  \alt `(' <optionalParameterTypes> `)'

<normalParameterTypes> ::= \gnewline{}
  <normalParameterType> (`,' <normalParameterType>)*

<normalParameterType> ::= <metadata> <typedIdentifier>
  \alt <metadata> <type>

<optionalParameterTypes> ::= <optionalPositionalParameterTypes>
  \alt <namedParameterTypes>

<optionalPositionalParameterTypes> ::= `[' <normalParameterTypes> `,'? `]'

<namedParameterTypes> ::=
  `\{' <namedParameterType> (`,' <namedParameterType>)* `,'? `\}'

<namedParameterType> ::=
  <metadata> \REQUIRED? <typedIdentifier>

<typedIdentifier> ::= <type> <identifier>
\end{grammar}

\LMHash{}%
A Dart implementation must provide a static checker that detects and reports
exactly those situations this specification identifies as compile-time errors,
and only those situations.
Similarly, the static checker must emit static warnings
for at least the situations specified as such in this specification.

\commentary{%
  Nothing precludes additional tools that implement alternative static analyses
  (e.g., interpreting the existing type annotations in a sound manner
  such as either non-variant generics, or inferring declaration based variance
  from the actual declarations).
  However, using these tools must not preclude
  successful compilation and execution of Dart code.%
}

\LMHash{}%
A type $T$ is \Index{malformed} if{}f:

\begin{itemize}
\item
  $T$ has the form \id{} or the form \code{\metavar{prefix}.\id},
  and it does not denote a declaration of a type.
\item
  $T$ denotes a type variable,
  but it occurs in the signature or body of a static member.
\item
  $T$ is a parameterized type of the form \code{$G$<$S_1, \ldots,\ S_n$>},
  and $G$ is malformed,
  or $G$ is not a generic type,
  or $G$ is a generic type,
  but it declares $n'$ type parameters and $n' \not= n$,
  or $S_j$ is malformed for some $j \in 1 .. n$.
\item
  $T$ is a function type of the form

  \code{$T_0$ \FUNCTION{}<$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$>}

  \code{\quad($T_1\ x_1, \ldots,\ T_k\ x_k,\ $[$T_{k+1}\ x_{k+1}, \ldots,\ T_n\ x_n$])}

  \noindent
  or of the form

  \code{$T_0$ \FUNCTION{}<$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$>}

  \code{\quad($T_1\ x_1, \ldots,\ T_k\ x_k,\ $\{$T_{k+1}\ x_{k+1}, \ldots,\ T_n\ x_n$\})}

  \noindent
  where each $x_j$ which is not a named parameter may be omitted,
  and $T_j$ is malformed for some $j \in 0 .. n$,
  or $B_j$ is malformed for some $j \in 1 .. m$.
\item
  $T$ denotes declarations that were imported from multiple imports clauses.
\end{itemize}

\LMHash{}%
Any occurrence of a malformed type in a library is a compile-time error.

\LMHash{}%
A type $T$ is \IndexCustom{deferred}{type!deferred}
if{}f it is of the form $p.T$ where $p$ is a deferred prefix.
It is a compile-time error to use a deferred type
in a type annotation, type test, type cast or as a type parameter.
However, all other compile-time errors must be issued
under the assumption that all deferred libraries have successfully been loaded.

% Now, when passed to a generic, p.T also has to be treated as dynamic -
% otherwise we have to fail immediately. Where do we say that? And how does
% this fit with idea that as a type object it fails? Should we say that the
% accessor on p returns dynamic instead of failing? Do we distinguish its use
% in a constructor vs its use in an annotation? It's not that we evaluate type
% objects in constructor args - these cannot represent parameterized types.


\subsubsection{Type Promotion}
\LMLabel{typePromotion}

\LMHash{}%
The static type system ascribes a static type to every expression.
In some cases, the type of a local variable
\commentary{(which can be a formal parameter)}
may be promoted from the declared type, based on control flow.

\LMHash{}%
We say that a variable $v$ is known to have type $T$
whenever we allow the type of $v$ to be promoted.
The exact circumstances when type promotion is allowed are given in
the relevant sections of the specification
(\ref{logicalBooleanExpressions}, \ref{conditional} and \ref{if}).

\LMHash{}%
Type promotion for a variable $v$ is allowed only when we can deduce that
such promotion is valid based on an analysis of certain boolean expressions.
In such cases, we say that
the boolean expression $b$ shows that $v$ has type $T$.
As a rule, for all variables $v$ and types $T$, a boolean expression
does not show that $v$ has type $T$.
Those situations where an expression does show that a variable has a type are
mentioned explicitly in the relevant sections of this specification
(\ref{typeTest} and \ref{logicalBooleanExpressions}).


\subsection{Dynamic Type System}
\LMLabel{dynamicTypeSystem}

% \ref{classes} says that 'when a class name appears as a type,%
% that name denotes the interface of the class. So we can say
% that the dynamic type of an instance is a non-generic class or
% a generic instantiation of a generic class.

\LMHash{}%
Let $o$ be an instance.
The \Index{dynamic type} of $o$ is the class which is specified
for the situation where $o$ was obtained as a fresh instance
(\ref{redirectingFactoryConstructors},
\ref{lists}, \ref{maps}, \ref{new}, \ref{functionInvocation}).

\commentary{%
  In particular, the dynamic type of an instance never changes.
  It is at times only specified that the given class implements
  a certain type, e.g., for a list literal.
  In these cases the dynamic type is implementation dependent,
  except of course that said superinterface constraint must be satisfied.%
}

\LMHash{}%
The dynamic types of a running Dart program are equivalent to
the static types with regard to subtyping.

\commentary{%
  Certain dynamic type checks are performed during execution
  (\ref{variables},
  \ref{redirectingGenerativeConstructors},
  \ref{executionOfInitializerLists},
  \ref{factories},
  \ref{redirectingFactoryConstructors},
  \ref{lists},
  \ref{new},
  \ref{bindingActualsToFormals},
  \ref{ordinaryInvocation},
  \ref{assignment},
  \ref{typeCast},
  \ref{localVariableDeclaration},
  \ref{asynchronousFor-in},
  \ref{return},
  \ref{yieldEach},
  \ref{assert}).
  As specified in those locations,
  these dynamic checks are based on the dynamic types of instances,
  and the actual types of declarations
  (\ref{actualTypes}).%
}

\LMHash{}%
When types are reified as instances of the built-in class \code{Type},
those objects override the \lit{==} operator
inherited from the \code{Object} class, so that
two \code{Type} objects are equal according to operator \lit{==}
if{}f the corresponding types are subtypes of each other.

\commentary{%
  For example, the \code{Type} objects for the types
  \DYNAMIC{} and \code{Object} are equal to each other
  and hence \code{dynamic\,==\,Object} must evaluate to \TRUE.
  No constraints are imposed on the built-in function \code{identical},
  so \code{identical(dynamic, Object)} may be \TRUE{} or \FALSE.

  Similarly, \code{Type} instances for distinct type alias declarations
  declaring a name for the same function type are equal:%
}

\begin{dartCode}
\TYPEDEF{} F = \VOID{} \FUNCTION{}<X>(X);
\TYPEDEF{} G = \VOID{} \FUNCTION{}<Y>(Y);
\\
\VOID{} main() \{
  assert(F == G);
\}
\end{dartCode}

\LMHash{}%
\commentary{%
  Instances of \code{Type} can be obtained in various ways,
  for example by using reflection,
  by reading the \code{runtimeType} of an object,
  or by evaluating a \emph{type literal} expression.%
}

\LMHash{}%
An expression is a \emph{type literal} if it is an identifier,
or a qualified identifier,
which denotes a class, mixin, enum, or type alias declaration, or it is
an identifier denoting a type parameter of a generic class or function.
It is a \emph{constant type literal} if it does not denote a type parameter,
and it is not qualified by a deferred prefix.
\commentary{%
  A constant type literal is a constant expression (\ref{constants}).%
}


\subsection{Type Aliases}
\LMLabel{typedef}

\LMHash{}%
A \Index{type alias} declares a name for a type,
or for a mapping from type arguments to types.

\commentary{%
  It is common to use the phrase ``a typedef'' for such a declaration,
  because of the prominent occurrence of the token \TYPEDEF.%
}

\begin{grammar}
<typeAlias> ::= \gnewline{}
  \TYPEDEF{} <typeIdentifier> <typeParameters>? `=' <type> `;'
  \alt \TYPEDEF{} <functionTypeAlias>

<functionTypeAlias> ::= <functionPrefix> <formalParameterPart> `;'

<functionPrefix> ::= <type>? <identifier>
\end{grammar}

\LMHash{}%
Consider a type alias declaration $D$ of the form

\noindent
\code{\TYPEDEF{} \id<\TypeParametersStd> = $T$;}

\noindent
declared in a library $L$.
The effect of $D$ is to introduce \id{} into the library scope of $L$.
When $s = 0$
\commentary{(where the type alias is non-generic)}
\id{} is bound to $T$.
When $s > 0$
\commentary{(where the type alias is generic)}
\id{} is bound to a mapping from a type argument list
\List{U}{1}{s}
to the type
$[U_1/X_1, \ldots, U_s/X_s]T$.

\LMHash{}%
Under the assumption that \List{X}{1}{s} are types such that
$X_j <: B_j$, for all $j \in 1 .. s$,
it is a compile-time error if $T$ is not regular-bounded,
and it is a compile-time error if any type occurring in $T$ is not well-bounded.

\commentary{%
  This means that the bounds declared for
  the formal type parameters of a generic type alias
  must be such that when they are satisfied,
  the bounds that pertain to the body are also satisfied,
  and a type occurring as a subterm of the body can violate its bounds,
  but only if it is a correct super-bounded type.%
}

\LMHash{}%
Moreover,
let $T_1,\ \ldots,\ T_l$ be types
and let $U$ be the parameterized type \code{\id<$T_1, \ldots,\ T_l$>}
in a location where \id{} denotes $D$.
It is a compile-time error if $l \not= s$.
It is a compile-time error if $U$ is not well-bounded
(\ref{superBoundedTypes}).

\LMHash{}%
For historic reasons, a type alias can have two more forms,
derived using \synt{functionTypeAlias}.
Let \DefineSymbol{S?} be a term which is empty or derived from \synt{type},
and similarly for \DefineSymbol{T_j?} for any $j$.
The two older forms are then defined as follows:

\LMHash{}%
A type alias of the form

\noindent
\code{\TYPEDEF{} $S?$ \id<\TypeParametersStd>(}

\noindent
\code{\quad$T_1?\ p_1, \ldots,\ T_n?\ p_n,\ [T_{n+1}?\ p_{n+1}, \ldots,\ T_{n+k}?\ p_{n+k}]$);}

\noindent
is treated as

\noindent
\code{\TYPEDEF{} \id<\TypeParametersStd> =}

\noindent
\code{\quad$S?$ \FUNCTION($T_1\ p_1, \ldots,\ T_n\ p_n,\ [T_{n+1}\ p_{n+1}, \ldots,\ T_{n+k}\ p_{n+k}]$);}

\LMHash{}%
A type alias of the form

\noindent
\code{\TYPEDEF{} $S?$ \id<\TypeParametersStd>(}

\noindent
\code{\quad$T_1?\ p_1, \ldots,\ T_n?\ p_n,\ \{T_{n+1}?\ p_{n+1}, \ldots,\ T_{n+k}?\ p_{n+k}\}$);}

\noindent
is treated as

\noindent
\code{\TYPEDEF{} \id<\TypeParametersStd> =}

\noindent
\code{\quad$S?$ \FUNCTION($T_1\ p_1, \ldots,\ T_n\ p_n,\ \{T_{n+1}\ p_{n+1}, \ldots,\ T_{n+k}\ p_{n+k}\}$);}

\LMHash{}%
In these rules, for each $j$, if $T_j?$ is empty
then \DefineSymbol{T_j} is \DYNAMIC,
otherwise $T_j$ is $T_j?$.

\commentary{%
  This means that the older forms allow for a parameter type to be omitted,
  in which case it is taken to be \DYNAMIC,
  but the parameter name cannot be omitted.
  This behavior is error prone,
  and hence the newer form (with \lit{=}) is recommended.
  For instance, the declaration \code{\TYPEDEF{} $F$(int);}
  specifies that $F$ denotes the type
  \code{\DYNAMIC{} \FUNCTION(\DYNAMIC)},
  and it is documented, but technically ignored,
  that the parameter has the name \code{int}.
  It is extremely likely that a reader will misread this,
  and assume that \code{int} is the parameter type.%
}

\LMHash{}%
It is a compile-time error if a default value is specified for
a formal parameter in these older forms,
or if a formal parameter has the modifier \COVARIANT.

\commentary{%
  Note that the old forms can only define function types,
  and they cannot denote the type of a generic function.
  When such a type alias has type parameters,
  it always expresses a family of non-generic function types.
  These restrictions exist because that syntax was defined
  before generic functions were added to Dart.%
}

\LMHash{}%
Let $D_F$ be a type alias declaration of the form

\noindent
\code{\TYPEDEF{} $F$<\TypeParametersStd> = $T$;}

\noindent
If $T$ or $B_j$ for some $j \in 1 .. s$ is or contains
a \synt{typeName} $G$ denoting a type alias declaration $D_G$,
then we say that
\IndexCustom{$D_F$ depends on $D_G$}{type alias!dependency}.

%%TODO(eernst): The relaxation where a type alias dependency arises
%% via $T$, but not via $B_j$, is more permissive and allows for some
%% type aliases to be declared that will be an error with the above rule.
%% It is very likely that the more relaxed rule can be used. This is a
%% possible enhancement for the future, and a non breaking change.

\LMHash{}%
Let $D$ be a type alias declaration,
and let $M$ be the transitive closure of
the type alias declarations that $D$ depends on.
A compile-time error occurs if $D \in M$.

\commentary{%
  In other words, it is an error for a type alias declaration
  to depend on itself, directly or indirectly.%
}

\commentary{%
  This kind of error may also arise when type arguments have been
  omitted in the program, but are added during static analysis
  via instantiation to bound
  (\ref{instantiationToBound})
  or via type inference,
  which will be specified later
  (\ref{overview}).%
}

\LMHash{}%
When $D$ is a type alias declaration of the form

\noindent
\code{\TYPEDEF{} $F$<\TypeParametersStd> = $T$;}

\noindent
we say that the parameterized type $U$ of the form
\code{$F$<\List{U}{1}{s}>}
in a scope where $F$ resolves to $D$
\IndexCustom{alias expands in one step to}{%
  type alias!alias expands in one step}
$[U_1/X_1, \ldots, U_s/X_s]T$.

\commentary{%
  Note that $s$ can be zero, in which case $F$ is non-generic,
  and we are just replacing the type alias name by its body.%
}

\LMHash{}%
If $U$ is a type we may repeatedly replace each subterm of $U$
which is a parameterized type applying a type alias to some type arguments
by its alias expansion in one step
\commentary{(including the non-generic case where there are no type arguments)}.
When no further steps are possible we say that the resulting type is the
\IndexCustom{transitive alias expansion}{%
  type alias!transitive alias expansion}
of $U$.

\commentary{%
  Note that the transitive alias expansion exists,
  because it is an error for a type alias declaration
  to depend on itself.
  However, it may be large.
  For instance, \code{\TYPEDEF{} $F$<$X$> = Map<$X$, $X$>;} yields
  an exponential size increase for \code{$F$<$F$<\ldots$F$<int>\ldots{}>{}>}.%
}

\LMHash{}%
\BlindDefineSymbol{D, F, T}%
Let $D$ be a type alias declaration of the form

\noindent
\code{\TYPEDEF{} $F$<\TypeParametersStd> = $T$;}

\noindent
and let \DefineSymbol{U} be a type of the form $F$ or \code{$p$.$F$}
in a scope where this term denotes $D$.
Assume that the transitive alias expansion of \code{$F$<\List{X}{1}{s}>} is
\BlindDefineSymbol{C, q}%
a type of the form $C$ or \code{$q$.$C$},
optionally followed by \synt{typeArguments},
where $q$ is an identifier denoting an import prefix,
and $C$ respectively \code{$q$.$C$} denotes a class or mixin
\commentary{(in particular, $C$ can not be a type variable)}.
Assume that $U$ occurs in an expression $e$ of the form
`\code{$U$.\id\;\metavar{args}}'
where \metavar{args} is derived from \syntax{<argumentPart>?},
such that \id{} is the name of
a static member of $C$ respectively \code{$q$.$C$}.
The expression $e$ is then treated as
`\code{$C$.\id\;\metavar{args}}'
respectively
`\code{$q$.$C$.\id\;\metavar{args}}'.

\commentary{%
  This means that it is possible to use a type alias
  to invoke a static member of a class or a mixin.
  For example:%
}

\begin{dartCode}
\CLASS{} C<X> \{
  static void staticMethod() \{\}
\}
\\
\TYPEDEF{} F = C<int>;
\\
\VOID{} main() \{
  F.staticMethod(); // \comment{OK.}
\}
\end{dartCode}

\rationale{%
  Note that the type arguments passed to $C$ respectively \code{$p$.$C$}
  are erased,
  such that the resulting expression can be a correct static member invocation.
  If a future version of Dart allows type arguments to be passed via the class
  in an invocation of a static member,
  it may be preferable to preserve these type arguments.
  At that time,
  existing invocations where type arguments are passed in this manner
  will not break,
  because it is currently an error for a static member to depend on the value
  of a formal type parameter of the enclosing class.%
}

\LMHash{}%
\BlindDefineSymbol{D, F, X_j, B_j}%
Let $D$ be a type alias declaration of the form

\noindent
\code{\TYPEDEF{} $F$<\TypeParametersStd> = $T$;}

\noindent
where $s > 0$.
\BlindDefineSymbol{Y_j}%
Let \List{Y}{1}{s} be fresh type variables,
assumed to satisfy the bounds of $D$.
We say that $D$
\NoIndex{expands to a type variable}
if the transitive alias expansion of
\code{$F$<\List{Y}{1}{s}>}
is $Y_j$ for some $j \in 1 .. s$.

\LMHash{}%
\BlindDefineSymbol{T, F, D}%
Let $T$ be a parameterized type \code{$F$<\List{T}{1}{s}>}
(where $s$ can be zero)
in a scope where $F$ denotes a type alias declaration $D$.
We say that $T$
\IndexCustom{uses $D$ as a class}{type alias!used as a class}
when $T$ occurs in one of the following ways:

\begin{itemize}
\item
  $T$ occurs in an instance creation expression of the form
  \code{$nc$ $T$(\ldots)} or the form \code{$nc$ $T$.\id(\ldots)},
  where $nc$ is either \NEW{} or \CONST{}
  (\ref{instanceCreation}).
  \commentary{%
    Note that, e.g., \code{$T$(42)} may be an instance creation,
    but it is then treated as \code{\NEW{} $T$(42)} or \code{\CONST{} $T$(42)},
    which means that it is included here
    (\ref{unqualifiedInvocation}).%
  }
\item
  $T$ or \code{$T$.\id} is the redirectee in a redirecting factory constructor,
  (\ref{redirectingFactoryConstructors}).
\item
  $T$ is used as a superclass, a mixin, or a superinterface
  in a class declaration
  (\ref{superclasses}, \ref{mixinApplication}, \ref{superinterfaces}),
  or as an \ON{} type or a superinterface in a mixin declaration
  (\ref{mixinDeclaration}).
  % It is OK to use it as the \ON{} type of an extension declaration:
  % In that position it is used as a type, not as a class.
\item
  $T$ is used to invoke a static member of a class or mixin,
  as described above.
\end{itemize}

\LMHash{}%
A compile-time error occurs if $D$ expands to a type variable,
and $T$ uses $D$ as a class.
A compile-time error occurs if $T$ uses $D$ as a class,
and $T$ is not regular-bounded.
\commentary{For example:}

\begin{dartCode}
\CLASS{} C<X extends num> \{\}
\TYPEDEF{} F<Y extends int> = C<Y>;
\TYPEDEF{} G<Z> = Z;
\\
\VOID{} main() \{
  F<int>(); // \comment{OK.}
  C<num>(); // \comment{OK.}
  F<num>(); // \comment{Error.}
  G<C<int>{}>(); // \comment{Error.}
\}
\end{dartCode}

\LMHash{}%
When we use phrases like `let $S$ be a class' or `assume that $S$ is a mixin',
it is understood that this includes the case where
$S$ is a \synt{typeName} denoting a type alias, or
$S$ is a parameterized type of the form
\syntax{<typeName> <typeArguments>}
where the type name denotes a type alias,
and the transitive alias expansion of $S$ denotes a class respectively a mixin.


\subsection{Subtypes}
\LMLabel{subtypes}

\LMHash{}%
This section defines when a type is a \Index{subtype} of another type.
The core of this section is the set of rules defined in
Figure~\ref{fig:subtypeRules},
but we will need to introduce a few concepts first,
in order to clarify what those rules mean.

\commentary{%
  A reader who has read many research papers about object-oriented type systems
  may find the meaning of the given notation obvious,
  but we still need to clarify a few details about how to handle
  syntactically different denotations of the same type,
  and how to choose the right initial environment, $\Delta$.
  %
  For a reader who is not familiar with the notation used in this section,
  the explanations given here should suffice to clarify what it means,
  with reference to the natural language explanations given at the end of
  the section for obtaining an intuition about the meaning.%
}

\LMHash{}%
This section is concerned with subtype relationships between types
during static analysis
as well as subtype relationships as queried in dynamic checks,
type tests
(\ref{typeTest}),
and type casts
(\ref{typeCast}).

\commentary{%
  A variant of the rules described here is shown in an appendix
  (\ref{algorithmicSubtyping}),
  demonstrating that Dart subtyping can be decided efficiently.%
}

\LMHash{}%
%% TODO(eernst): Introduce these specialized intersection types
%% in a suitable location where type promotion is specified.
Types of the form
\IndexCustom{$X \& S$}{type!of the form $X \& S$}%
\IndexExtraEntry{\&@$X \& S$}
arise during static analysis due to type promotion
(\ref{typePromotion}).
They never occur during execution,
they are never a type argument of another type,
nor a return type or a formal parameter type,
and it is always the case that $S$ is a subtype of the bound of $X$.
\commentary{%
  The motivation for $X \& S$ is that it represents
  the type of a local variable $v$
  whose type is declared to be the type variable $X$,
  and which is known to have type $S$ due to promotion.
  Similarly, $X \& S$ may be seen as an intersection type,
  which is a subtype of $X$ and also a subtype of $S$.
  Intersection types are \emph{not} supported in general,
  only in this special case.%
}
Every other form of type may occur during static analysis
as well as during execution,
and the subtype relationship is always determined in the same way.

% Subtype Rule Numbering
\newcommand{\SrnReflexivity}{1}
\newcommand{\SrnTop}{2}
\newcommand{\SrnBottom}{3}
\newcommand{\SrnNull}{4}
\newcommand{\SrnLeftTypeAlias}{5}
\newcommand{\SrnRightTypeAlias}{6}
\newcommand{\SrnLeftFutureOr}{7}
\newcommand{\SrnTypeVariableReflexivityA}{8}
\newcommand{\SrnRightPromotedVariable}{9}
\newcommand{\SrnRightFutureOrA}{10}
\newcommand{\SrnRightFutureOrB}{11}
\newcommand{\SrnLeftPromotedVariable}{12}
\newcommand{\SrnLeftVariableBound}{13}
\newcommand{\SrnRightFunction}{14}
\newcommand{\SrnPositionalFunctionType}{15}
\newcommand{\SrnNamedFunctionType}{16}
\newcommand{\SrnCovariance}{17}
\newcommand{\SrnSuperinterface}{18}

\begin{figure}[p]
  \def\VSP{\vspace{4mm}}
  \def\ExtraVSP{\vspace{2mm}}
  \def\Axiom#1#2#3#4{\centerline{\inference[#1]{}{\SubtypeStd{#3}{#4}}}\VSP}
  \def\Rule#1#2#3#4#5#6{\centerline{\inference[#1]{\SubtypeStd{#3}{#4}}{\SubtypeStd{#5}{#6}}}\VSP}
  \def\RuleTwo#1#2#3#4#5#6#7#8{%
    \centerline{\inference[#1]{\SubtypeStd{#3}{#4} & \SubtypeStd{#5}{#6}}{\SubtypeStd{#7}{#8}}}\VSP}
  \def\RuleRaw#1#2#3#4#5{%
    \centerline{\inference[#1]{#3}{\SubtypeStd{#4}{#5}}}\VSP}
  \def\RuleRawRaw#1#2#3#4{\centerline{\inference[#1]{#3}{#4}}\VSP}
  %
  \begin{minipage}[c]{0.49\textwidth}
    \Axiom{\SrnReflexivity}{Reflexivity}{S}{S}
    \Axiom{\SrnBottom}{Left Bottom}{\bot}{T}
  \end{minipage}
  \begin{minipage}[c]{0.49\textwidth}
    \RuleRaw{\SrnTop}{Right Top}{T \in \{\code{Object}, \DYNAMIC, \VOID\}}{S}{T}
    \RuleRaw{\SrnNull}{Left Null}{T \not= \bot}{\code{Null}}{T}
  \end{minipage}

  \ExtraVSP
  \RuleRaw{\SrnLeftTypeAlias}{Type Alias Left}{%
    \code{\TYPEDEF{} $F$<\TypeParametersNoBounds{X}{s}> = U} &
    \SubtypeStd{[S_1/X_1,\ldots,S_s/X_s]U}{T}}{\code{$F$<\List{S}{1}{s}>}}{T}
  \RuleRaw{\SrnRightTypeAlias}{Type Alias Right}{%
    \code{\TYPEDEF{} $F$<\TypeParametersNoBounds{X}{s}> = U} &
    \SubtypeStd{S}{[T_1/X_1,\ldots,T_s/X_s]U}}{S}{\code{$F$<\List{T}{1}{s}>}}

  \begin{minipage}[c]{0.49\textwidth}
    \RuleTwo{\SrnLeftFutureOr}{Left FutureOr}{S}{T}{%
      \code{Future<$S$>}}{T}{\code{FutureOr<$S$>}}{T}
    \RuleTwo{\SrnRightPromotedVariable}{Right Promoted Variable}{S}{X}{S}{T}{%
      S}{X \& T}
    \Rule{\SrnRightFutureOrB}{Right FutureOr B}{S}{T}{S}{\code{FutureOr<$T$>}}
    \Rule{\SrnLeftVariableBound}{Left Variable Bound}{\Delta(X)}{T}{X}{T}
  \end{minipage}
  \begin{minipage}[c]{0.49\textwidth}
    \Axiom{\SrnTypeVariableReflexivityA}{Left Promoted Variable A}{X \& S}{X}
    \Rule{\SrnRightFutureOrA}{Right FutureOr A}{S}{\code{Future<$T$>}}{%
      S}{\code{FutureOr<$T$>}}
    \Rule{\SrnLeftPromotedVariable}{Left Promoted Variable B}{S}{T}{X \& S}{T}
    \RuleRaw{\SrnRightFunction}{Right Function}{T\mbox{ is a function type}}{%
      T}{\FUNCTION}
  \end{minipage}
  %
  \ExtraVSP
  \RuleRawRaw{\SrnPositionalFunctionType}{Positional Function Types}{%
    \Delta' = \Delta\uplus\{X_i\mapsto{}B_i\,|\,1 \leq i \leq s\} &
    \Subtype{\Delta'}{S_0}{T_0} \\
    n_1 \leq n_2 &
    n_1 + k_1 \geq n_2 + k_2 &
    \forall j \in 1 .. n_2 + k_2\!:\;\Subtype{\Delta'}{T_j}{S_j}}{%
    \begin{array}{c}
      \Delta\vdash\RawFunctionTypePositional{S_0}{X}{B}{s}{S}{n_1}{k_1}\;<:\;\\
      \RawFunctionTypePositional{T_0}{X}{B}{s}{T}{n_2}{k_2}
    \end{array}}
  \ExtraVSP\ExtraVSP
  \RuleRawRaw{\SrnNamedFunctionType}{Named Function Types}{%
    \Delta' = \Delta\uplus\{X_i\mapsto{}B_i\,|\,1 \leq i \leq s\} &
    \Subtype{\Delta'}{S_0}{T_0} &
    \forall j \in 1 .. n\!:\;\Subtype{\Delta'}{T_j}{S_j} \\
    \{\,\List{y}{n+1}{n+k_2}\,\} \subseteq \{\,\List{x}{n+1}{n+k_1}\,\} \\
    \forall p \in 1 .. k_2, q \in 1 .. k_1:\quad
    y_{n+p} = x_{n+q}\quad\Rightarrow\quad\Subtype{\Delta'}{T_{n+p}}{S_{n+q}}}{%
    \begin{array}{c}
      \Delta\vdash\RawFunctionTypeNamed{S_0}{X}{B}{s}{S}{n}{x}{k_1}{r}\;<:\;\\
      \RawFunctionTypeNamed{T_0}{X}{B}{s}{T}{n}{y}{k_2}{r}
    \end{array}}
  %
  \ExtraVSP
  \RuleRaw{\SrnCovariance}{Covariance}{%
    \code{\CLASS{} $C$<\TypeParametersNoBounds{X}{s}>\,\ldots\,\{\}} &
    \forall j \in 1 .. s\!:\;\SubtypeStd{S_j}{T_j}}{%
    \code{$C$<\List{S}{1}{s}>}}{\code{$C$<\List{T}{1}{s}>}}
  \ExtraVSP
  \RuleRaw{\SrnSuperinterface}{Superinterface}{%
    \code{\CLASS{} $C$<\TypeParametersNoBounds{X}{s}>\,\ldots\,\{\}}\\
    \Superinterface{\code{$D$<\List{T}{1}{m}>}}{C} &
    \SubtypeStd{[S_1/X_1,\ldots,S_s/X_s]\code{$D$<\List{T}{1}{m}>}}{T}}{%
    \code{$C$<\List{S}{1}{s}>}\;}{\;T}
  %
  \caption{Subtype rules.}
  \label{fig:subtypeRules}
\end{figure}


\subsubsection{Meta-Variables}
\LMLabel{metaVariables}

\LMHash{}%
A \Index{meta-variable} is a symbol which stands for a syntactic construct
that satisfies some static semantic requirements.

\commentary{%
  For instance, $X$ is a meta-variable standing for
  an identifier \code{W},
  but only if \code{W} denotes a type variable declared in an enclosing scope.
  In the definitions below, we specify this by saying that
  `$X$ ranges over type variables'.
  Similarly, $C$ is a meta-variable standing for
  a \synt{typeName}, for instance, \code{p.D},
  but only if \code{p.D} denotes a class in the given scope.
  We specify this as `$C$ ranges over classes'.%
}

\LMHash{}%
In this section we use the following meta-variables:

\begin{itemize}
\item $X$ ranges over type variables.
\item $C$ ranges over classes,
\item $F$ ranges over type aliases.
\item $T$ and $S$ range over types, possibly with an index like $T_1$ or $S_j$.
\item $B$ ranges over types, again possibly with an index;
  it is only used as a type variable bound.
\end{itemize}


\subsubsection{Subtype Rules}
\LMLabel{subtypeRules}

\LMHash{}%
We define several rules about subtyping in this section.
Whenever a rule contains one or more meta-variables,
that rule can be used by
\IndexCustom{instantiating}{instantiation!subtype rule}
it, that is, by consistently replacing
each occurrence of a given meta-variable by
concrete syntax denoting the same type.

\commentary{%
  In general, this means that two or more occurrences of
  a given meta-variable in a rule
  stands for identical pieces of syntax,
  and the instantiation of the rule proceeds as
  a simple search-and-replace operation.
  For instance,
  rule~\SrnReflexivity{} in Figure~\ref{fig:subtypeRules}
  can be used to conclude
  \Subtype{\emptyset}{\code{int}}{\code{int}},
  where $\emptyset$ denotes the empty environment
  (any environment would suffice because no type variables occur).

  However, the wording `denoting the same type' above covers
  additional situations as well:
  For instance, we may use rule~\SrnReflexivity{}
  to show that \code{p1.C} is a subtype of
  \code{p2.C} when \code{C} is a class declared in a
  library $L$ which is imported by libraries $L_1$ and $L_2$ and
  used in declarations there,
  when $L_1$ and $L_2$ are imported with prefixes
  \code{p1} respectively \code{p2} by the current library.
  The important point is that all occurrences of the same meta-variable
  in a given rule instantiation stands for the same type,
  even in the case where that type is not denoted by
  the same syntax in both cases.

  Conversely, we can \emph{not} use the same rule to conclude
  that \code{C} is a subtype of \code{C}
  in the case where the former denotes a class declared in library $L_1$
  and the latter denotes a class declared in $L_2$, with $L_1 \not= L_2$.
  This situation can arise without compile-time errors, e.g.,
  if $L_1$ and $L_2$ are imported indirectly into the current library
  and the two ``meanings'' of \code{C} are used
  as type annotations on variables or formal parameters of functions
  declared in intermediate libraries importing $L_1$ respectively $L_2$.
  The failure to prove
  ``\Subtype{\emptyset}{\code{C}}{\code{C}}''
  will then occur, e.g., in a situation where we check whether
  such a variable can be passed as an actual argument to such a function,
  because the two occurrences of \code{C} do not denote the same type.%
}

\LMHash{}%
Every \synt{typeName} used in a type mentioned in this section is assumed to
have no compile-time error and denote a type.

\commentary{%
  That is, no subtyping relationship can be proven for
  a type that is or contains an undefined name
  or a name that denotes something other than a type.
  Note that it is not necessary in order to determine a subtyping relationship
  that every type satisfies the declared bounds,
  the subtyping relation does not depend on bounds.
  However, if an attempt is made to prove a subtype relationship
  and one or more \synt{typeName}s receives an actual type argument list
  whose length does not match the declaration
  (including the case where some type arguments are given
  to a non-generic class,
  and the case where a generic class occurs,
  but no type arguments are given)
  then the attempt to prove the relationship simply fails.%
}

\LMHash{}%
The rules in Figure~\ref{fig:subtypeRules} use
the symbol \Index{$\Delta$} to denote the given knowledge about the
bounds of type variables.
$\Delta$ is a partial function that maps type variables to types.
At a given location where the type variables in scope are
\TypeParametersStd{}
\commentary{(as declared by enclosing classes and/or functions)},
we define the environment as follows:
$\Delta = \{\,X_1 \mapsto B_1,\ \ldots\ X_s \mapsto B_s\,\}$.
\commentary{%
  That is, $\Delta(X_1) = B_1$, and so on,
  and $\Delta$ is undefined when applied to a type variable $Y$
  which is not in $\{\,\List{X}{1}{s}\,\}$.%
}
When the rules are used to show that a given subtype relationship exists,
this is the initial value of $\Delta$.

\LMHash{}%
If a generic function type is encountered, an extension of $\Delta$ is used,
as shown in the rules~\SrnPositionalFunctionType{}
and~\SrnNamedFunctionType{}
of Figure~\ref{fig:subtypeRules}.
Extension of environments uses the operator \Index{$\uplus$},
which is the operator that produces the union of disjoint sets,
and gives priority to the right hand operand in case of conflicts.

\commentary{%
  So
  $\{ \code{X} \mapsto \code{int}, \code{Y} \mapsto \code{double} \} \uplus
  \{ \code{Z} \mapsto \code{Object} \} =
  \{ \code{X} \mapsto \code{int}, \code{Y} \mapsto \code{double}, \code{Z} \mapsto \code{Object} \}$
  and
  $\{ \code{X} \mapsto \code{int}, \code{Y} \mapsto \code{FutureOr<List<double>{}>} \} \uplus
  \{ \code{Y} \mapsto \code{int} \} =
  \{ \code{X} \mapsto \code{int}, \code{Y} \mapsto \code{int} \}$.
  Note that operator $\uplus$ is concerned with scopes and shadowing,
  with no connection to, e.g., subtypes or instance method overriding.%
}

\LMHash{}%
In this specification we frequently refer to
subtype relationships and assignability
without mentioning the environment explicitly,
as in \Index{\SubtypeNE{S}{T}}.
This is only done when a specific location in code is in focus,
and it means that the environment is that which is obtained
by mapping each type variable in scope at that location
to its declared bound.

\LMHash{}%
Each rule in Figure~\ref{fig:subtypeRules} has a horizontal line,
to the left of which the \Index{rule number} is indicated;
under the horizontal line there is a judgment which is the
\IndexCustom{conclusion}{rule!conclusion}
of the rule,
and above the horizontal line there are zero or more
\IndexCustom{premises}{rule!premise}
of the rule,
which are typically also subtype judgments.
When that is not the case for a given premise,
we specify the meaning explicitly.

\commentary{%
  Instantiation of a rule, mentioned above,
  denotes the consistent replacement of meta-variables
  by actual syntactic terms denoting types everywhere in the rule,
  that is, in the premises as well as in the conclusion, simultaneously.%
}


\subsubsection{Being a subtype}
\LMLabel{beingASubtype}

\LMHash{}%
A type $S$ is shown to be a \Index{subtype} of another type $T$
in an environment $\Delta$ by providing
an instantiation of a rule $R$ whose conclusion is
\IndexCustom{\SubtypeStd{S}{T}}{$\Delta$@\SubtypeStd{S}{T}},
along with rule instantiations showing
each of the premises of $R$,
continuing until a rule with no premises is reached.

\commentary{%
  For rule \SrnNull, note that the \code{Null} type
  is a subtype of all non-$\bot$ types,
  even though it doesn't actually extend or implement those types.
  The other types are effectively treated as if they were nullable,
  which makes the null object (\ref{null}) assignable to them.%
}

\LMHash{}%
The first premise in the
rules~\SrnLeftTypeAlias{} and~\SrnRightTypeAlias{}
is a type alias declaration.
This premise is satisfied in each of the following situations:

\begin{itemize}
\item A non-generic type alias named $F$ is declared.
  In this case $s$ is zero,
  no assumptions are made about the existence
  of any formal type parameters,
  and actual type argument lists are omitted everywhere in the rule.
\item We may choose $s$ and \List{X}{1}{s} such that the following holds:
  A generic type alias named $F$ is declared,
  with formal type parameters \List{X}{1}{s}.
  \commentary{%
    Each formal type parameter $X_j$ may have a bound,
    but the bounds are never used in this context,
    so we do not introduce metavariables for them.%
  }
\end{itemize}

\LMHash{}%
Rule~\SrnRightFunction{} has as a premise that `$T$ is a function type'.
This means that $T$ is a type of one of the forms introduced in
section~\ref{typeOfAFunction}.
\commentary{%
  This is the same as the forms of type that occur at top level
  in the conclusions of
  rule~\SrnPositionalFunctionType{} and
  rule~\SrnNamedFunctionType.%
}

\LMHash{}%
In rules~\SrnCovariance{} and~\SrnSuperinterface,
the first premise is a class declaration.
This premise is satisfied in each of the following situations:

\begin{itemize}
\item A non-generic class named $C$ is declared.
  In this case $s$ is zero,
  no assumptions are made about the existence
  of any formal type parameters,
  and actual type argument lists are omitted everywhere in the rule.
\item We may choose $s$ and \List{X}{1}{s} such that the following holds:
  A generic class named $C$ is declared,
  with formal type parameters \List{X}{1}{s}.
  \commentary{%
    Each formal type parameter $X_j$ may have a bound,
    but the bounds are never used in this context,
    so we do not introduce metavariables for them.%
  }
\end{itemize}

\LMHash{}%
The second premise of rule~\SrnSuperinterface{} specifies that
a parameterized type \code{$D$<\ldots{}>} belongs to
\IndexCustom{\Superinterfaces{C}}{superinterfaces(C)@\Superinterfaces{C}}.
The semantic function \Superinterfaces{\_} applied to a generic class $C$ yields
the set of direct superinterfaces of $C$
(\ref{superinterfaces}).

\commentary{%
  Note that one of the direct superinterfaces of $C$ is
  the interface of the superclass of $C$,
  and that may be a mixin application
  (\ref{mixinApplication}),
  in which case $D$ in the rule is
  the synthetic class which specifies
  the semantics of that mixin application.%
}

\commentary{%
  The last premise of rule~\SrnSuperinterface{}
  substitutes the actual type arguments \List{S}{1}{s} for the
  formal type parameters \List{X}{1}{s},
  because \List{T}{1}{m} may contain those formal type parameters.%
}

\commentary{%
  The rules~\SrnCovariance{} and~\SrnSuperinterface{}
  are applicable to interfaces,
  but they can be used with classes as well,
  because a non-generic class $C$ which is used as a type
  denotes the interface of $C$,
  and similarly for a parameterized type
  \code{$C$<\List{T}{1}{k}>}
  where $C$ denotes a generic class.%
}


\subsubsection{Informal Subtype Rule Descriptions}
\LMLabel{informalSubtypeRuleDescriptions}

\commentary{%
  This section gives an informal and non-normative natural language description
  of each rule in Figure~\ref{fig:subtypeRules}.

  The descriptions use the rule numbers to make the connection explicit,
  and also adds names to the rules that may be helpful in order to understand
  the role played by each rule.

  In the following, many rules contain meta-variables
  (\ref{metaVariables})
  like $S$ and $T$,
  and it is always the case that they can stand for arbitrary types.
  For example, rule~\SrnRightFutureOrA{} says that
  ``The type $S$ is a \ldots{} of \code{FutureOr<$T$>} \ldots'',
  and this is taken to mean that for any arbitrary types $S$ and $T$,
  showing that $S$ is a subtype of $T$ is sufficient to show that $S$ is
  a subtype of \code{FutureOr<$T$>}.

  Another example is the wording in rule~\SrnReflexivity{}:
  ``\ldots{} in any environment $\Delta$'',
  which indicates that the rule can be applied no matter which bindings
  of type variables to bounds there exist in the environment.
  It should be noted that the environment matters even with rules
  where it is simply stated as a plain $\Delta$ in the conclusion
  and in one or more premises,
  because the proof of those premises could, directly or indirectly,
  include the application of a rule where the environment is used.

  \def\Item#1#2{\item[#1]{\textbf{#2:}}}
  \begin{itemize}
  \Item{\SrnReflexivity}{Reflexivity}
    Every type is a subtype of itself, in any environment $\Delta$.
    In the following rules except for a few,
    the rule is also valid in any environment
    and the environment is never used explicitly,
    so we will not repeat that.
  \Item{\SrnTop}{Top}
    Every type is a subtype of \code{Object},
    every type is a subtype of \DYNAMIC,
    and every type is a subtype of \VOID.
    Note that this implies that these types are equivalent
    according to the subtype relation.
    We denote these types,
    and others with the same property (such as \code{FutureOr<Object>}),
    as top types
    (\ref{superBoundedTypes}).
  \Item{\SrnBottom}{Bottom}
    Every type is a supertype of $\bot$.
  \Item{\SrnNull}{Null}
    Every type other than $\bot$ is a supertype of \code{Null}.
  \Item{\SrnLeftTypeAlias}{Type Alias Left}
    An application of a type alias to some actual type arguments is
    a subtype of another type $T$
    if the expansion of the type alias to the type that it denotes
    is a subtype of $T$.
    Note that a non-generic type alias is handled by letting $s = 0$.
  \Item{\SrnRightTypeAlias}{Type Alias Right}
    A type $S$ is a subtype of an application of a type alias
    if $S$ is a subtype of
    the expansion of the type alias to the type that it denotes.
    Note that a non-generic type alias is handled by letting $s = 0$.
  \Item{\SrnLeftFutureOr}{Left FutureOr}
    The type \code{FutureOr<$S$>} is a subtype of a given type $T$
    if $S$ is a subtype of $T$ and \code{Future<$S$>} is a subtype of $T$,
    for every type $S$ and $T$.
  \Item{\SrnTypeVariableReflexivityA}{Left Promoted Variable}
    The type $X \& S$ is a subtype of $X$.
  \Item{\SrnRightPromotedVariable}{Right Promoted Variable A}
    The type $S$ is a subtype of $X \& T$ if
    $S$ is a subtype of both $X$ and $T$.
  \Item{\SrnRightFutureOrA}{Right FutureOr A}
    The type $S$ is a subtype of \code{FutureOr<$T$>} if
    $S$ is a subtype of \code{Future<$T$>}.
  \Item{\SrnRightFutureOrB}{Right FutureOr B}
    The type $S$ is a subtype of \code{FutureOr<$T$>} if
    $S$ is a subtype of $T$.
  \Item{\SrnLeftPromotedVariable}{Left Promoted Variable B}
    The type $X \& S$ is a subtype of $T$ if
    $S$ is a subtype of $T$.
  \Item{\SrnLeftVariableBound}{Left Variable Bound}
    The type variable $X$ is a subtype of a type $T$ if
    the bound of $X$
    (as specified in the current environment $\Delta$)
    is a subtype of $T$.
  \Item{\SrnRightFunction}{Right Function}
    Every function type is a subtype of the type \FUNCTION.
  \Item{\SrnPositionalFunctionType}{Positional Function Type}
    A function type $F_1$ with positional optional parameters
    is a subtype of
    another function type $F_2$ with positional optional parameters
    if the former has at most
    the same number of required parameters as the latter,
    and the latter has at least
    the same total number of parameters as the former;
    the return type of $F_1$ is a subtype of that of $F_2$;
    and each parameter type of $F_1$ is a \emph{supertype} of
    the corresponding parameter type of $F_2$, if any.
    Note that the relationship to function types with no optional parameters,
    and the relationship between function types with no optional parameters,
    is covered by letting $k_2 = 0$ respectively $k_1 = k_2 = 0$.
    For every subtype relation considered in this rule,
    the formal type parameters of $F_1$ and $F_2$ must be taken into account
    (as reflected in the use of the extended environment $\Delta'$).
    We can assume without loss of generality
    that the names of type variables are pairwise identical,
    because we consider types of generic functions to be equivalent under
    consistent renaming
    (\ref{typeOfAFunction}).
    In short, ``during the proof, we will rename them as needed''.
    Finally, note that the relationship between non-generic function types
    is covered by letting $s = 0$.
  \Item{\SrnNamedFunctionType}{Named Function Type}
    A function type $F_1$ with named optional parameters is a subtype of
    another function type $F_2$ with named optional parameters
    if they have the same number of required parameters,
    and the set of names of named parameters for the latter is a subset
    of that for the former;
    the return type of $F_1$ is a subtype of that of $F_2$;
    and each parameter type of $F_1$ is a \emph{supertype} of
    the corresponding parameter type of $F_2$, if any.
    Note that the relationship to function types with no optional parameters,
    and the relationship between function types with no optional parameters,
    is covered by letting $k_2 = 0$ respectively $k_1 = k_2 = 0$,
    and also that the latter case is identical to the rule obtained from
    rule~\SrnPositionalFunctionType{}
    concerning subtyping among function types with no optional parameters.
    As in rule~\SrnPositionalFunctionType,
    we can assume without loss of generality
    that the names of type variables are pairwise identical.
    Similarly, non-generic functions are covered by letting $s = 0$.
  \Item{\SrnCovariance}{Class Covariance}
    A parameterized type based on a generic class $C$ is a subtype of
    a parameterized type based on the same class $C$ if
    each actual type argument of the former is a subtype of
    the corresponding actual type argument of the latter.
    This rule may have $s = 0$ and cover a non-generic class as well,
    but that is redundant because this is already covered by
    rule~\SrnReflexivity.
  \Item{\SrnSuperinterface}{Superinterface}
    Considering the case where $s = 0$ and $m = 0$ first,
    a parameterized type based on a non-generic class $C$ is a subtype of
    a parameterized type based on a different non-generic class $D$ if
    $D$ is a direct superinterface of $C$.
    When $s > 0$ or $m > 0$, this rule describes a subtype relationship
    which includes one or more generic classes,
    in which case we need to give names to the formal type parameters of $C$,
    and specify how they are used in the specification of the superinterface
    based on $D$.
    With those pieces in place, we can specify the subtype relationship
    that exists between two parameterized types based on $C$ and $D$.
    %
    %% TODO(eernst): Note that the specification of how to pass type arguments
    %% in \ref{mixinApplication} is incorrect, and also that it will need to be
    %% rewritten completely for the integration of the new mixin construct.
    The case where the superclass is a mixin application is covered via
    the equivalence with a declaration of
    a regular (possibly generic) superclass
    (\ref{mixinApplication}),
    and this means that there may be multiple subtype steps from
    a given class declaration to the class specified in an \EXTENDS{} clause.
  \end{itemize}%
}


\subsubsection{Additional Subtyping Concepts}
\LMLabel{additionalSubtypingConcepts}

\LMHash{}%
$S$ is a \Index{supertype} of $T$ in a given environment $\Delta$,
written \SupertypeStd{S}{T},
if{}f \SubtypeStd{T}{S}.

\LMHash{}%
A type $T$
\Index{may be assigned}
to a type $S$ in an environment $\Delta$,
written \AssignableStd{S}{T},
if{}f either \SubtypeStd{S}{T} or \SubtypeStd{T}{S}.
In this case we say that the types $S$ and $T$ are
\Index{assignable}.

\rationale{%
  This rule may surprise readers accustomed to conventional typechecking.
  The intent of the \AssignableRelationSymbol{} relation
  is not to ensure that an assignment is guaranteed to succeed dynamically.
  Instead, it aims to only flag assignments
  that are almost certain to be erroneous,
  without precluding assignments that may work.

  For example, assigning an object of static type \code{Object}
  to a variable with static type \code{String},
  while not guaranteed to be correct,
  might be fine if the run-time value happens to be a string.

  A static analyzer or compiler
  may support more strict static checks as an option.%
}


\subsection{Function Types}
\LMLabel{functionTypes}

\LMHash{}%
\IndexCustom{Function types}{type!function}
come in two variants:

\begin{enumerate}
\item
  The types of functions that only have positional parameters.
  These have the general form
  \FunctionTypePositionalStd{T}.
\item
  The types of functions with named parameters.
  These have the general form
  \FunctionTypeNamedStd{T}.
\end{enumerate}

\commentary{%
  Note that the non-generic case is covered by having $s = 0$,
  in which case the type parameter declarations are omitted
  (\ref{generics}).
  The case with no optional parameters is covered by having $k = 0$;
  note that all rules involving function types of the two kinds
  coincide in this case.%
}

\LMHash{}%
Two function types are considered equal if consistent renaming of type
parameters can make them identical.

\commentary{%
  A common way to say this is that we do not distinguish
  function types which are alpha-equivalent.
  For the subtyping rule below this means we can assume that
  a suitable renaming has already taken place.
  In cases where this is not possible
  because the number of type parameters in the two types differ
  or the bounds are different,
  no subtype relationship exists.%
}

\LMHash{}%
A function object is always an instance of some class $C$ that implements
the class \FUNCTION{} (\ref{functionType}),
and which has a method named \CALL,
whose signature is the function type $C$ itself.
\commentary{%
  Consequently, all function types are subtypes of \FUNCTION{}
  (\ref{subtypes}).%
}


\subsection{Type \FUNCTION}
\LMLabel{functionType}

\LMHash{}%
The built-in class \FUNCTION{} is a supertype of all function types
(\ref{functionTypes}).
It is impossible to extend, implement, or mix in the class \FUNCTION.

\LMHash{}%
If a class declaration or mixin application has \FUNCTION{} as superclass,
it instead uses \code{Object} as superclass.

\LMHash{}%
If a class or mixin declaration implements \FUNCTION, it has no effect.
It is as if the \FUNCTION{} was removed from the \code{implements} clause
(and if it's the only implemented interface, the entire clause is removed).
The resulting class or mixin interface
does not have \FUNCTION{} as a superinterface.

\LMHash{}%
If a mixin application mixes \FUNCTION{} onto a superclass, it follows the
normal rules for mixin-application, but since the result of that mixin
application is equivalent to a class with \code{implements Function}, and
that clause has no effect, the resulting class also does not
implement \FUNCTION.
\commentary{%
  The \FUNCTION{} class declares no concrete instance members,
  so the mixin application creates a sub-class of
  the superclass with no new members and no new interfaces.%
}

\rationale{%
  Since using \FUNCTION{} in these ways has no effect, it would be
  reasonable to disallow it completely, like we do extending, implementing or
  mixing in types like \code{int} or \code{String}.
  For backwards compatibility with Dart 1 programs,
  the syntax is allowed to remain, even if it has no effect.
  Tools may choose to warn users that their code has no effect.%
}


\subsection{Type \DYNAMIC}
\LMLabel{typeDynamic}

\LMHash{}%
The type \DYNAMIC{} is a static type which is a supertype of all other types,
just like \code{Object},
but it differs from other types in that the static analysis
assumes that every member access has a corresponding member
with a signature that admits the given access.

\commentary{%
  For instance,
  when the receiver in an ordinary method invocation has type \DYNAMIC,
  any method name can be invoked,
  with any number of type arguments or none,
  with any number of positional arguments,
  and any set of named arguments,
  of any type,
  without error.
  Note that the invocation will still cause a compile-time error
  if there is an error in one or more arguments or other subterms.%
}

\LMHash{}%
% Inference is assumed to have taken place, so the type was not inferred.
If no static type annotation has been provided,
the type system considers declarations to have type \DYNAMIC.
%% TODO(eernst): Change when adding specification of instantiate-to-bound.
If a generic type is used but type arguments are not provided,
the type arguments default to type \DYNAMIC.

\commentary{%
  %% TODO(eernst): Amend when adding specification of instantiate-to-bound.
  This means that given a generic declaration
  \code{$G$<$P_1, \ldots,\ P_n$>$\ldots$},
  where $P_i$ is a formal type parameter declaration, $i \in 1 .. n$,
  the type $G$ is equivalent to

  \noindent
  \code{$G$<$\DYNAMIC, \ldots,\ \DYNAMIC{}$>}.%
}

\LMHash{}%
The built-in type declaration \code{dynamic},
which is declared in the library \code{dart:core},
denotes the \DYNAMIC{} type.
When the name \DYNAMIC{} exported by \code{dart:core} is evaluated
as an expression,
it evaluates to a \code{Type} object representing the \DYNAMIC{} type,
even though \DYNAMIC{} is not a class.

\commentary{%
  This \code{Type} object must compare equal to the corresponding \code{Type}
  objects for \code{Object} and \VOID{} according to operator \lit{==}
  (\ref{dynamicTypeSystem}).%
}

\LMHash{}%
To improve the precision of static types,
member accesses on a receiver of type \DYNAMIC{} that refer to
declarations of the built-in class \code{Object}
are given the static type corresponding to those declarations
whenever doing so is sound.

\begin{itemize}
\item
  Let $e$ be an expression of the form \code{$d$.\id},
  which is not followed by an argument part,
  where the static type of $d$ is \DYNAMIC,
  and \id{} is the name of a getter declared in \code{Object};
  if the return type of \code{Object.\id} is $T$ then
  the static type of $e$ is $T$.
  \commentary{%
    For instance, \code{d.hashCode} has type \code{int}
    and \code{d.runtimeType} has type \code{Type}.%
  }

\item
  Let $e$ be an expression of the form \code{$d$.\id},
  which is not followed by an argument part,
  where the static type of $d$ is \DYNAMIC,
  and \id{} is the name of a method declared in \code{Object}
  whose method signature has type $F$
  \commentary{(which is a function type)}.
  The static type of $e$ is then $F$.
  \commentary{%
    For instance, \code{$d$.toString} has type \code{String \FUNCTION()}.%
  }

\item
  Let $e$ be an expression which is of the form
  \code{$d$.\id(\metavar{arguments})}
  or the form \code{$d$.\id<\metavar{typeArguments}>(\metavar{arguments})},
  where the static type of $d$ is \DYNAMIC,
  \id{} is the name of a getter declared in \code{Object} with return type $F$,
  \metavar{arguments} are derived from \synt{arguments}, and
  \metavar{typeArguments} are derived from \synt{typeArguments}, if present.
  Static analysis will then process $e$ as a function expression invocation
  where an object of static type $F$ is applied to the given argument part.
  \commentary{%
    So this is always a compile-time error.
    For instance, \code{$d$.runtimeType(42)} is a compile-time error,
    because it is checked as a
    function expression invocation where
    an entity of static type \code{Type} is
    invoked. Note that it could actually succeed: An overriding implementation
    of \code{runtimeType} could return an instance
    whose dynamic type is a subtype
    of \code{Type} that has a \CALL{} method.
    We decided to make it an error because it is likely to be a mistake,
    especially in cases like \code{$d$.hashCode()}
    where a developer might have forgotten that \code{hashCode} is a getter.%
  }

\item
  Let $e$ be an expression of the form \code{$d$.\id(\metavar{arguments})}
  where the static type of $d$ is \DYNAMIC, \metavar{arguments} is
  an actual argument list derived from \synt{arguments},
  and \id{} is the name of a method declared in \code{Object}
  whose method signature has type $F$.
  If the number of positional actual arguments in \metavar{arguments}
  is less than the number of required positional arguments of $F$
  or greater than the number of positional arguments in $F$,
  or if \metavar{arguments} includes any named arguments
  with a name that is not declared in $F$,
  the type of $e$ is \DYNAMIC.
  Otherwise, the type of $e$ is the return type in $F$.
  \commentary{%
    So \code{$d$.toString(bazzle:\,42)} has type \DYNAMIC{} whereas
    \code{$d$.toString()} has type \code{String}.
    Note that invocations which "do not fit" the statically
    known declaration are not errors, they just get return type \DYNAMIC.%
  }

\item
  Let $e$ be an expression of the form
  \code{$d$.\id<\metavar{typeArguments}>(\metavar{arguments})} where
  the static type of $d$ is \DYNAMIC,
  \metavar{typeArguments} is a list of actual
  type arguments derived from \synt{typeArguments}, and
  \metavar{arguments} is an actual argument list derived from \synt{arguments}.
  It is a compile-time error if \id{} is the name of
  a non-generic method declared in \code{Object}.
  \commentary{%
    No generic methods are declared in \code{Object}.
    Hence, we do not specify that there must be
    the statically required number of actual type arguments, and
    they must satisfy the bounds.
    That would otherwise be the consistent approach,
    because the invocation is guaranteed to fail when any of those
    requirements are violated,
    but generalizations of this mechanism would need to include such rules.%
  }

\item
  For an instance method invocation $e$ (including invocations of getters,
  setters, and operators) where the receiver has static type \DYNAMIC{} and
  $e$ does not match any of the above cases, the static type of $e$ is
  \DYNAMIC.
  When an expression derived from \synt{cascadeSection} performs
  a getter or method invocation that corresponds to one of the cases above,
  the corresponding static analysis and compile-time errors apply.
  \commentary{%
    For instance, \code{$d$..foobar(16)..hashCode()} is an error.%
  }
\end{itemize}

\commentary{%
  Note that only very few forms of instance method invocation with a
  receiver of type \DYNAMIC{} can be a compile-time error.
  Of course, some expressions like \code{x[1, 2]} are syntax errors
  even though they could also be considered "invocations",
  and subexpressions are checked separately so
  any given actual argument could be a compile-time error.
  But almost any given argument list shape could be handled via
  \code{noSuchMethod},
  and an argument of any type could be accepted because any
  formal parameter in an overriding declaration could have its type
  annotation contravariantly changed to \code{Object}.
  So it is a natural consequence of the principle of
  that
  a \DYNAMIC{} receiver admits almost all instance method invocations.
  The few cases where an instance method invocation with
  a receiver of type \DYNAMIC{} is an error
  are either guaranteed to fail at run time,
  or they are very, very likely to be developer mistakes.%
}


\subsection{Type FutureOr}
\LMLabel{typeFutureOr}

\LMHash{}%
The built-in type declaration \code{FutureOr},
which is exported by the library \code{dart:async},
defines a generic type with one type parameter (\ref{generics}).
The type \code{FutureOr<$T$>} is a non-class type
which is regular-bounded for all $T$.

\commentary{%
  The subtype relations involving \code{FutureOr} are specified elsewhere
  (\ref{subtypeRules}).
  Note, however, that they entail certain useful properties:

  \begin{itemize}
  \item[$\bullet$]
    $T <: \code{FutureOr<$T$>}$.
  \item[$\bullet$]
    $\code{Future<$T$>} <: \code{FutureOr<$T$>}$.
  \item[$\bullet$]
    If $T <: S$ and $\code{Future<$T$>} <: S$, then $\code{FutureOr<$T$>} <: S$.
  \end{itemize}

  That is, \code{FutureOr} is in a sense
  the union of $T$ and the corresponding future type.
  The last point guarantees that
  \code{FutureOr<$T$>} <: \code{Object},
  and also that \code{FutureOr} is covariant in its type parameter,
  just like class types:
  if $S$ <: $T$ then \code{FutureOr<$S$>} <: \code{FutureOr<$T$>}.%
}

\LMHash{}%
If the type arguments passed to \code{FutureOr} would incur compile-time errors
if applied to a normal generic class with one type parameter,
the same compile-time errors are issued for \code{FutureOr}.
The name \code{FutureOr} as an expression
denotes a \code{Type} object representing the type \code{FutureOr<dynamic>}.

\rationale{%
  The \code{FutureOr<$T$>} type represents a case where an object can be
  either an instance of the type $T$
  or the type \code{Future<$T$>}.
  Such cases occur naturally in asynchronous code.
  The available alternative would be to use a top type (e.g., \DYNAMIC{}),
  but \code{FutureOr} allows some tools to provide
  a more precise type analysis.%
}

\LMHash{}%
The type \code{FutureOr<$T$>} has an interface that is identical to that
of \code{Object}.
\commentary{%
  That is, only members that \code{Object} has can be invoked
  on an object with static type \code{FutureOr<$T$>}.%
}

\rationale{%
  We only want to allow invocations of members that are inherited from
  a common supertype of both $T$ and \code{Future<$T$>}.
  In most cases the only common supertype is \code{Object}.
  The exceptions, like \code{FutureOr<Future<Object\gtgt}
  which has \code{Future<Object>} as common supertype,
  are few and not practically useful,
  so for now we choose to only allow invocations of
  members inherited from \code{Object}.%
}

\LMHash{}%
We define the auxiliary function
\IndexCustom{\futureOrBase{T}}{futureOrBase(t)@\emph{futureOrBase}$(T)$}
as follows:

\begin{itemize}
\item If $T$ is \code{FutureOr<$S$>} for some $S$
  then $\futureOrBase{T} = \futureOrBase{S}$.
\item Otherwise $\futureOrBase{T} = T$.
\end{itemize}


\subsection{Type Void}
\LMLabel{typeVoid}

\LMHash{}%
The special type \VOID{} is used to indicate
that the value of an expression is meaningless and intended to be discarded.

\commentary{%
  A typical case is that the type \VOID{} is used as the return type
  of a function that ``does not return anything''.
  Technically, there will always be \emph{some} object
  which is returned
  (\ref{functions}).
  But it is perfectly meaningful to have a function
  whose sole purpose is to create side-effects,
  such that \emph{any} use of the returned object
  would be misguided.
  %
  This does not mean that there is anything wrong
  with the returned object as such.
  It could be any object whatsoever.
  But the developer who chose the return type \VOID{}
  did that to indicate that it is a misunderstanding to
  ascribe any meaning to that object,
  or to use it for any purpose.%
}

\commentary{%
  The type \VOID{} is a top type
  (\ref{superBoundedTypes}),
  so \VOID{} and \code{Object} are subtypes of each other
  (\ref{subtypes}),
  which also implies that any object can be
  the value of an expression of type \VOID.
  %
  Consequently, any instance of type \code{Type} which reifies the type \VOID{}
  must compare equal (according to the \lit{==} operator \ref{equality})
  to any instance of \code{Type} which reifies the type \code{Object}
  (\ref{dynamicTypeSystem}).
  It is not guaranteed that \code{identical(\VOID, Object)} evaluates to true.
  In fact, it is not recommended that implementations strive to achieve this,
  because it may be more important to ensure that diagnostic messages
  (including stack traces and dynamic error messages)
  preserve enough information to use the word `void' when referring to types
  which are specified as such in source code.%
}

\LMHash{}%
In support of the notion
that the value of an expression with static type \VOID{} should be discarded,
such objects can only be used in specific situations:
The occurrence of an expression of type \VOID{} is a compile-time error
unless it is permitted according to one of the following rules.

\begin{itemize}
\item
  In an \synt{expressionStatement} \code{$e$;}, $e$ may have type \VOID.
  \rationale{The value of $e$ is discarded.}
\item
  In the initialization and increment expressions of a for-loop,
  \code{\FOR{} ($e_1$; $e_2$; $e_3$) {\ldots}},
  $e_1$ may have type \VOID,
  and each of the expressions in the expression list $e_3$ may have type \VOID.
  \rationale{The values of $e_1$ and $e_3$ are discarded.}
\item
  In a type cast \code{$e$ as $T$}, $e$ may have type \VOID.
  \rationale{%
    Developers thus obtain the ability to \emph{override} the constraints
    on usages of values with static type \VOID.
    This means that it is not enforced that such values are discarded,
    but they can only be used when the wish to do so
    has been indicated explicitly.%
  }
\item
  In a parenthesized expression \code{($e$)}, $e$ may have type \VOID.
  \rationale{%
    Note that \code{($e$)} itself has type \VOID,
    which implies that it must occur in some context
    where it is not an error to have it.%
  }
\item
  In a conditional expression \code{$e$\,?\,$e_1$\,:\,$e_2$},
  $e_1$ and $e_2$ may have type \VOID.
  \rationale{%
    The static type of the conditional expression is then \VOID,
    even if one of the branches has a different type,
    which means that the conditional expression must again occur
    in some context where it is not an error to have it.%
  }
\item
  In a null coalescing expression \code{$e_1$\,??\,$e_2$},
  $e_2$ may have type \VOID.
  \rationale{%
    The static type of the null coalescing expression is then \VOID,
    which in turn restricts where it can occur.%
  }
\item
  In an expression of the form \code{\AWAIT\,\,$e$}, $e$ may have type \VOID.
  \rationale{%
    This rule was adopted because it was a substantial breaking change
    to turn this situation into an error
    at the time where the treatment of \VOID{} was changed.
    Tools may choose to give a hint in such cases.%
  }
\item
  \commentary{%
    In a return statement \code{\RETURN\,$e$;},
    $e$ may have type \VOID{} in a number of situations
    (\ref{return}).%
  }
\item
  \commentary{%
    In an arrow function body \code{=> $e$},
    the returned expression $e$ may have type \VOID{}
    in a number of situations
    (\ref{functions}).%
  }
\item
  An initializing expression for a variable of type \VOID{}
  may have type \VOID.
  \rationale{Usages of that variable are constrained.}
\item
  An actual argument expression corresponding to a formal parameter
  whose statically known type annotation is \VOID{}
  may have type \VOID.
  \rationale{%
    Usages of that parameter in the body of the callee
    are statically expected to be constrained by having type \VOID.
    See the discussion about soundness below
    (\ref{voidSoundness}).%
  }
  This rule also applies to the operators \code{[]} and \code{[]=}.
  \commentary{%
    For example, $e_1$ and $e_2$ may have type \VOID{}
    in an expression of the form \code{$e_0$[$e_1$] = $e_2$}
    when the parameters of the statically known operator \code{[]=}
    both have type \VOID{}.%
  }
  Finally, this rule also applies to setters.
  \commentary{%
    For example, with an expression of the form \code{$e_1$ = $e_2$}
    which denotes a setter invocation whose
    statically known parameter type is \VOID,
    $e_2$ may have type \VOID{}.%
  }
\item
  In an expression of the form \code{$e_1$\,=\,$e_2$}
  where $e_1$ is an \synt{assignableExpression} denoting a local variable
  \commentary{(which can also be a formal parameter)}
  of type \VOID,
  $e_2$ may have type \VOID.
  \rationale{%
    Usages of that variable are constrained because it has type \VOID.
    See the discussion about soundness below
    (\ref{voidSoundness}).%
  }
\item
  Let $e$ be an expression ending in a \synt{cascadeSection}
  of the form \code{..\,$S$\,$s$\;=\;$e_1$},
  where $S$ is of the form

  \noindent
  \syntax{(<cascadeSelector> <argumentPart>*)
    (<assignableSelector> <argumentPart>*)*}

  \noindent
  and $e_1$ is of the form \synt{expressionWithoutCascade}.

  If $s$ is an \synt{assignableSelector} of the
  form \code{.\id} or \code{?.\id}
  where the static type of the identifier \id{} is \VOID,
  $e_1$ may have type \VOID.
  Otherwise, if $s$ is an \synt{assignableSelector} of the form
  \code{[$\,e_0\,$]} where the static type of
  the first formal parameter in the statically known declaration
  of operator \code{[]=} is \VOID,
  $e_0$ may have type \VOID.
  Also, if the static type of the second formal parameter is \VOID,
  $e_1$ may have type \VOID.
\end{itemize}

\LMHash{}%
Finally, we need to address situations involving implicit usage of
an object whose static type can be \VOID.
%
It is a compile-time error for a for-in statement to have an iterator
expression of type $T$ such that \code{Iterator<\VOID{}>}
is the most specific instantiation of \code{Iterator}
that is a superinterface of $T$, unless the
iteration variable has type \VOID.
%
It is a compile-time error for an asynchronous for-in statement
to have a stream expression of type $T$
such that \code{Stream<\VOID{}>} is the most specific
instantiation of \code{Stream} that is a superinterface of $T$,
unless the iteration variable has type \VOID.

\commentary{Here are some examples:}

\begin{dartCode}
\FOR{} (Object x in <\VOID>[]) \{\} // \comment{Error.}
\AWAIT{} \FOR{} (int x \IN{} new Stream<\VOID{}>.empty()) \{\} // \comment{Error.}
\FOR{} (\VOID{} x \IN{} <\VOID{}>[]) \{\ldots\} // \comment{OK.}
\FOR (\VAR{} x \IN{} <\VOID{}>[]) \{\ldots\} // \comment{OK, type of x inferred.}
\end{dartCode}

\commentary{%
  However, in the examples that are not errors
  the usage of \code{x} in the loop body is constrained,
  because it has type \VOID.%
}


\subsubsection{Void Soundness}
\LMLabel{voidSoundness}

\LMHash{}%
The constraints on usage of an object obtained from the evaluation of
an expression with static type \VOID{}
are not strictly enforced.

\commentary{%
  The usage of a ``void value'' is not a soundness issue, that is,
  no invariants needed for correct execution of a Dart program
  can be violated because of such a usage.%
}

\rationale{%
  It could be said that the type \VOID{} is used
  to help developers maintain a certain self-imposed discipline
  about the fact that certain objects are not \emph{intended} to be used.
  %
  Because of the fact that enforcement is not necessary,
  and because of the treatment of \VOID{} in earlier versions of Dart,
  the language uses a \emph{best effort} approach to ensure
  that the value of an expression of type \VOID{}
  will not be used.%
}

\commentary{%
  In fact, there are numerous ways in addition to the type cast
  in which a developer can get access to such an object:%
}

\begin{dartCode}
\ABSTRACT{} \CLASS A<X> \{
  final X x;
  A(this.x);
  Object foo(X x);
\}
\\
\CLASS{} B<X> \EXTENDS{} A<X> \{
  B(X x): super(x);
  Object foo(Object x) => x;
\}
\\
Object f<X>(X x) => x;
\\
\VOID{} main() \{
  \VOID x = 42;
  print(f(x)); // \comment{(1)}
  \\
  A<\VOID{}> a = B<\VOID{}>(x);
  A<Object> aObject = a;
  print(aObject.x); // \comment{(2)}
  print(a.foo(x)); // \comment{(3)}
\}
\end{dartCode}

\commentary{%
  At (1), a variable \code{x} of type \VOID{} is passed to
  a generic function \code{f},
  which is allowed because the actual type argument \VOID{} is inferred,
  and it is allowed to pass an actual argument of type \VOID{} to
  a formal parameter with the same type.
  %
  However, no special treatment is given when an expression has a type
  which is or contains a type variable whose value could be \VOID,
  so we are allowed to return \code{x} in the body of \code{f},
  even though this means that we indirectly get access to the value
  of an expression of type \VOID, under the static type \code{Object}.

  At (2), we indirectly obtain access to the value of
  the variable \code{x} with type \VOID,
  because we use an assignment to get access to the instance of \code{B}
  which was created with type argument \VOID{} under the type
  \code{A<Object>}.
  Note that \code{A<Object>} and \code{A<\VOID{}>} are subtypes of each other,
  that is, they are equivalent according to the subtype rules,
  so neither static nor dynamic type checks will fail.

  At (3), we indirectly obtain access to the value of
  the variable \code{x} with type \VOID{}
  under the static type \code{Object},
  because the statically known method signature of \code{foo}
  has parameter type \VOID,
  but the actual implementation of \code{foo} which is invoked
  is an override whose parameter type is \code{Object},
  which is allowed because \code{Object} and \VOID{} are both top types.%
}

\rationale{%
  Obviously, the support for preventing developers from using objects
  obtained from expressions of type \VOID{} is far from sound,
  in the sense that there are many ways to circumvent the rule
  that such an object should be discarded.

  However, we have chosen to focus on the simple, first-order usage
  (where an expression has type \VOID, and the value is used),
  and we have left higher-order cases largely unchecked,
  relying on additional tools such as linters to perform an analysis
  which covers indirect data flows.

  It would certainly have been possible to define sound rules,
  such that the value of an expression of type \VOID{}
  would be guaranteed to be discarded after some number of transfers
  from one variable or parameter to the next one, all with type \VOID,
  explicitly, or as the value of a type parameter.
  In particular, we could require that method overrides should
  never override return type \code{Object} by return type \VOID,
  or parameter types in the opposite direction;
  parameterized types with type argument \VOID{} could not be assigned
  to variables where the corresponding type argument is anything other than
  \VOID, etc.\ etc.

  But this would be quite impractical.
  In particular, the need to either prevent a large number of type variables
  from ever having the value \VOID,
  or preventing certain usages of values whose type is such a type variable,
  or whose type contains such a type variable,
  that would be severely constraining on a very large part of all Dart code.

  So we have chosen to help developers maintain this self-imposed discipline
  in simple and direct cases,
  and leave it to ad-hoc reasoning or separate tools to ensure
  that the indirect cases are covered as closely as needed in practice.%
}


\subsection{Parameterized Types}
\LMLabel{parameterizedTypes}

% TODO(eernst): We may want to add a new concept for the application of a
% generic function to actual type arguments (maybe it's an extra kind of
% `parameterized type', but it differs from the generic class case because
% we _can_ have dynamic invocations of a generic function). But this does
% not arise as a stand-alone entity before we introduce generic tear-offs
% (\code{var f = foo<int>;}), or if we allow it to arise implicitly based
% on inference. That new concept should probably be added to this section.

\LMHash{}%
A \emph{parameterized type} is a syntactic construct
where the name of a generic type declaration is applied to
a list of actual type arguments.
A \emph{generic instantiation} is the operation where
a generic type is applied to actual type arguments.

\commentary{%
  So a parameterized type is the syntactic concept that corresponds to
  the semantic concept of a generic instantiation.
  When using the former, we will often leave the latter implicit.%
}

\LMHash{}%
Let $T$ be a parameterized type \code{$G$<$S_1, \ldots,\ S_n$>}.

\LMHash{}%
It is a compile-time error if $G$ is not a generic type,
or $G$ is a generic type,
but the number of formal type parameters in the declaration of $G$ is not $n$.
Otherwise, let
$X_1, \ldots, X_n$
be the formal type parameters of $G$, and let
$B_1, \ldots, B_n$
be the corresponding upper bounds, using \DYNAMIC{} when no bound is declared.

\LMHash{}%
$T$ is \Index{malbounded} if{}f either
$S_i$ is malbounded for one or more $i \in 1 .. n$,
or $T$ is not well-bounded (\ref{superBoundedTypes}).

\LMHash{}%
It is a compile-time error if $T$ is malbounded.

\LMHash{}%
$T$ is evaluated as follows.
Let $t_i$ be the result of evaluating $S_i$, for $i \in 1 .. n$.
$T$ then evaluates to the generic instantiation
where $G$ is applied to $t_1, \ldots, t_n$.

\LMHash{}%
Let $T$ be a parameterized type of the form
\code{$G$<$A_1, \ldots,\ A_n$>}
and assume that $T$ is not malformed and not malbounded.
If $S$ is the static type of a member $m$ of $G$,
then the static type of the member $m$ of an expression of type
\code{$G$<$A_1, \ldots,\ A_n$>}
is
$[A_1/X_1, \ldots, A_n/X_n]S$,
where $X_1, \ldots, X_n$ are the formal type parameters of $G$.

%% TODO(eernst): This is the location where we can specify that each of the
%% type arguments of the receiver type \code{$G$<$A_1, \ldots,\ A_n$>} must be
%% replaced by the bottom type (`Null`, for now) in locations of the member
%% type where it occurs contravariantly. For instance, `c.f` should have
%% static type `void Function(Null)` when `c` has static type `C<T>` for any
%% `T`, and we have `class C<X> { void Function(X) f; }`.


\subsubsection{Actual Types}
\LMLabel{actualTypes}

% NOTE(eernst): The actual type arguments in this section are dynamic entities,
% not syntax (the concept of an `actual type' and an 'actual bound' is used to
% specify the dynamic semantics, including dynamic errors). So we use $t_i$
% to denote these type arguments, just like all those locations where the
% concept is used, rather than $A_i$ which is frequently used to denote the
% syntax of an actual type argument.
%
% The point is that $t_i$ will never contain a formal type parameter, so we
% need not worry about the need to iterate in the substitution that finds an
% actual bound. For instance, there is no problem determining the actual bound
% for \code{X} in an invocation of \code{void foo<X extends C<X>>() \{...\}}
% even if it is a recursive invocation on the form \code{foo<C<X>>()} in the
% body.

\LMHash{}%
Let $T$ be a term derived from \synt{type}.
Let \List{X}{1}{s} be the formal type parameters in scope
at the location where $T$ occurs.
In a context where the actual type arguments corresponding to
\List{X}{1}{s} are \List{t}{1}{s},
the \Index{actual value of the type} $T$ is then
$[t_1/X_1, \ldots, t_s/X_s]T$.

\LMHash{}%
Let $D$ be a declaration with name $n$ and type annotation $T$.
The \Index{actual type} of $D$ and of $n$ in a given context is
then the actual value of $T$ in that context.

\commentary{%
  In the non-generic case where $s = 0$,
  the actual type is equal to the declared type,
  in the sense that we use simple terms like \code{int} to denote both.
  Note that \List{X}{1}{s} may be declared by multiple entities, e.g.,
  one or more enclosing generic functions and an enclosing generic class.%
}

\LMHash{}%
Let \code{$X$ \EXTENDS{} $B$} be a formal type parameter declaration.
The \Index{actual bound} of $X$ in a given context is
the actual value of $B$ in that context.

\commentary{%
  Note that even though $X$ may occur in $B$
  it does not occur in the actual value of $B$,
  because no type has an actual value that includes a type variable.%
}


\subsubsection{Least Upper Bounds}
\LMLabel{leastUpperBounds}

% TODO(eernst): This section has been updated to take generic functions
% into account, but no other changes have been performed. Hence, we still
% need to update this section to use Dart 2 rules for LUB.

\LMHash{}%
% does this diverge in some cases?
Given two interfaces $I$ and $J$,
let $S_I$ be the set of superinterfaces of $I$,
let $S_J$ be the set of superinterfaces of $J$
and let $S = (\{I\} \cup S_I) \cap (\{J\} \cup S_J)$.
Furthermore,
we define $S_n = \{T | T \in S \wedge depth(T) = n\}$ for any finite $n$
where $depth(T)$ is the number of steps in the longest inheritance path
from $T$ to \code{Object}.
%TODO(lrn): Specify: "inheritance path" is a path in the superinterface graph.
Let $q$ be the largest number such that $S_q$ has cardinality one,
which must exist because $S_0$ is $\{\code{Object}\}$.
The least upper bound of $I$ and $J$ is the sole element of $S_q$.

\LMHash{}%
The least upper bound of \DYNAMIC{} and any type $T$ is \DYNAMIC.
The least upper bound of \VOID{} and any type $T \ne \DYNAMIC{}$ is \VOID.
The least upper bound of $\bot$ and any type $T$ is $T$.
Let $U$ be a type variable with upper bound $B$.
The least upper bound of $U$ and a type $T \ne \bot$ is
the least upper bound of $B$ and $T$.

\LMHash{}%
The least upper bound operation is commutative and idempotent,
but it is not associative.

% Function types

%% TODO(eernst): This section should use the new syntax for function types
%% (\FunctionTypePositionalStd{} etc.); these updates are made by CL 84908.

\LMHash{}%
The least upper bound of a function type and an interface type $T$ is
the least upper bound of \FUNCTION{} and $T$.
Let $F$ and $G$ be function types.
If $F$ and $G$ differ in their number of required parameters,
then the least upper bound of $F$ and $G$ is \FUNCTION.
Otherwise:

\begin{itemize}
\item If

\noindent
\code{$F = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($T_1, \ldots,\ T_r,\ $[$T_{r+1}, \ldots,\ T_n$]) $ \rightarrow T_0$} and

\noindent
\code{$G = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($S_1, \ldots,\ S_r,\ $[$S_{r+1}, \ldots,\ S_k$]) $ \rightarrow S_0$}

\noindent
where $k \le n$ then the least upper bound of $F$ and $G$ is

\noindent
\code{<$X_1\ B_1, \ldots,\ X_s\ B_s$>($L_1, \ldots,\ L_r,\ $[$L_{r+1}, \ldots,\ L_k$]) $ \rightarrow L_0$}

\noindent
where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0 .. k$.
\item If

\noindent
\code{$F = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($T_1, \ldots,\ T_r,\ $[$T_{r+1}, \ldots,\ T_n$]) $ \rightarrow T_0$},

\noindent
\code{$G = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($S_1, \ldots,\ S_r,\ $\{ \ldots{} \}) $ \rightarrow S_0$}

\noindent
then the least upper bound of $F$ and $G$ is

\noindent
\code{<$X_1\ B_1, \ldots,\ X_s\ B_s$>($L_1, \ldots,\ L_r$) $ \rightarrow L_0$}

\noindent
where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0 .. r$.
\item If

\noindent
\code{$F = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($T_1, \ldots,\ T_r,\ $\{$T_{r+1}\ p_{r+1}, \ldots,\ T_f\ p_f$\}) $ \rightarrow T_0$},

\noindent
\code{$G = $ <$X_1\ B_1, \ldots,\ X_s\ B_s$>($S_1, \ldots,\ S_r,\ $\{$S_{r+1}\ q_{r+1}, \ldots,\ S_g\ q_g$\}) $ \rightarrow S_0$}

then let
$\{x_m, \ldots, x_n\} = \{p_{r+1}, \ldots, p_f\} \cap \{q_{r+1}, \ldots, q_g\}$
and let $X_j$ be the least upper bound of the types of $x_j$ in $F$ and
$G, j \in m .. n$.
Then the least upper bound of $F$ and $G$ is

\noindent
\code{<$X_1\ B_1, \ldots,\ X_s\ B_s$>($L_1, \ldots,\ L_r,\ $\{$X_m\ x_m, \ldots,\ X_n\ x_n$\}) $ \rightarrow L_0$}

where $L_i$ is the least upper bound of $T_i$ and $S_i, i \in 0 .. r$
\end{itemize}

\commentary{%
  Note that the non-generic case is covered by using $s = 0$,
  in which case the type parameter declarations are omitted (\ref{generics}).%
}


\section{Reference}
\LMLabel{reference}


\subsection{Lexical Rules}
\LMLabel{lexicalRules}

\LMHash{}%
Dart source text is represented as a sequence of Unicode code points.
This sequence is first converted into a sequence of tokens
according to the lexical rules given in this specification.
At any point in the tokenization process,
the longest possible token is recognized.


\subsubsection{Reserved Words}
\LMLabel{reservedWords}

\LMHash{}%
A \Index{reserved word} can only be used in the syntactic positions
specified by the grammar.
In particular, a compile-time error occurs if a reserved word is used
where an identifier is expected.

\commentary{%
  Note that reserved words occur bold and unquoted in grammar rules
  (e.g., \ASSERT{})
  even though the consistent notation would use quotes
  (e.g., \lit{assert}).
  This notational abuse occurs because we believe
  it makes the grammar rules more readable.%
}

\begin{grammar}
<RESERVED\_WORD> ::= \ASSERT{} | \BREAK{} | \CASE{} | \CATCH{} |
    \CLASS{} | \CONST{}
  \alt\hspace{-3mm} \CONTINUE{} | \DEFAULT{} | \DO{} | \ELSE{} | \ENUM{} |
    \EXTENDS{} | \FALSE{} | \FINAL{} | \FINALLY{} | \FOR{}
  \alt\hspace{-3mm} \IF{} | \IN{} | \IS{} | \NEW{} | \NULL{} | \RETHROW{} |
    \RETURN{} | \SUPER{} | \SWITCH{} | \THIS{} | \THROW{}
  \alt\hspace{-3mm} \TRUE{} | \TRY{} | \VAR{} | \VOID{} | \WHILE{} | \WITH{}
\end{grammar}

\LMHash{}%
In the grammar, the rule for reserved words above must occur
before the rule for \synt{BUILT\_IN\_IDENTIFIER}
(\ref{identifierReference}).

\commentary{%
  This ensures that \synt{IDENTIFIER} and \synt{IDENTIFIER\_NO\_DOLLAR} do not
  derive any reserved words, and they do not derive any built-in identifiers.
}


\subsubsection{Comments}
\LMLabel{comments}

\LMHash{}%
\IndexCustom{Comments}{comment}
are sections of program text that are used for documentation.

\begin{grammar}
<SINGLE\_LINE\_COMMENT> ::= \gnewline{}
  `//' \gtilde(<LINE\_BREAK>)* (<LINE\_BREAK>)?

<MULTI\_LINE\_COMMENT> ::= \gnewline{}
  `/*' (<MULTI\_LINE\_COMMENT> | \gtilde{} `*/')* `*/'
\end{grammar}

\LMHash{}%
Dart supports both single-line and multi-line comments.
A \Index{single line comment} begins with the token \code{//}.
Everything between \code{//} and the end of line
must be ignored by the Dart compiler.

\LMHash{}%
A \Index{multi-line comment} begins with the token \code{/*}
and ends with the token \code{*/}.
Everything between \code{/*} and \code{*/}
must be ignored by the Dart compiler.
Comments may nest.


\subsection{Operator Precedence}
\LMLabel{operatorPrecedence}

\LMHash{}%
Operator precedence is given implicitly by the grammar.

\commentary{%
  The following non-normative table may be helpful
  \newline

  \begin{tabular}{| r | r | r | r |}
  \hline
  Description & Operator & Associativity & Precedence \\
  \hline
  Unary postfix & \code{$e$.}, \code{$e$?.}, \code{$e$++}, \code{$e$-{}-}, \code{$e1$[$e2$]},
  \code{$e$()} & None & 16 \\
  \hline
  Unary prefix & \code{-$e$}, \code{!$e$}, \code{\gtilde$e$}, \code{++$e$}, \code{-{}-$e$}, \code{\AWAIT{} $e$} & None & 15\\
  \hline
  Multiplicative & \code{*}, \code{/}, \code{\gtilde/}, \code{\%} & Left & 14\\
  \hline
  Additive & \code{+}, \code{-} & Left & 13\\
  \hline
  Shift & \code{\ltlt}, \code{\gtgt}, \code{\gtgtgt} & Left & 12\\
  \hline
  Bitwise AND & \code{\&} & Left & 11\\
  \hline
  Bitwise XOR & \code{\^{}} & Left & 10\\
  \hline
  Bitwise Or & \code{|} & Left & 9\\
  \hline
  Relational & \code{<}, \code{>}, \code{<=}, \code{>=}, \AS, \IS, \code{\IS{}!} & None & 8\\
  \hline
  Equality & \code{==}, \code{!=} & None & 7\\
  \hline
  Logical AND & \code{\&\&} & Left & 6\\
  \hline
  Logical Or & \code{||} & Left & 5\\
  \hline
  If-null & \code{??} & Left & 4\\
  \hline
  Conditional & \code{$e1$\,?\,$e2$\,:\,$e3$} & Right & 3\\
  \hline
  Cascade & \code{..} & Left & 2\\
  \hline
  Assignment & \code{=}, \code{*=}, \code{/=}, \code{+=}, \code{-=}, \code{\&=}, \code{\^{}=}, etc. & Right & 1\\
  \hline
  \end{tabular}%
}


\section*{Appendix: Algorithmic Subtyping}
\LMLabel{algorithmicSubtyping}

% Subtype Rule Numbering
\newcommand{\AppSrnReflexivity}{\ensuremath{1_{\scriptsize\mbox{algo}}}}
\newcommand{\AppSrnTypeVariableReflexivityB}{\SrnTypeVariableReflexivityA.1}
\newcommand{\AppSrnTypeVariableReflexivityC}{\SrnTypeVariableReflexivityA.2}
\newcommand{\AppSrnTypeVariableReflexivityD}{\SrnTypeVariableReflexivityA.3}
\newcommand{\AppSrnRightFutureOrC}{\SrnRightFutureOrB.1}
\newcommand{\AppSrnRightFutureOrD}{\SrnRightFutureOrB.2}

\begin{figure}[h!]
  \def\VSP{\vspace{3mm}}
  \def\ExtraVSP{\vspace{1mm}}
  \def\Axiom#1#2#3#4{\centerline{\inference[#1]{}{\SubtypeStd{#3}{#4}}}\VSP}
  \def\Rule#1#2#3#4#5#6{\centerline{\inference[#1]{\SubtypeStd{#3}{#4}}{\SubtypeStd{#5}{#6}}}\VSP}
  \def\RuleTwo#1#2#3#4#5#6#7#8{%
    \centerline{\inference[#1]{\SubtypeStd{#3}{#4} & \SubtypeStd{#5}{#6}}{\SubtypeStd{#7}{#8}}}\VSP}
  \def\RuleRaw#1#2#3#4#5{%
    \centerline{\inference[#1]{#3}{\SubtypeStd{#4}{#5}}}\VSP}
  \def\RuleRawRaw#1#2#3#4{\centerline{\inference[#1]{#3}{#4}}\VSP}
  %
  \begin{minipage}[c]{0.49\textwidth}
    \RuleRaw{\AppSrnReflexivity}{Reflexivity}{S\mbox{ not composite}}{S}{S}
    \Rule{\AppSrnTypeVariableReflexivityC}{Type Variable Reflexivity B}{X}{T}{X}{X \& T}
    \Rule{\AppSrnRightFutureOrC}{Right FutureOr C}{\Delta(X)}{\code{FutureOr<$T$>}}{X}{\code{FutureOr<$T$>}}
  \end{minipage}
  \begin{minipage}[c]{0.49\textwidth}
    \Axiom{\AppSrnTypeVariableReflexivityB}{Type Variable Reflexivity}{X}{X}
    \Rule{\AppSrnTypeVariableReflexivityD}{Type Variable Reflexivity C}{X \& S}{T}{X \& S}{X \& T}
    \Rule{\AppSrnRightFutureOrD}{Right FutureOr D}{S}{\code{FutureOr<$T$>}}{X \& S}{\code{FutureOr<$T$>}}
  \end{minipage}
  %
  \caption{Algorithmic subtype rules.
    Rules \SrnTop--\SrnSuperinterface{} are unchanged and hence omitted here.}
  \label{fig:algorithmicSubtypeRules}
\end{figure}

\LMHash{}%
The text in this appendix is not part of the specification of the Dart language.
However, we still use the notation where precise information
uses the style associated with normative text in the specification (this style),
\commentary{whereas examples and explanations use commentary style (like this)}.

\LMHash{}%
This appendix presents a variant of the subtype rules given
in Figure~\ref{fig:subtypeRules} on page~\pageref{fig:subtypeRules}.

\commentary{%
  The rules will prove the same set of subtype relationships,
  but the rules given here show that there is an efficient implementation
  that will determine whether \SubtypeStd{S}{T} holds,
  for any given types $S$ and $T$.
  It is easy to see that the algorithmic rules will prove at most
  the same subtype relationships,
  because all rules given here can be proven
  by means of rules in Figure~\ref{fig:subtypeRules}.
  It is also relatively straightforward to sketch out proofs
  that the algorithmic rules can prove at least the same subtype relationships,
  also when the following ordering and termination constraints are observed.%
}

\LMHash{}%
The only rule which is modified is number~\SrnReflexivity,
which is modified to \AppSrnReflexivity.
This only changes the applicability of the rule:
This rule is only used for types which are not atomic.
An \IndexCustom{atomic type}{type!atomic}
is a type which is not a type variable,
not a promoted type variable,
not a function type,
and not a parameterized type.

\commentary{%
  In other words, rule \AppSrnReflexivity{} is used for
  special types like \DYNAMIC, \VOID, and \FUNCTION,
  and it is used for non-generic classes,
  but it is not used for any type where it is an operation
  that takes more than one comparison to detect whether
  it is the same as some other type.
  %
  The point is that the remaining rules will force
  a structural traversal anyway, as far as needed,
  and we may hence just as well omit the initial structural traversal
  which might take many steps only to report that two large type terms
  are not quite identical.%
}

\LMHash{}%
The rules are ordered by means of their rule numbers:
A rule given here numbered $N.1$ is inserted immediately after rule $N$,
followed by rule $N.2$, and so on,
followed by the rule whose number is $N+1$.
\commentary{%
  So the order is
  \AppSrnReflexivity, \SrnTop--\SrnTypeVariableReflexivityA,
  \AppSrnTypeVariableReflexivityB, \AppSrnTypeVariableReflexivityC,
  \AppSrnTypeVariableReflexivityD,
  \SrnRightPromotedVariable, and so on.%
}

\LMHash{}%
We now specify the procedure which is used to determine whether
\SubtypeStd{S}{T} holds,
for some specific types $S$ and $T$:
Select the first rule $R$ whose syntactic constraints are satisfied
by the given types $S$ and $T$,
and proceed to show that its premises hold.
If so, we terminate and conclude that the subtype relationship holds.
Otherwise we terminate and conclude
that the subtype relationship does not hold,
except if $R$ is
\SrnRightFutureOrA, \SrnRightFutureOrB,
\AppSrnRightFutureOrC, or \AppSrnRightFutureOrD.
\commentary{%
  In particular, for the original query \SubtypeStd{S}{T},
  we do not backtrack into trying to use a rule that has
  a higher rule number than that of $R$,
  except that we may try all of
  the rules with \code{FutureOr<$T$>} to the right.%
}

\commentary{%
  Apart from the fact that the full complexity of subtyping
  is potentially incurred each time it is checked whether a premise holds,
  the checks applied for each rule is associated with an amount of work
  which is constant for all rules except the following:
  First, the group of rules
  \SrnRightFutureOrA, \SrnRightFutureOrB,
  \AppSrnRightFutureOrC, and \AppSrnRightFutureOrD{}
  may cause backtracking to take place.
  Next, rules \SrnPositionalFunctionType--\SrnCovariance{}
  require work proportional to the size of $S$ and $T$,
  due to the number of premises that must be checked.
  Finally, rule~\SrnSuperinterface{} requires work
  proportional to the size of $S$,
  and it may also incur the cost of searching up to the entire set of
  direct and indirect superinterfaces of the candidate subtype $S$,
  until the corresponding premise for one of them is shown to hold,
  if any.

  Additional optimizations are applicable.
  For instance,
  we can immediately conclude that the subtype relationship does not hold
  when we are about to check rule~\SrnSuperinterface{}
  if $T$ is a type variable or a function type.
  For several other forms of type, e.g.,
  a promoted type variable,
  \code{Object}, \DYNAMIC, \VOID,
  \code{FutureOr<$T$>} for any $T$, or \FUNCTION,
  it is known that it will never occur as $T$ for rule~\SrnSuperinterface,
  which means that this seemingly expensive step
  can be confined to some extent.%
}


\section*{Appendix: Integer Implementations}
\LMLabel{integerImplementations}

\commentary{%
  The \code{int} type represents integers.
  The specification is written with 64-bit two's complement integers as the
  intended implementation. But when Dart is compiled to JavaScript,
  the implementation of \code{int} will instead use the JavaScript number type
  and the corresponding JavaScript operations,
  except for bit operations as explained below.

  This introduces a number of differences:

  \begin{itemize}
  \item[$\bullet$]
    Valid values of JavaScript \code{int} are any IEEE-754 64-bit
    floating point number with no fractional part. This includes
    positive and negative \Index{infinity}, which can be reached by
    overflowing (integer division by zero is still a dynamic error).
    Otherwise valid integer literals (including any leading minus sign)
    that represent invalid JavaScript \code{int} values are compile-time
    errors when compiling to JavaScript. Operations on integers may
    lose precision, because the operands and the result are represented
    as 64-bit floating point numbers that are limited to 53 significant
    bits.
  \item[$\bullet$]
    JavaScript \code{int} instances also implement \code{double}, and
    integer-valued \code{double} instances also implement \code{int}.
    The \code{int} and \code{double} class are still separate subclasses
    of the class \code{num}, but \emph{instances} of either class that
    represent an integer act as if they are actually instances of a
    common subclass implementing both \code{int} and \code{double}.
    Fractional numbers only implement \code{double}.
  \item[$\bullet$]
    Bitwise operations on integers (\lit{\&}, \lit{|}, \lit{\^},
    \lit{\gtilde}, \lit{\ltlt}, and \lit{\gtgt}) all truncate the
    operands to 32-bit two's complement integers, perform 32-bit
    operations on those, and the resulting 32 bits are interpreted as a
    32-bit unsigned integer. For example, \code{-1\,\ltlt\,1} evaluates
    to 4294967294 (also known as \code{(-2).toUnsigned(32)}). The right
    shift operator, \lit{\gtgt}, performs a signed right shift on the
    32 bits when the original number is negative, and an unsigned right
    shift when the original number is non-negative. Both kinds of shift
    writes bit $k+1$ into position $k$, $0 \leq k < 31$; but the signed
    shift leaves bit 31 unchanged, and the unsigned shift writes a 0
    as bit 31. For example:
    \code{0x80000002\,\gtgt\,1\ ==\ 0x40000001}, but
    \code{-0x7FFFFFFE\,\gtgt\,1\ ==\ 0xC0000001}.
    In this example we note that both \code{0x80000002} and \code{-0x7FFFFFFE}
    yield the 32-bit two's complement representation \code{0x80000002},
    but they have different values for the IEEE 754 sign bit.
  \item[$\bullet$]
    The \code{identical} method cannot distinguish the values $0.0$ and
    $-0.0$, and it cannot recognize any \Index{NaN} value as identical
    to itself. For efficiency, the \code{identical} operation uses the
    JavaScript \code{===} operator.
  \end{itemize}%
}

\printindex
\end{document}

[Text after \end{document} is ignored, hence we do not need "%"]
----------------------------------------------------------------------

* On Location Markers

This is a description of location markers, giving some information
about the underlying motivation and rationale, the actual
implementation, and the relevant tool support.

** What is a Location Marker?

In order to support more fine-grained update propagation from this
language specification to artifacts that depend on it, location
markers have been added. The idea is that each logical unit (section,
subsection, etc) and each paragraph containing normative text should
be addressable using these markers, such that source code (compilers
and other tools, tests, etc.) can contain location markers, and the
corresponding location in the spec may be looked up using standard
document viewer search features.

An SHA1 hash value of the text is associated with each location
marker, such that changes in the text will incur changes in this hash
value. Consequently, source code in tools/tests that depend on
specific parts of the spec may be flagged for revision by checking
whether these hash values have changed: If a given test T depends on
a paragraph with hash value V in the spec, and the search for V fails
in a new version of the spec, then that paragraph has changed and T
should be revisited and possible revised.

As a result, the search for parts of source code and similar artifacts
in likely need of updates because of spec changes can be performed
mechanically, which should help ensure that the conformance of all
artifacts depending on this spec is maintained more easily, and hence
more consistently. Note that it makes no difference whether the need
for an update has arisen in a very recent version of the spec or it
has existed for a long time, because the hash value just remains
different as long as the text is different from what it was when the
location marker was harvested from the spec.

** LaTeX Commands Supporting Location Markers

Concretely, this is based on the commands \LMHash and \LMLabel.
\LMHash{V} is used to add the text V in the margin, intended to mark
a paragraph of normative text with the SHA1 hash value of the text, V.
\LMLabel{L} has the effect of \label{L}, and moreover it shows the
text sec:L in the margin. In order to indicate a dependency on a
section or subsection an \LMLabel location marker is used, and in
order to indicate a dependency on a specific paragraph, the hash value
of that paragraph is used.

In this file, each normative paragraph has had the command \LMHash{}
added at the beginning, such that each of these paragraphs can be
decorated with their hash value. Similarly, all \section{}s,
\subsection{}s, \subsubsection{}s, and \paragraph{}s have had
their \label commands changed to \LMLabel, such that they are
decorated with logical names.

** Rationale

The design of location markers was proposed by Erik Ernst and
developed through discussions with several others, in particular Gilad
Bracha and Lars Bak. Some discussions along the way that gave rise to
the given design are outlined below.

The basic idea is that a hash value based on the actual text will
serve well to identify a piece of text, because it will change
whenever the text changes, and it remains the same if the text is
moved to a different location; in other words, it characterizes the
text itself, independently of the rest of the document. Hence:

  - references to specific paragraphs in the spec are easy to create:
    copy the marker and paste it into the source code (but see below
    why this uses an extra indirection as far as possible)

  - such references would be robust in the sense that they depend on
    the actual text alone, i.e., they would not be invalidated by
    updates to section numbers, relocation of the paragraph, or
    updates to text in different paragraphs; as Lars mentioned, we
    should use a "stripped" version of the text, removing comments,
    normalizing white space, etc., which would make the refs even more
    robust in case of "inessential" changes

  - artifacts depending on a given part of the spec that was
    changed could easily be pointed out: After an update to a
    part of the spec, that artifact would hold a marker associated
    with a hash value which does not any more occur in the spec,
    maintainers of the artifact would then receive a notification
    ("test1773 depends on a part of the spec that was updated").
    Nice tool support would show them the paragraph in the most recent
    version of the spec as well as the old version that the artifact
    used to depend on, and a comparison of the two would help
    clarifying what needs fixing because of this change, if anything.

However, there is a conflict in this scenario: Lars pointed out that
it is very inconvenient to have to create a lot of revision control
commits (e.g., new versions of tests), just because a large number of
artifacts depend on a specific hash value that changed, if that change
has no real impact on each of those artifacts. The obvious solution
to this problem would be to use symbolic names and keep the actual
hash values out of the primary artifacts.

This approach has been used for \section{}s, \subsection{}s, etc., by
using their labels as location markers. For instance, dependency on
\subsubsection{New} would be marked as a dependency on 'sec:new',
which will (most likely) exist with the same label in the spec for a
long time. To detect a need for updates, the hash value associated
with \subsubsection{New} from the date of the latest check of this
kind to the dependent artifact should be compared with the current
hash value for the same \subsubsection{}: The artifact should be
revisited iff those hash values differ. As an easy approximation to
this scheme, the hash values for all location markers would be
computed for each spec update, and the location markers that have new
hash values should cause revisits to all artifacts depending on that
location marker.

The symbolic location markers on larger units like \section{}
etc. enable location marking in a hierarchical fashion: Dependencies
on a \subsubsection{} or on a \section{} can be chosen according to
the actual needs with each dependent artifact. In general, fine
granularity helps avoiding false positives, where an update somewhere
in a large unit will flag too many dependent artifacts for revisits.
In contrast, coarse granularity enables other artifacts to declare the
actual dependencies when small units would be impractical because the
artifact depends on so many of them. But there is a problem at the
bottom of this hierarchy, namely with paragraphs.

It would be very inconvenient to have to invent a logical name for
every paragraph. Similarly, using a simple paragraph numbering would
be unstable (add one new paragraph in the beginning of a section, and
all the rest have new numbers, creating a massive flood of false
update alerts, or, even worse, corrupting the declared dependencies in
artifacts because they point to the wrong paragraphs).

Hence, paragraphs have no other label than their actual hash value.
Artifacts that depend on very specific elements in the spec may
declare so by using an actual hash value for a given paragraph, and in
return they pay in terms of potential updates to the marker when that
paragraph changes, even in cases where the actual change makes no
difference for that particular artifact. This choice of granularity
vs. stability is up to the creator of each artifact.

** Maintenance of this document

The invariant that each normative paragraph is associated with a line
containing the text \LMHash{} should be maintained. Extra occurrences
of \LMHash{} can be added if needed, e.g., in order to make
individual \item{}s in itemized lists addressable. Each \LM.. command
must occur on a separate line. \LMHash{} must occur immediately
before the associated paragraph, and \LMLabel must occur immediately
after the associated \section, \subsection{} etc.

----------------------------------------------------------------------
