-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/vet: function with no-var receiver raises 'passes lock by value' #27001
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
Comments
This is working as expected. The error from vet is correct, the method receiver is always a copy of the value the method is called on because a method is just syntactic sugar for a function whose implicit first parameter is the receiver. In most cases, when the method is declared on a pointer type, the receiver is a copy of the pointer. However in this case the receiver is a value type
Makes a copy of |
TBH, if you have a |
That’s a fair observation but I vet isn’t going to optimise for this rare case. Just move your method to a pointer receiver and vet will be happy.
… On 15 Aug 2018, at 22:19, Tit Petric ***@***.***> wrote:
TBH, if you have a (S) or (_ S), any value of S is un-assignable and a copy isn't being made, or even produced in the final go assembly. Go asm for the case reports the same output code as func New() *S for both of these receiver methods.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Will you at least field a PR if I optimize for this rare case? If that's a non-starter, please feel free to close the issue :) |
I agree with Dave that this is technically correct, but in practice it does seem like a false positive. I'd personally be fine with a fix for this particular edge case, but it would need to cover all other cases, such as when a function receives On the other hand, this seems like such a niche example - I can't help but wonder if there's any real reason why one would want to do this, avoiding the pointer receiver. Let's leave this open for a bit, to see if others have any compelling arguments. |
The main reason is guaranteed immutability of the receiver. Even if I hide the function signature behind an interface and check that it's implemented as a value receiver, I can't really enforce that somebody may not declare It's not a high priority for me, but I thank you for your time so far, it gave me the opportunity to think about it more and how I would work around this issue. I'd still like to give a stab at fixing copylock at some point, if the discussion will move in that direction. Thank you all ;) |
I don’t think this should be fixed in vet. It is a bug in user code that vet has identified.
Copying the receiver, even in the extreme case of omitting a local name for the receiver is a potential data race — the atomic variable that sync uses is copied without using an atomic load — which pushes the program into the realm of undefined behaviour.
I think that this check should remain as is and its warning heeded.
… On 16 Aug 2018, at 05:59, Tit Petric ***@***.***> wrote:
The main reason is guaranteed immutability of the receiver. Even if I hide the function signature behind an interface and check that it's implemented as a value receiver, I can't really enforce that somebody may not declare func (s S) Something() S { at that point (thereby exposing himself to the issue that vet reports against). Obviously *S resolves the vet reported issue, but it throws immutability out of the window.
It's not a high priority for me, but I thank you for your time so far, it gave me the opportunity to think about it more and how I would work around this issue. I'd still like to give a stab at fixing copylock at some point, if the discussion will move in that direction. Thank you all ;)
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
I defer to your better judgement and I'm closing the issue. |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?1.10
Does this issue reproduce with the latest release?
Yes
What did you do?
What did you expect to see?
Nothing. The functions don't copy the receiver (not-assignable).
What did you see instead?
The text was updated successfully, but these errors were encountered: