@@ -6,10 +6,12 @@ Status: Draft
66
77## CHANGELOG
88
9- 2023.06.15
9+ 2023.06.24
1010 - Adjust function literal return type inference to avoid spurious application
1111 of ` flatten ` , and make sure return statements do not affect generator
1212 functions.
13+ - Specify the value context to use for generator functions for more
14+ non-trivial return types (not just ` Iterable<X> ` for some ` X ` ).
1315
14162022.05.12
1517 - Define the notions of "constraint solution for a set of type variables" and
@@ -265,11 +267,11 @@ unlike normal fields, the initializer for a `late` field may reference `this`.
265267Function literals which are inferred in an empty typing context (see below) are
266268inferred using the declared type for all of their parameters. If a parameter
267269has no declared type, it is treated as if it was declared with type ` dynamic ` .
268- Inference for each returned expression in the body of the function literal is
269- done in an empty typing context (see below).
270+ Inference for each returned or yielded expression in the body of the function
271+ literal is done with an empty _ value context _ scheme (see below).
270272
271273Function literals which are inferred in an non-empty typing context where the
272- context type is a function type are inferred as described below .
274+ context type is a function type are inferred as described here .
273275
274276Each parameter is assumed to have its declared type if present. If no type is
275277declared for a parameter and there is a corresponding parameter in the context
@@ -281,19 +283,21 @@ corresponding parameter in the context type schema, the variable is treated as
281283having type ` dynamic ` .
282284
283285The return type of the context function type is used at several points during
284- inference. We refer to this type as the ** imposed return type
285- schema** . Inference for each returned or yielded expression in the body of the
286- function literal is done using a context type derived from the imposed return
287- type schema ` S ` as follows:
286+ inference. We refer to this type as the ** imposed return type schema** .
287+
288+ Inference for each returned or yielded expression in the body of the
289+ function literal is done using a ** value context** type scheme derived from the
290+ imposed return type schema ` S ` as follows:
291+ - If function is declared ` async ` , then without null safety,
292+ the value context scheme is ** flatten** (` S ` );
293+ with null safety the value context scheme is
294+ ** futureValueTypeSchema** (` S ` ), as defined below.
295+ - If the function expression is declared ` async* ` then the value context
296+ scheme is ** streamElementTypeSchema** (` S ` ), as defined below.
297+ - If the function expression is declared ` sync* ` then the value context
298+ scheme is ** iterableElementTypeSchema** (` S ` ), as defined below.
288299 - If the function expression is neither ` async ` nor a generator, then the
289- context type is ` S ` .
290- - If the function expression is declared ` async* ` and ` S ` is of the form
291- ` Stream<S1> ` for some ` S1 ` , then the context type is ` S1 ` .
292- - If the function expression is declared ` sync* ` and ` S ` is of the form
293- ` Iterable<S1> ` for some ` S1 ` , then the context type is ` S1 ` .
294- - Otherwise, without null safety, the context type is ` flatten(T) `
295- where ` T ` is the imposed return type schema; with null safety, the context
296- type is ` futureValueTypeSchema(S) ` .
300+ value context scheme is ` S ` .
297301
298302The function ** futureValueTypeSchema** is defined as follows:
299303
@@ -306,70 +310,124 @@ The function **futureValueTypeSchema** is defined as follows:
306310- ** futureValueTypeSchema** (` _ ` ) = ` _ ` .
307311- Otherwise, for all other ` S ` , ** futureValueTypeSchema** (` S ` ) = ` Object? ` .
308312
309- _ Note that it is a compile-time error unless the return type of an asynchronous
310- non-generator function is a supertype of ` Future<Never> ` , which means that
311- the last case will only be applied when ` S ` is ` Object ` or a top type._
313+ The function ** streamElementTypeSchema** is defined as follow:
314+
315+ - ** streamElementTypeSchema** (` S? ` ) = ** streamElementTypeSchema** (` S ` ),
316+ for all ` S ` .
317+ - ** streamElementTypeSchema** (` S* ` ) = ** streamElementTypeSchema** (` S ` ),
318+ for all ` S ` .
319+ - ** streamElementTypeSchema** (` FutureOr<S> ` ) = ** streamElementTypeSchema** (` S ` ),
320+ for all ` S ` .
321+ - ** streamElementTypeSchema** (` Stream<S> ` ) = ` S ` , for all ` S ` .
322+ - ** streamElementTypeSchema** (` void ` ) = ` void `
323+ - ** streamElementTypeSchema** (` dynamic ` ) = ` dynamic `
324+ - ** streamElementTypeSchema** (` _ ` ) = ` _ `
325+ - Otherwise, for all other ` S ` , ** streamElementTypeSchema** (` S ` ) = ` Object? ` .
326+
327+ The function ** iterableElementTypeSchema** is defined as follow:
328+
329+ - ** iterableElementTypeSchema** (` S? ` ) = ** iterableElementTypeSchema** (` S ` ),
330+ for all ` S ` .
331+ - ** iterableElementTypeSchema** (` S* ` ) = ** iterableElementTypeSchema** (` S ` ),
332+ for all ` S ` .
333+ - ** iterableElementTypeSchema** (` FutureOr<S> ` ) =
334+ ** iterableElementTypeSchema** (` S ` ), for all ` S ` .
335+ - ** iterableElementTypeSchema** (` Iterable<S> ` ) = ` S ` , for all ` S ` .
336+ - ** iterableElementTypeSchema** (` void ` ) = ` void `
337+ - ** iterableElementTypeSchema** (` dynamic ` ) = ` dynamic `
338+ - ** iterableElementTypeSchema** (` _ ` ) = ` _ `
339+ - Otherwise, for all other ` S ` , ** iterableElementTypeSchema** (` S ` ) = ` Object? ` .
340+
341+ _ Note that it is a compile-time error unless the return type of an
342+ asynchronous non-generator function is a supertype of ` Future<Never> ` ,
343+ which means that the last case of ** futureValueTypeScheme** will only
344+ be applied when ` S ` is ` Object ` .
345+ Similarly for ` async* ` and ` sync* ` functions whose return types
346+ must be a supertypes of ` Stream<Never> ` and ` Iterable<Never> ` ._
312347
313348In order to infer the return type of a function literal, we first infer the
314- ** actual returned type** of the function literal.
315-
316- The actual returned type of a function literal with an expression body is the
317- inferred type of the expression body, using the local type inference algorithm
318- described below with a typing context as computed above.
319-
320- The actual returned type of a function literal with a block body is computed as
321- follows. Let ` T ` be ` Never ` if every control path through the block exits the
322- block without reaching the end of the block, as computed by the ** definite
323- completion** analysis specified elsewhere, or if the function is a generator
324- function.
325- Let ` T ` be ` Null ` if the function is a non-generator function and any control
326- path reaches the end of the block without exiting the block, as computed by the
327- ** definite completion** analysis specified elsewhere. Let ` K ` be the typing
328- context for the function body as computed above from the imposed return type
329- schema.
349+ ** actual value type** of the function literal. _ The actual value type
350+ represents the types of the actual values returned by non-generator functions,
351+ and the values emitted by generator functions._
352+
353+ Let ` K ` be the value context schema for the function body as computed above
354+ from the imposed return type schema.
355+ _ When we refer to the _ inferred type_ of an expression with a typing context,
356+ it is the type inferred using the local type inference algorithm
357+ described below._
358+
359+ The actual value type of a function literal with an expression body, ` => e ` ,
360+ _ (which cannot be a generator function)_ is computed as follows:
361+ - If the enclosing function is marked ` async ` ,
362+ let ` T ` be the inferred type of the returned expession with ` FutureOr<K> `
363+ as typing context.
364+ The actual value type is ** flatten** (` T ` ).
365+ - If the enclosing function is not marked ` async ` , let ` T ` be the inferred
366+ type of the returned expression with typing context ` K ` .
367+ The actually value type is ` T ` .
368+
369+ The actual value type of a function literal with a block body is computed as
370+ follows.
371+ Let ` T ` be ` Never ` if the function is a generator function,
372+ or if every control path through the block exits the block without
373+ reaching the end of the block, as computed by the ** definite completion**
374+ analysis specified elsewhere.
375+ Otherwise _ (the function is a non-generator function and at least
376+ one control path reaches the end of the block)_ let ` T ` be ` null ` .
377+
378+ Then process relevant statements of the block, one by one in source order,
379+ to find a value type ` V ` for that statement.
380+
330381 - If the enclosing function is a non-` async ` non-generator function,
331- for each ` return e; ` statement in the block, let ` S ` be the inferred type
332- of ` e ` , using the local type inference algorithm described below with typing
333- context ` K ` , and update ` T ` to be ` UP(S, T) ` .
334- - If the enclosing function is marekd ` async ` , for each ` return e; ` statement
335- in the block, let ` S ` be the inferred type of ` e ` , using the local type
336- inference algorithm described below with typing context ` FutureOr<K> ` ,
337- and update ` T ` to be ` UP(flatten(S), T) ` .
338- - If the enclosing function is a non-generator function, for each ` return; `
339- statement in the block, update ` T ` to be ` UP(Null, T) ` .
340- - For each ` yield e; ` statement in the block, let ` S ` be the inferred type of
341- ` e ` , using the local type inference algorithm described below with typing
342- context ` K ` , and update ` T ` to be ` UP(S, T) ` .
343- - If the enclosing function is marked ` sync* ` , then for each ` yield* e; `
344- statement in the block, let ` S ` be the inferred type of ` e ` , using the
345- local type inference algorithm described below with a typing context of
346- ` Iterable<K> ` . If there exists a type ` E ` such that ` Iterable<E> ` is a
347- super-interface of ` S ` , update ` T ` to be ` UP(E, T) ` . Otherwise update
348- ` T ` to be ` UP(S, T) ` .
349- _ It is a compile-time error if * S* is not a assignable to
350- ` Iterable<Object?> ` , so either * S* implements ` Iterable ` , or it is one of
351- ` dynamic ` or ` Never ` ._
352- - If the enclosing function is marked ` async* ` , then for each ` yield* e; `
353- statement in the block, let ` S ` be the inferred type of ` e ` , using the
354- local type inference algorithm described below with a typing context of
355- ` Stream<K> ` . If there exists a type ` E ` such that ` Stream<E> ` is a
356- super-interface of ` S ` , update ` T ` to be ` UP(E, T) ` . Otherwise update
357- ` T ` to be ` UP(S, T) ` .
358- _ It is a compile-time error if * S* is not a assignable to
359- ` Stream<Object?> ` , so either * S* implements ` Iterable ` , or it is one of
360- ` dynamic ` or ` Never ` ._
361-
362- The ** actual returned type** of the function literal is the value of ` T ` after
382+ the relevant statements are ` return; ` or ` return e; ` statements.
383+ - For a ` return; ` statement, let ` V ` be ` Null ` .
384+ - For a ` return e; ` statement, let ` V ` be the inferred type of ` e ` with
385+ ` K ` as context type scheme, using the local type inference algorithm
386+ described below.
387+
388+ - If the enclosing function is marked ` async ` , the relevant statements
389+ are ` return; ` and ` return e; ` statements.
390+ * For a ` return; ` statement, let ` V ` be ` Null ` .
391+ * For a ` return e; ` statement, let ` S ` be the inferred type of ` e `
392+ with typing context ` FutureOr<K> ` . Let ` V ` be ** flatten** (` S ` ).
393+
394+ - If the enclosing function is marked ` sync* ` , the relevant statements
395+ are ` yield e; ` or ` yield* e; ` statement.
396+ * For a ` yield e; ` statement, let ` V ` be the inferred type of ` e ` with
397+ typing context ` K ` .
398+ * For a ` yield* e; ` statement, let ` S ` be the inferred type of ` e ` with
399+ typing context ` Iterable<K> ` .
400+ If ` S ` implements ` Iterable<R> ` for some ` R ` , let ` V ` be ` R ` .
401+ Otherwise let ` V ` be ` S ` .
402+ _ It is a compile-time error if ` S ` is not a assignable to
403+ ` Iterable<Object?> ` , so either ` S ` implements ` Iterable ` ,
404+ or it is one of ` dynamic ` or ` Never ` ._
405+
406+ - If the enclosing function is marked ` async* ` , the relevant statements are
407+ ` yield e; ` or ` yield* e; ` statements.
408+ * For a ` yield e; ` statement, let ` V ` be the inferred type of ` e ` with
409+ typing context ` K ` .
410+ * For a ` yield* e; ` statement, let ` S ` be the inferred type of ` e ` with
411+ typing context ` Stream<K> ` .
412+ If ` S ` implements ` Stream<R> ` for some ` R ` , let ` V ` be ` R ` .
413+ Otherwise let ` V ` be ` S ` .
414+ _ It is a compile-time error if ` S ` is not a assignable to
415+ ` Stream<Object?> ` , so either ` S ` implements ` Stream ` ,
416+ or it is one of ` dynamic ` or ` Never ` ._
417+
418+ After processing each relevant statement, update ` T ` to be ** UP** (` T ` , ` V ` ).
419+
420+ The ** actual value type** of the function literal is the value of ` T ` after
363421all ` return ` and ` yield ` statements in the block body have been considered.
364422
365- Let ` T ` be the ** actual returned type** of a function literal as computed above.
423+ Let ` T ` be the ** actual value type** of a function literal as computed above.
366424Let ` R ` be the greatest closure of the typing context ` K ` as computed above.
367425
368426With null safety, if ` R ` is ` void ` , let ` S ` be ` void `
369427_ (without null-safety: no special treatment is applicable to ` void ` )_ .
370428
371429Otherwise (_ without null safety or if ` R ` is not ` void ` _ ),
372- if ` T <: R ` then let ` S ` be ` T ` . Otherwise, let ` S ` be ` R ` . The
430+ if ` T <: R ` then let ` S ` be ` T ` , else let ` S ` be ` R ` . The
373431inferred return type of the function literal is then defined as follows:
374432
375433 - If the function literal is marked ` async ` then the inferred return type is
0 commit comments