From 0a70ae2c4680190246464c0a8dbfead0dc1a3352 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Thu, 15 Jun 2023 10:32:20 +0200 Subject: [PATCH 1/5] Typo --- resources/type-system/inference.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/type-system/inference.md b/resources/type-system/inference.md index f33b439e78..72dbfd58ee 100644 --- a/resources/type-system/inference.md +++ b/resources/type-system/inference.md @@ -6,6 +6,10 @@ Status: Draft ## CHANGELOG +2023.06.15 + - Adjust function literal return type inference to avoid spurious application + of `flatten`. + 2022.05.12 - Define the notions of "constraint solution for a set of type variables" and "Grounded constraint solution for a set of type variables". These @@ -349,11 +353,12 @@ With null safety: if `R` is `void`, or the function literal is marked `async` and `R` is `FutureOr`, let `S` be `void` (without null-safety: no special treatment is applicable to `void`). -Otherwise, if `T <: R` then let `S` be `T`. Otherwise, let `S` be `R`. The -inferred return type of the function literal is then defined as follows: +Otherwise, if `T <: R` then let `S` be `T`. Otherwise, let `S` be +`flatten(R)` if the function literal is marked `async`, and `R` otherwise. +The inferred return type of the function literal is then defined as follows: - If the function literal is marked `async` then the inferred return type is - `Future`. + `Future`. - If the function literal is marked `async*` then the inferred return type is `Stream`. - If the function literal is marked `sync*` then the inferred return type is From 491747298ab03200bbb5cdea8122f4c801cd3808 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Thu, 15 Jun 2023 11:59:46 +0200 Subject: [PATCH 2/5] Correction: must flatten the context type when testing T <: R, too --- resources/type-system/inference.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/type-system/inference.md b/resources/type-system/inference.md index 72dbfd58ee..f59ed9dde6 100644 --- a/resources/type-system/inference.md +++ b/resources/type-system/inference.md @@ -353,9 +353,10 @@ With null safety: if `R` is `void`, or the function literal is marked `async` and `R` is `FutureOr`, let `S` be `void` (without null-safety: no special treatment is applicable to `void`). -Otherwise, if `T <: R` then let `S` be `T`. Otherwise, let `S` be -`flatten(R)` if the function literal is marked `async`, and `R` otherwise. -The inferred return type of the function literal is then defined as follows: +When the function is marked `async`: if `T <: flatten(R)` then let `S` be `T`; +otherwise let `S` be `flatten(R)`. When the function is not marked `async`: if +`T <: R` then let `S` be `T`; otherwise let `S` be `R`. The inferred return +type of the function literal is then defined as follows: - If the function literal is marked `async` then the inferred return type is `Future`. From 01e0a9bc2b743d1425199392af9637fb1eb81153 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Thu, 15 Jun 2023 12:13:31 +0200 Subject: [PATCH 3/5] Clarified the meaning of `S` --- resources/type-system/inference.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/type-system/inference.md b/resources/type-system/inference.md index f59ed9dde6..6b37fa626c 100644 --- a/resources/type-system/inference.md +++ b/resources/type-system/inference.md @@ -349,14 +349,17 @@ all `return` and `yield` statements in the block body have been considered. Let `T` be the **actual returned type** of a function literal as computed above. Let `R` be the greatest closure of the typing context `K` as computed above. +*Now compute `S`, which is the future value type of an `async` function, the +element type of a generator function, and the return type of other functions.* + With null safety: if `R` is `void`, or the function literal is marked `async` and `R` is `FutureOr`, let `S` be `void` (without null-safety: no special treatment is applicable to `void`). -When the function is marked `async`: if `T <: flatten(R)` then let `S` be `T`; -otherwise let `S` be `flatten(R)`. When the function is not marked `async`: if -`T <: R` then let `S` be `T`; otherwise let `S` be `R`. The inferred return -type of the function literal is then defined as follows: +When the function is marked `async`: if `T <: futureValueType(R)` then let `S` +be `T`; otherwise let `S` be `futureValueType(R)`. When the function is not +marked `async`: if `T <: R` then let `S` be `T`; otherwise let `S` be `R`. The +inferred return type of the function literal is then defined as follows: - If the function literal is marked `async` then the inferred return type is `Future`. From 322a81ec2fc04f53f331cfe812d3fcfefbbbb2ba Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Thu, 15 Jun 2023 13:16:15 +0200 Subject: [PATCH 4/5] Clarify the logic (when each sentence is applicable) --- resources/type-system/inference.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/type-system/inference.md b/resources/type-system/inference.md index 6b37fa626c..93b36278f6 100644 --- a/resources/type-system/inference.md +++ b/resources/type-system/inference.md @@ -356,10 +356,11 @@ With null safety: if `R` is `void`, or the function literal is marked `async` and `R` is `FutureOr`, let `S` be `void` (without null-safety: no special treatment is applicable to `void`). -When the function is marked `async`: if `T <: futureValueType(R)` then let `S` -be `T`; otherwise let `S` be `futureValueType(R)`. When the function is not -marked `async`: if `T <: R` then let `S` be `T`; otherwise let `S` be `R`. The -inferred return type of the function literal is then defined as follows: +If the previous paragraph did not yield a value for `S`: When the function is +marked `async`: if `T <: futureValueType(R)` then let `S` be `T`; otherwise let +`S` be `futureValueType(R)`. When the function is not marked `async`: if `T <: +R` then let `S` be `T`; otherwise let `S` be `R`. The inferred return type of +the function literal is then defined as follows: - If the function literal is marked `async` then the inferred return type is `Future`. From 20b0dc6065f30fb41a04cf4c925d5d49d57a6bca Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Thu, 15 Jun 2023 13:17:14 +0200 Subject: [PATCH 5/5] Whitespace --- resources/type-system/inference.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/type-system/inference.md b/resources/type-system/inference.md index 93b36278f6..49d954b3d6 100644 --- a/resources/type-system/inference.md +++ b/resources/type-system/inference.md @@ -359,8 +359,9 @@ treatment is applicable to `void`). If the previous paragraph did not yield a value for `S`: When the function is marked `async`: if `T <: futureValueType(R)` then let `S` be `T`; otherwise let `S` be `futureValueType(R)`. When the function is not marked `async`: if `T <: -R` then let `S` be `T`; otherwise let `S` be `R`. The inferred return type of -the function literal is then defined as follows: +R` then let `S` be `T`; otherwise let `S` be `R`. + +The inferred return type of the function literal is then defined as follows: - If the function literal is marked `async` then the inferred return type is `Future`.