Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collection literals: output type inferences #7293

Merged
merged 2 commits into from
Jun 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions proposals/collection-literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,20 +302,26 @@ static T[] AsArray<T>(T[] arg) => arg;
static List<T[]> AsListOfArray<T>(List<T[]> 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.
The [*type inference*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#1163-type-inference) rules are updated as follows.
The existing rules for the [*first phase*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#11632-the-first-phase) are extracted to a new *input type inference* section, and a rule is added to *input type inference* and *output type inference* for collection literal expressions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The existing rules for the [*first phase*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#11632-the-first-phase) are extracted to a new *input type inference* section, and a rule is added to *input type inference* and *output type inference* for collection literal expressions.
The existing rules for the [*first phase*](https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/expressions.md#11632-the-first-phase) are extracted to a new *input type inference* section, and a rule is added to *input type inference* and *output type inference* for collection literal expressions.

> 11.6.3.2 The first phase
>
> For each of the method arguments `Eᵢ`:
> - An *input type inference* is made *from* `Eᵢ` *to* the corresponding *parameter type* `Tᵢ`.
Copy link
Member Author

@cston cston Jun 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted existing rules to an input type inference section based on suggestion from @MadsTorgersen.


> An *input type inference* is made *from* an expression `E` *to* a type `T` in the following way:
>
> - 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 an *input type inference* is made *from* each `Eᵢ` *to* `Tₑ`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little concerned about the interaction of this rule with tuples. I think what the LDM wants is multi-level walks here, where a tuple of collection literals would walk through multiple levels if T is such a type, but this wouldn't do that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule for collection literals and the rule for tuple literals both use this input type inference rule for their parts.

> - *[existing rules from first phase]* ...

> 11.6.3.7 Output type inferences
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the spec has it as 12.6.3.7 now. Don't know whether there's a need for us to keep in sync.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The links here are to standard-v6 currently. We could update all to v7 in the future and update the section numbers at the same time.

>
> - **If `Eᵢ` is a *collection literal*, a *collection literal inference* is made *from* `Eᵢ` *to* the corresponding *parameter type* `Tᵢ`.**
> - ...
> An *output type inference* is made *from* an expression `E` *to* a type `T` in the following way:
>
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ᵢ`.
> - 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 an *output type inference* is made *from* each `Eᵢ` *to* `Tₑ`.
> - *[existing rules from output type inferences]* ...

## Extension methods
```c#
Expand Down