Skip to content

Commit 0e67298

Browse files
BillWagnerjskeet
authored andcommitted
Type inference for tuple elements
Fixes #1244 I followed the recommended text from [collection expressions](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/collection-expressions.md#type-inference) because we well need them in the future. I did break apart the first phase and the input type inference because tuple elements now needs subscripts as well. We could put them together, but the small `i` and `j` start to look the same.
1 parent c4be155 commit 0e67298

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

standard/expressions.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -763,14 +763,7 @@ Type inference takes place in phases. Each phase will try to infer type argument
763763
764764
#### 12.6.3.2 The first phase
765765
766-
For each of the method arguments `Eᵢ`:
767-
768-
- If `Eᵢ` is an anonymous function, an *explicit parameter type inference* ([§12.6.3.8](expressions.md#12638-explicit-parameter-type-inferences)) is made *from* `Eᵢ` *to* `Tᵢ`
769-
- Otherwise, if `Eᵢ` has a type `U` and the corresponding parameter is a value parameter ([§15.6.2.2](classes.md#15622-value-parameters)) then a *lower-bound inference* ([§12.6.3.10](expressions.md#126310-lower-bound-inferences)) is made *from* `U` *to* `Tᵢ`.
770-
- Otherwise, if `Eᵢ` has a type `U` and the corresponding parameter is a reference parameter ([§15.6.2.3.3](classes.md#156233-reference-parameters)), or output parameter ([§15.6.2.3.4](classes.md#156234-output-parameters)) then an *exact inference* ([§12.6.3.9](expressions.md#12639-exact-inferences)) is made *from* `U` *to* `Tᵢ`.
771-
- Otherwise, if `Eᵢ` has a type `U` and the corresponding parameter is an input parameter ([§15.6.2.3.2](classes.md#156232-input-parameters)) and `Eᵢ` is an input argument, then an *exact inference* ([§12.6.3.9](expressions.md#12639-exact-inferences)) is made *from* `U` *to* `Tᵢ`.
772-
- Otherwise, if `Eᵢ` has a type `U` and the corresponding parameter is an input parameter ([§15.6.2.3.2](classes.md#156232-input-parameters)) then a *lower bound inference* ([§12.6.3.10](expressions.md#126310-lower-bound-inferences)) is made *from* `U` *to* `Tᵢ`.
773-
- Otherwise, no inference is made for this argument.
766+
For each of the method arguments `Eᵢ`, an input type inference is made from `Eᵢ` to the corresponding parameter type `Tᵢ`.
774767
775768
#### 12.6.3.3 The second phase
776769
@@ -798,10 +791,23 @@ An *unfixed* type variable `Xᵢ` *depends directly on* an *unfixed* type varia
798791
799792
`Xₑ` *depends on* `Xᵢ` if `Xₑ` *depends directly on* `Xᵢ` or if `Xᵢ` *depends directly on* `Xᵥ` and `Xᵥ` *depends on* `Xₑ`. Thus “*depends on*” is the transitive but not reflexive closure of “*depends directly on*”.
800793
794+
#### §input-type-inference Input type inferences
795+
796+
An *input type inference* is made *from* an expression `E` *to* a type `T` in the following way:
797+
798+
- If `E` is a tuple expression12.8.6) with arity `N` and elements `Eᵢ`, and `T` is a tuple type with arity `N` with a corresponding element type `Tₑ` or `T` is a nullable value type `T0?` and `T0` is a tuple type with arity `N` that has a corresponding element type `Tₑ`, then for each `Eᵢ`, an input type inference is made from `Eᵢ` to `Tₑ`.
799+
- If `E` is an anonymous function, an *explicit parameter type inference* ([§12.6.3.8](expressions.md#12638-explicit-parameter-type-inferences)) is made *from* `E` *to* `T`
800+
- Otherwise, if `E` has a type `U` and the corresponding parameter is a value parameter ([§15.6.2.2](classes.md#15622-value-parameters)) then a *lower-bound inference* ([§12.6.3.10](expressions.md#126310-lower-bound-inferences)) is made *from* `U` *to* `T`.
801+
- Otherwise, if `E` has a type `U` and the corresponding parameter is a reference parameter ([§15.6.2.3.3](classes.md#156233-reference-parameters)), or output parameter ([§15.6.2.3.4](classes.md#156234-output-parameters)) then an *exact inference* ([§12.6.3.9](expressions.md#12639-exact-inferences)) is made *from* `U` *to* `T`.
802+
- Otherwise, if `E` has a type `U` and the corresponding parameter is an input parameter ([§15.6.2.3.2](classes.md#156232-input-parameters)) and `E` is an input argument, then an *exact inference* ([§12.6.3.9](expressions.md#12639-exact-inferences)) is made *from* `U` *to* `T`.
803+
- Otherwise, if `E` has a type `U` and the corresponding parameter is an input parameter ([§15.6.2.3.2](classes.md#156232-input-parameters)) then a *lower bound inference* ([§12.6.3.10](expressions.md#126310-lower-bound-inferences)) is made *from* `U` *to* `T`.
804+
- Otherwise, no inference is made for this argument.
805+
801806
#### 12.6.3.7 Output type inferences
802807
803-
An *output type inference* is made *from* an expression `E` *to* a type T in the following way:
808+
An *output type inference* is made *from* an expression `E` *to* a type `T` in the following way:
804809
810+
- If `E` is a tuple expression with arity `N` and elements `Eᵢ`, and `T` is a tuple type with arity `N` a corresponding element type `Tₑ` or `T` is a nullable value type `T0?` and `T0` is a tuple type with arity `N` that has a corresponding element type `Tₑ`, then for each `Eᵢ` an output type inference is made from `Eᵢ` to `Tₑ`.
805811
- If `E` is an anonymous function with inferred return type `U` ([§12.6.3.13](expressions.md#126313-inferred-return-type)) and `Tis a delegate type or expression tree type with return type `Tₓ`, then a *lower-bound inference* ([§12.6.3.10](expressions.md#126310-lower-bound-inferences)) is made *from* `U` *to* `Tₓ`.
806812
- Otherwise, if `E` is a method group and `T` is a delegate type or expression tree type with parameter types `T₁...Tᵥ` and return type `Tₓ`, and overload resolution of `E` with the types `T...Tᵥ` yields a single method with return type `U`, then a *lower-bound inference* is made *from* `U` *to* `Tₓ`.
807813
- Otherwise, if `E` is an expression with type `U`, then a *lower-bound inference* is made *from* `U` *to* `T`.

0 commit comments

Comments
 (0)