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
Don't flag self–assignments with side effects #638
Don't flag self–assignments with side effects #638
Conversation
compute the fact using a more traditional definition of purity and adjust SA4017 accordingly the main change is that some stub functions (as defined by functions.IsStub) can be considered pure now
staticcheck/lint.go
Outdated
return false | ||
} | ||
if id, ok := call.Fun.(*ast.Ident); ok { | ||
if fn, ok := pass.TypesInfo.ObjectOf(id).(*types.Func); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a pure function taking an argument that is impure or has side effects? Recursively? Also what about methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch regarding pure functions taking impure arguments. Addressed in 1a9134f.
Can you clarify what you mean about methods? Currently we just conservatively assume that all method calls may have side effects and the purity fact for methods is always false.
So I was thinking about this recently and I realised that this PR confuses terminology quite a bit and does not do quite what it's meant to do. To elaborate, the original issue says that we shouldn't flag assignments where indexing has side effects. What I think we really want is to stop flagging cases where indexing is non–deterministic. // Pure and deterministic.
func foo(x int) int { return x + 42 }
// Impure but still deterministic.
func bar(x int) int {
println(x)
return x + 42
} I've built everything around the Thoughts? |
Purity is the correct attribute to check for, for two reasons:
On a side-note, your definition of "deterministic" is more restricted than the general definition. Something like a PRNG (math/rand) is also deterministic, it's just that its inputs include state other than function arguments, namely the values stored in struct fields. |
@ksurent I propose the following solution instead: https://github.com/dominikh/go-tools/compare/impure-self-assignment?expand=1 Of note: it correctly handles more complex and nested syntax, such as |
Merged as 9774f3b. |
Fix SA4018 to not flag self–assignments of the form
x[e] = x[e]
wheree
may have side effects (e.g. a function call we know isn't pure or a channel read).This also includes a change that unties the implementation of the purity fact from SA4017, making it available for reuse in SA4018 and potentially other checks in the future.