dotnet / dotnet/csharpstandard
Discards and ref assignment
- Dominant language
- C#
- Stars
- 815
- Forks
- 99
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 16
Description
**Describe the bug**
Per draft C# 8.0 standard, the statement `int i = 0; _ = ref i;` is invalid, but Roslyn accepts it. Since the compiler is already out, the standard should be modified to allow ref assignment to discards.
**Example**
```csharp
int i = 0;
_ = ref i;
```
**Expected behavior**
The compiler should complain.
**Actual behavior**
The compiler doesn't complain.
**Additional context**
9.2.9.2 Discards:
> A ***discard*** is a local variable that has no name. A discard is introduced by a declaration expression (§12.19) with the identifier `_`; and is either implicitly typed (`_` or `var _`) or explicitly typed (`T _`).
This means that if `_ = ref i;` is acceptable, it is a declaration expression.
12.19 Declaration expressions:
> ... When used as a declaration expression, `_` is called a *simple discard*. It is semantically equivalent to `var _`, but is permitted in more places.
>
> A declaration expression shall only occur in the following syntactic contexts:
>
> - ...
> - As a simple discard `_` comprising the left side of a simple assignment (§12.23.2).
> - ...
Note "simple assignment".
12.23:
> ### 12.23.2 Simple assignment
> The `=` operator is called the simple assignment operator.
> ### 12.23.3 Ref assignment
> The `= ref` operator is known as the *ref assignment* operator.
This means ref assignment is not simple assignment (i.e., ref assignment is not "simple assignment to a variable reference variable", whatever the latter means).
(Memo to self: Once this issue is resolved, depending on how it's resolved, there might be another issue to file. For example, `object[] array = ...; _ = ref array[0];` currently compiles to `ldelem.ref` by Roslyn, instead of `ldelema`. This difference is important because the latter checks for variance.)
Contributor guide
Assessment
This issue has not been assessed yet.