From 57ac9a80945ccfdc980eba7e6cce2812d063a823 Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:36:08 -0700 Subject: [PATCH 1/9] Collection literals: update type inference --- proposals/collection-literals.md | 94 +++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 25 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index 4826916092..ab6dc56e43 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -295,44 +295,88 @@ List e3 = [..e1]; // error? ## Type inference ```c# -AsArray([1, 2, 3]); // ok: AsArray(int[]) -[4].AsImmutableArray(); // ok: AsImmutableArray(ImmutableArray) +AsArray([1, 2, 3]); // AsArray(int[]) static T[] AsArray(this T[] arg) => arg; -static ImmutableArray AsImmutableArray(this ImmutableArray arg) => arg; ``` -The existing rules for type inference (see [§11.6.3](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference)) include the following **additions** for *exact inferences* §11.6.3.9, *lower-bound inferences* §11.6.3.10 and *upper-bound inferences* §11.6.3.11. The additions are the same for each section. +The *natural element type* of a collection literal expression is the [*best common type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#116315-finding-the-best-common-type-of-a-set-of-expressions) of: +* For each *expression element* `Ei`, the expression `Ei` +* For each *spread element* `Si`, the *iteration type* of `Si` +The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are extended to include inference from the *natural element type* of collection literal expressions. The following rules are **added**. + +> 11.6.3.9 Exact inferences +> > An *exact inference* *from* a type `U` *to* a type `V` is made as follows: > -> - If `V` is one of the *unfixed* `Xᵢ` then `U` is added to the set of exact bounds for `Xᵢ`. -> - Otherwise, sets `V₁...Vₑ` and `U₁...Uₑ` are determined by checking if any of the following cases apply: -> - `V` is an array type `V₁[...]` and `U` is an array type `U₁[...]` of the same rank -> - **`V` is a single-dimensional array type `V₁[]` and `U` is a collection literal with element type `U₁`** -> - `V` is the type `V₁?` and `U` is the type `U₁` -> - `V` is a constructed type `C` and `U` is a constructed type `C` -> - **`V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`** +> - ... +> - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then an *exact inference* is made from `U₁` to `V₁`.** +> - Otherwise, no inferences are made. + +> 11.6.3.10 Lower-bound inferences +> +> A *lower-bound inference from* a type `U` *to* a type `V` is made as follows: > -> If any of these cases apply then an *exact inference* is made from each `Uᵢ` to the corresponding `Vᵢ`. +> - ... +> - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then a *lower-bound inference* is made from `U₁` to `V₁`.** +> - Otherwise, no inferences are made. -_How do we recognize that `C` has element type `V₁`?_ +> 11.6.3.11 Upper-bound inferences +> +> An *upper-bound inference from* a type `U` *to* a type `V` is made as follows: +> +> - ... +> - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then an *upper-bound inference* is made from `U₁` to `V₁`.** +> - Otherwise, no inferences are made. -_Update to include inference from dictionary types._ -```c# -var d = ["Alice": 42, "Bob": 43].AsDictionary(comparer); +> 11.6.3.12 Fixing +> +> An *unfixed* type variable `Xᵢ` with a set of bounds is *fixed* as follows: +> +> - The set of *candidate types* `Uₑ` starts out as the set of all types in the set of bounds for `Xᵢ` **where types inferred from collection literal element types are ignored if there are any types that were not inferred from collection literal element types**. +> - ... -static Dictionary AsDictionary( - this List> list, - IEqualityComparer comparer = null) { ... } -``` +### Open questions -_What are the implications of type inference of spread elements?_ -```c# -F([..[1, 2]]); // ok: F(int[]) +- How do we recognize that `C` has element type `V₁`? -static void F(T[] arg) { } -``` +- What changes are required for conditional operator? + +- Can we support inference from extension method `this`? + + ```c# + [4].AsImmutableArray(); // AsImmutableArray(ImmutableArray) + + static ImmutableArray AsImmutableArray(this ImmutableArray arg) => arg; + ``` + +- What changes are required for dictionary types? + + ```c# + var d = ["Alice": 42, "Bob": 43].AsDictionary(comparer); + + static Dictionary AsDictionary( + this List> list, + IEqualityComparer comparer = null) { ... } + ``` + +- Infer from spread element iterator type? + + ```c# + IEnumerable e = [1, 2, 3]; + AsArray([..e]); // AsArray(int[]) + ``` + +- Infer from nested collection literals? + + ```c# + NestedArray([[1, 2, 3], []]); // NestedArray(int[][]) + + static void NestedArray(T[][] arg) { } + ``` + + This might be supported by introducing a *collection type* at compile time that represents an arbitrary collection with a specific *natural element type* and that is recognized in type inference similar to support for [*function types*](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type) for lambda expressions. ### Interaction with natural type From 338287217d1cae9afe8c0f81c158758227ec19d3 Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Sat, 17 Jun 2023 08:40:42 -0700 Subject: [PATCH 2/9] Update lower-bound rules only --- proposals/collection-literals.md | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index ab6dc56e43..64f7a93cf5 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -304,15 +304,9 @@ The *natural element type* of a collection literal expression is the [*best comm * For each *expression element* `Ei`, the expression `Ei` * For each *spread element* `Si`, the *iteration type* of `Si` -The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are extended to include inference from the *natural element type* of collection literal expressions. The following rules are **added**. - -> 11.6.3.9 Exact inferences -> -> An *exact inference* *from* a type `U` *to* a type `V` is made as follows: -> -> - ... -> - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then an *exact inference* is made from `U₁` to `V₁`.** -> - Otherwise, no inferences are made. +The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are extended to include inference from the *natural element type* of collection literal expressions. +Collection literal expressions only contribute to *lower bounds*, even when passed as arguments to `in` parameters. +The following type inference rules are **added**. > 11.6.3.10 Lower-bound inferences > @@ -322,14 +316,6 @@ The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/st > - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then a *lower-bound inference* is made from `U₁` to `V₁`.** > - Otherwise, no inferences are made. -> 11.6.3.11 Upper-bound inferences -> -> An *upper-bound inference from* a type `U` *to* a type `V` is made as follows: -> -> - ... -> - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then an *upper-bound inference* is made from `U₁` to `V₁`.** -> - Otherwise, no inferences are made. - > 11.6.3.12 Fixing > > An *unfixed* type variable `Xᵢ` with a set of bounds is *fixed* as follows: From 4207d2ec4357ab84039de19cf7a70b3d4db4353f Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Sun, 18 Jun 2023 10:59:37 -0700 Subject: [PATCH 3/9] Add extension methods --- proposals/collection-literals.md | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index 64f7a93cf5..fb743658dd 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -295,7 +295,7 @@ List e3 = [..e1]; // error? ## Type inference ```c# -AsArray([1, 2, 3]); // AsArray(int[]) +var a = AsArray([1, 2, 3]); // AsArray(int[]) static T[] AsArray(this T[] arg) => arg; ``` @@ -304,9 +304,8 @@ The *natural element type* of a collection literal expression is the [*best comm * For each *expression element* `Ei`, the expression `Ei` * For each *spread element* `Si`, the *iteration type* of `Si` -The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are extended to include inference from the *natural element type* of collection literal expressions. -Collection literal expressions only contribute to *lower bounds*, even when passed as arguments to `in` parameters. -The following type inference rules are **added**. +The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are **updated** to include inferences from the *natural element type* of collection literal expressions. +Collection literal expressions only contribute to *lower bounds*, even when passed as arguments to `in` parameters so *lower-bound* are updated but *upper-bound* and *exact* inferences are not. > 11.6.3.10 Lower-bound inferences > @@ -323,19 +322,27 @@ The following type inference rules are **added**. > - The set of *candidate types* `Uₑ` starts out as the set of all types in the set of bounds for `Xᵢ` **where types inferred from collection literal element types are ignored if there are any types that were not inferred from collection literal element types**. > - ... -### Open questions +## Extension methods +```c# +var ia = [4].AsImmutableArray(); // AsImmutableArray(ImmutableArray) -- How do we recognize that `C` has element type `V₁`? +static ImmutableArray AsImmutableArray(this ImmutableArray arg) => arg; +``` -- What changes are required for conditional operator? +The existing [*extension method invocation*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#11783-extension-method-invocations) rules are **updated** to include conversions from collection literal expressions. -- Can we support inference from extension method `this`? +> 11.7.8.3 Extension method invocations +> +> An extension method `Cᵢ.Mₑ` is *eligible* if: +> +> - ... +> - An implicit identity, reference, **collection literal**, or boxing conversion exists from *expr* to the type of the first parameter of `Mₑ`. - ```c# - [4].AsImmutableArray(); // AsImmutableArray(ImmutableArray) +## Open questions - static ImmutableArray AsImmutableArray(this ImmutableArray arg) => arg; - ``` +- How do we recognize that `C` has element type `V₁`? + +- What changes are required for conditional operator? - What changes are required for dictionary types? @@ -347,13 +354,6 @@ The following type inference rules are **added**. IEqualityComparer comparer = null) { ... } ``` -- Infer from spread element iterator type? - - ```c# - IEnumerable e = [1, 2, 3]; - AsArray([..e]); // AsArray(int[]) - ``` - - Infer from nested collection literals? ```c# @@ -364,7 +364,7 @@ The following type inference rules are **added**. This might be supported by introducing a *collection type* at compile time that represents an arbitrary collection with a specific *natural element type* and that is recognized in type inference similar to support for [*function types*](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type) for lambda expressions. -### Interaction with natural type +## Interaction with natural type The *natural type* should not prevent conversions to other collection types in *best common type* or *type inference* scenarios. ```c# From 10df7b4ad58eaca00a2addf82afd1aa1a6d0dac0 Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Sun, 18 Jun 2023 20:51:19 -0700 Subject: [PATCH 4/9] Misc. --- proposals/collection-literals.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index fb743658dd..c8a7e5335d 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -297,7 +297,7 @@ List e3 = [..e1]; // error? ```c# var a = AsArray([1, 2, 3]); // AsArray(int[]) -static T[] AsArray(this T[] arg) => arg; +static T[] AsArray(T[] arg) => arg; ``` The *natural element type* of a collection literal expression is the [*best common type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#116315-finding-the-best-common-type-of-a-set-of-expressions) of: @@ -342,6 +342,16 @@ The existing [*extension method invocation*](https://github.com/dotnet/csharpsta - How do we recognize that `C` has element type `V₁`? +- Infer from nested collection literals? + + ```c# + NestedArray([[1, 2, 3], []]); // NestedArray(int[][]) + + static void NestedArray(T[][] arg) { } + ``` + + This might be supported by introducing a *collection type* at compile time that represents an arbitrary collection with a specific *natural element type* and that is recognized in type inference similar to support for [*function types*](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type) for lambda expressions. + - What changes are required for conditional operator? - What changes are required for dictionary types? @@ -354,16 +364,6 @@ The existing [*extension method invocation*](https://github.com/dotnet/csharpsta IEqualityComparer comparer = null) { ... } ``` -- Infer from nested collection literals? - - ```c# - NestedArray([[1, 2, 3], []]); // NestedArray(int[][]) - - static void NestedArray(T[][] arg) { } - ``` - - This might be supported by introducing a *collection type* at compile time that represents an arbitrary collection with a specific *natural element type* and that is recognized in type inference similar to support for [*function types*](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type) for lambda expressions. - ## Interaction with natural type The *natural type* should not prevent conversions to other collection types in *best common type* or *type inference* scenarios. From d24aaec6f52f99fb62cd40795588ecffc4988f3f Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Mon, 19 Jun 2023 15:29:39 -0700 Subject: [PATCH 5/9] Updates following LDM discussion --- proposals/collection-literals.md | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index c8a7e5335d..2596dd3dfb 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -300,27 +300,20 @@ var a = AsArray([1, 2, 3]); // AsArray(int[]) static T[] AsArray(T[] arg) => arg; ``` -The *natural element type* of a collection literal expression is the [*best common type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#116315-finding-the-best-common-type-of-a-set-of-expressions) of: -* For each *expression element* `Ei`, the expression `Ei` -* For each *spread element* `Si`, the *iteration type* of `Si` +The [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are **updated** to include inferences from collection literal expressions. -The existing [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are **updated** to include inferences from the *natural element type* of collection literal expressions. -Collection literal expressions only contribute to *lower bounds*, even when passed as arguments to `in` parameters so *lower-bound* are updated but *upper-bound* and *exact* inferences are not. - -> 11.6.3.10 Lower-bound inferences -> -> A *lower-bound inference from* a type `U` *to* a type `V` is made as follows: -> -> - ... -> - **Otherwise, if `V` is a single-dimensional array type `V₁[]` or `V` is a constructible collection type `C` with element type `V₁`, and `U` is a collection literal with element type `U₁`, then a *lower-bound inference* is made from `U₁` to `V₁`.** -> - Otherwise, no inferences are made. - -> 11.6.3.12 Fixing +> 11.6.3.2 The first phase > -> An *unfixed* type variable `Xᵢ` with a set of bounds is *fixed* as follows: +> For each of the method arguments `Eᵢ`: > -> - The set of *candidate types* `Uₑ` starts out as the set of all types in the set of bounds for `Xᵢ` **where types inferred from collection literal element types are ignored if there are any types that were not inferred from collection literal element types**. +> - **If `Eᵢ` is a *collection literal*, a *collection element type inference* is made *from* `Eᵢ` *to* the corresponding *parameter type* `Tᵢ`.** > - ... +> +A *collection element type inference* is made *from* a expression `E` *to* a type `T` as follows: +- If `E` is a collection literal with elements `Eᵢ`, and `T` is a *single-dimensional array type* `Tₑ[]` or `T` is [*collection type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) with an [*iteration type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) `Tₑ`, then for each `Eᵢ`: + - If `Eᵢ` is a *collection literal*, a *collection element type inference* is made *from* `Eᵢ` *to* `Tₑ`. + - Otherwise, if `Eᵢ` has type `Uᵢ` then a *lower-bound inference* is made *from* `Uᵢ` *to* `Tₑ`. + - Otherwise, no inferences are made for `Eᵢ`. ## Extension methods ```c# @@ -329,7 +322,7 @@ var ia = [4].AsImmutableArray(); // AsImmutableArray(ImmutableArray) static ImmutableArray AsImmutableArray(this ImmutableArray arg) => arg; ``` -The existing [*extension method invocation*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#11783-extension-method-invocations) rules are **updated** to include conversions from collection literal expressions. +The [*extension method invocation*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#11783-extension-method-invocations) rules are **updated** to include conversions from collection literal expressions. > 11.7.8.3 Extension method invocations > From ff5227f87e604a30150fc5bf2deccb6f9499997b Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:55:42 -0700 Subject: [PATCH 6/9] Rename term --- proposals/collection-literals.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index 2596dd3dfb..df5503dc08 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -306,12 +306,12 @@ The [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6 > > For each of the method arguments `Eᵢ`: > -> - **If `Eᵢ` is a *collection literal*, a *collection element type inference* is made *from* `Eᵢ` *to* the corresponding *parameter type* `Tᵢ`.** +> - **If `Eᵢ` is a *collection literal*, a *collection literal inference* is made *from* `Eᵢ` *to* the corresponding *parameter type* `Tᵢ`.** > - ... > -A *collection element type inference* is made *from* a expression `E` *to* a type `T` as follows: +A *collection literal inference* is made *from* a expression `E` *to* a type `T` as follows: - If `E` is a collection literal with elements `Eᵢ`, and `T` is a *single-dimensional array type* `Tₑ[]` or `T` is [*collection type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) with an [*iteration type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) `Tₑ`, then for each `Eᵢ`: - - If `Eᵢ` is a *collection literal*, a *collection element type inference* is made *from* `Eᵢ` *to* `Tₑ`. + - If `Eᵢ` is a *collection literal*, a *collection literal inference* is made *from* `Eᵢ` *to* `Tₑ`. - Otherwise, if `Eᵢ` has type `Uᵢ` then a *lower-bound inference* is made *from* `Uᵢ` *to* `Tₑ`. - Otherwise, no inferences are made for `Eᵢ`. From f45cf064df3fb4040578e3e9cf826bc0655eaece Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Tue, 20 Jun 2023 10:59:43 -0700 Subject: [PATCH 7/9] Update open questions --- proposals/collection-literals.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index df5503dc08..0d70dc47ab 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -295,9 +295,11 @@ List e3 = [..e1]; // error? ## Type inference ```c# -var a = AsArray([1, 2, 3]); // AsArray(int[]) +var a = AsArray([1, 2, 3]); // AsArray(int[]) +var b = AsListOfArray([[4, 5], []]); // AsListOfArray(List) static T[] AsArray(T[] arg) => arg; +static List AsListOfArray(List arg) => arg; ``` The [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are **updated** to include inferences from collection literal expressions. @@ -333,18 +335,6 @@ The [*extension method invocation*](https://github.com/dotnet/csharpstandard/blo ## Open questions -- How do we recognize that `C` has element type `V₁`? - -- Infer from nested collection literals? - - ```c# - NestedArray([[1, 2, 3], []]); // NestedArray(int[][]) - - static void NestedArray(T[][] arg) { } - ``` - - This might be supported by introducing a *collection type* at compile time that represents an arbitrary collection with a specific *natural element type* and that is recognized in type inference similar to support for [*function types*](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md#natural-function-type) for lambda expressions. - - What changes are required for conditional operator? - What changes are required for dictionary types? From 65dd585eab35c0d7e349070db5c4bd179b9b4408 Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Wed, 21 Jun 2023 09:57:16 -0700 Subject: [PATCH 8/9] Simplify rule --- proposals/collection-literals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index 0d70dc47ab..e24954cd4d 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -312,7 +312,7 @@ The [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6 > - ... > A *collection literal inference* is made *from* a expression `E` *to* a type `T` as follows: -- If `E` is a collection literal with elements `Eᵢ`, and `T` is a *single-dimensional array type* `Tₑ[]` or `T` is [*collection type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) with an [*iteration type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) `Tₑ`, then for each `Eᵢ`: +- If `E` is a collection literal with elements `Eᵢ` and `T` is a [*collection type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) with an [*iteration type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) `Tₑ`, then for each `Eᵢ`: - If `Eᵢ` is a *collection literal*, a *collection literal inference* is made *from* `Eᵢ` *to* `Tₑ`. - Otherwise, if `Eᵢ` has type `Uᵢ` then a *lower-bound inference* is made *from* `Uᵢ` *to* `Tₑ`. - Otherwise, no inferences are made for `Eᵢ`. From 30ddbea53b3c4448e6ed898efe175275dd694ce7 Mon Sep 17 00:00:00 2001 From: Charles Stoner <10732005+cston@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:28:37 -0700 Subject: [PATCH 9/9] Fix typo, formatting --- proposals/collection-literals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/collection-literals.md b/proposals/collection-literals.md index e24954cd4d..619de20160 100644 --- a/proposals/collection-literals.md +++ b/proposals/collection-literals.md @@ -311,8 +311,8 @@ The [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6 > - **If `Eᵢ` is a *collection literal*, a *collection literal inference* is made *from* `Eᵢ` *to* the corresponding *parameter type* `Tᵢ`.** > - ... > -A *collection literal inference* is made *from* a expression `E` *to* a type `T` as follows: -- If `E` is a collection literal with elements `Eᵢ` and `T` is a [*collection type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) with an [*iteration type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) `Tₑ`, then for each `Eᵢ`: +A *collection literal inference* is made *from* an expression `E` *to* a type `T` as follows: +- If `E` is a *collection literal* with elements `Eᵢ` and `T` is a [*collection type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) with an [*iteration type*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/statements.md#1295-the-foreach-statement) `Tₑ`, then for each `Eᵢ`: - If `Eᵢ` is a *collection literal*, a *collection literal inference* is made *from* `Eᵢ` *to* `Tₑ`. - Otherwise, if `Eᵢ` has type `Uᵢ` then a *lower-bound inference* is made *from* `Uᵢ` *to* `Tₑ`. - Otherwise, no inferences are made for `Eᵢ`.