-
Notifications
You must be signed in to change notification settings - Fork 18k
x/tools/gopls: rename reports spurious conflict between parameter and package-level decl ("unexpected var object") #61294
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
Based on the logic of renamer.check: // check performs safety checks of the renaming of the 'from' object to r.to.
func (r *renamer) check(from types.Object) {
if r.objsToUpdate[from] {
return
}
r.objsToUpdate[from] = true
// NB: order of conditions is important.
if from_, ok := from.(*types.PkgName); ok {
r.checkInFileBlock(from_)
} else if from_, ok := from.(*types.Label); ok {
r.checkLabel(from_)
} else if isPackageLevel(from) {
r.checkInPackageBlock(from)
} else if v, ok := from.(*types.Var); ok && v.IsField() {
r.checkStructField(v)
} else if f, ok := from.(*types.Func); ok && recv(f) != nil {
r.checkMethod(f)
} else if isLocal(from) {
r.checkInLexicalScope(from)
} else {
r.errorf(from.Pos(), "unexpected %s object %q (please report a bug)\n",
objectKind(from), from)
}
} and the fact that Decode is not a package name, label, package-level decl, field, or method, it must be that the isLocal function is spuriously returning false for this parameter var, likely somehow related to generics. But so far I have not been able to reproduce it in golang.org/x/tools/go/types/internal/play modified to report isLocal, trying minimizations such as: package main
import "fmt"
func New[T any](g func() (T, error)) {
g()
} |
I had the same problem. As soon as I take it out of context it stops being broken. I feel kind of stupid reporting by it 🙈 |
Ha! I now have a minimal reproduction of it package cmd
import "errors"
var Foo = errors.New("oops")
func Bar() {
}
const Baz = 42
func New(Foo int, Bar string, Baz float64) string {
return ""
} The problem seems to happen when the parameter is shadowing an exported token. Non of the parameters to That's also why it stoped to break once I took it out of its context, because it stopped shadowing the exported token called |
Well done for isolating this test case: I can reproduce it locally and will prepare a fix presently. |
Change https://go.dev/cl/509875 mentions this issue: |
The reason it was tricky is that the package must be imported for the bug to appear, even though the object is local to the function. The explanation is that, from the type-checker's perspective, function parameter vars are exported, as they may affect error messages emitted by the compiler in other packages, and this property of being exported causes rename to use a different algorithm. @findleyr We should bear in mind that being imported may be significant when trying to reproduce future rename bugs. |
I guess it doesn't happen that much because it's very unusual for function parameter vars to be uppercase. That's also how I encountered it, I saw the code and wanted to lowercase it. The Decode function was though quite far away from this in a completely different file. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Trying to run
rename
command on theDecode
parameter with gopls:I cannot reproduce it when I isolate that code so it seems it has something to do with the module in general. I cannot share it because it's a private code base.
What did you expect to see?
Being able to rename the parameter
What did you see instead?
An error by
gopls
:The text was updated successfully, but these errors were encountered: