-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Variable from using
cannot be used as ref
or out
#26313
Comments
@OmarTawfik Could you take a look? |
using
cannot be used as ref
or out
Confirmed this is by-design.
The rationale is that we'll need to dispose the resource, so we can't let you point the variable to something else (we would lose the resource that needs disposing). |
@jcouv Reopening the issue because the Expected behavior and Actual behavior statements remain correct. The specification language you found only impacts the Additional information section of what I wrote. |
@sharwell I'm sorry but the spec clearly mentions "or pass them as ref or out parameters" which would suggest that this is by design, so why is the expected behavior the one you're describing? Isn't this a language feature request as opposed to a compiler bug? |
Yes and I understand this limitation might be frustrating but it is still a language limitation and not a compiler issue, so it would seem more appropriate for csharplang. |
@Neme12 The resource variable is a value type. The behavior inconsistent with the current specification is the call If a deviation from the language of the specification is allowable in that instance, then it should also be allowable for the call to |
Yes I know that an instance method can still modify the struct and you have a valid point to say it's logically inconsistent, but unfortunately it's consistent with what the specification says:
There is no mention of instance methods being illegal but ref and out parameters are clearly forbidden. |
Where do you see a deviation from the specification? Yes |
@Neme12 You can see the impact that read-only has on by-ref call here: Notice that If you modify the sample to review a |
Yes I'm aware of the semantics of readonly fields & structs. |
When calling instance methods of value types, the resource variable is treated as not read-only and is passed by reference. The spec says a compilation error should occur (or rather, that a reference to a copy should be passed). The current implementation behavior does not align with the specification for this case. One thing working in favor of this issue is this may be a long-standing behavior of the compiler. In cases like this, the compiler has occasionally been left intentionally deviating from the specification. In addition, the current implementation fails to compile for the case where I've requested a change, so the change will not result in a silent change in behavior for any currently-valid code. The situtaion may allow the implementation to be modified for consistency while the language gets updated. |
@sharwell
See https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#member-access Note that this only applies to readonly fields, not readonly variables (such as a using or foreach statement variable). It looks to me like the behavior you're seeing in both cases is currently by design. |
It also seems to apply to readonly references but those are not in the spec so I won't comment on that. |
This same text states the behavior would be equivalent if https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#simple-names
|
Yes. In this example:
Hm, this wording is a little unfortunate. Maybe it is clarified elsewhere but I'm not going investigate. |
Version Used: 15.7 Preview 4
Steps to Reproduce:
Expected Behavior:
The calls to
Move()
andMove2()
are equivalent.Actual Behavior:
The call to
Move2()
results in the error described.Additional Information:
The call to
Move()
shows that invocations using a reference to a value used in ausing
statement are allowed in some contexts. In these contexts, CS1657 appears to be an arbitrary language limitation that could be removed. Allowing by-ref calls in this context would simplify the implementation of an allocation-freeOwnedDisposable<T>
, which I'm creating as part of an experimental way to address dotnet/roslyn-analyzers#1617. This limitation forces the code to usetry
/finally
instead of the equivalentusing
statement.The text was updated successfully, but these errors were encountered: