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

Tuple conversion are incorrectly specified #1155

Open
333fred opened this issue Aug 12, 2024 · 2 comments
Open

Tuple conversion are incorrectly specified #1155

333fred opened this issue Aug 12, 2024 · 2 comments

Comments

@333fred
Copy link
Member

333fred commented Aug 12, 2024

Describe the bug

The compiler implements both a tuple type conversion, and a tuple literal conversion from expression. The spec currently only covers that latter conversion. As a concrete example of a feature that explicitly designed for and allowed, but the spec says is illegal:

short s = 1;

(int, int) t1 = (s, s); // As said in the spec, this is a tuple expression conversion
(short, short) t2 = (s, s);
(int, int) t3 = t2; // By the spec, there shouldn't be a conversion here, but the compiler allows a tuple type conversion from (short, short) to (int, int)

Specifically, https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/conversions.md#10213-implicit-tuple-conversions is the only conversions portion of the specification that touches tuples, and it covers tuple expressions. These are defined by https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#1286-tuple-expressions. In t3 = t2, t2 is not a tuple expression, but is instead a simple name: https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#1284-simple-names; since we're not dealing tuple expressions, implicit tuple conversions don't apply, and the spec says that no conversion should exist from t2 to t3.

@Nigel-Ecma
Copy link
Contributor

Oops…

I suggest this error has crept in due to the melding of tuple construction and tuple conversion into a single operation – the implicit tuple conversion §10.2.13.

Possible fix:

  • In §12.8.6 Tuple expressions define a tuple value in terms of ValueTuple and not by referencing tuple conversion.
  • In §12.2.2 Values of expressions change the fourth bullet to reference §12.8.6 and not tuple conversion. Also while in this clause fix the issue that when the fourth bullet was added it wasn't included in the final sentence of the preceding paragraph which still only mentions three things.
  • §10.2.13 Implicit tuple conversions can then start “An implicit conversion exists from an expression E with a tuple type S to a tuple type T if S has the same arity as T and an implicit conversion exists from each element type in S to the corresponding element type in T.” The ValueTuple stuff then gets removed as it is now in §12.8.6.

A possible criticism of this approach is that it might define/imply (depending on wording) something like (var a, var b) = (42, 24); as creating a ValueTuple and then destroying it – but what if it does? Not doing so is a compiler optimisation surely? However if wished the Standard could make it clear that eliding temporary ValueTuples is valid, though I suspect eliding temporaries is always valid.

@333fred
Copy link
Member Author

333fred commented Aug 12, 2024

A possible criticism of this approach is that it might define/imply (depending on wording) something like (var a, var b) = (42, 24); as creating a ValueTuple and then destroying it – but what if it does?

FWIW, I've always viewed this operation as doing exactly that, and the compiler optimized to avoid creating the tuple. We use that exact wording when talking about expression-bodied constructors that do something like MyClass(int a, b) => (this.a, this.b) = (a, b);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants