Skip to content
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

x/tools/go/ssa: ent.withHooks$1: cannot convert *t0 (M) to PM #58633

Closed
Antonboom opened this issue Feb 22, 2023 · 13 comments
Closed

x/tools/go/ssa: ent.withHooks$1: cannot convert *t0 (M) to PM #58633

Antonboom opened this issue Feb 22, 2023 · 13 comments
Assignees
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@Antonboom
Copy link

Antonboom commented Feb 22, 2023

What version of Go are you using (go version)?

$ go version
go version go1.20.1 darwin/arm64

Does this issue reproduce with the latest release?

Yes, and it's actual for x/tools master too.

What did you do?

Demo: https://github.com/Antonboom/golangci-vs-ent-generics

$ golangci-lint version    
golangci-lint has version 1.51.2 built from 3e8facb4 on 2023-02-19T21:43:54Z

$ golangci-lint run ./...

What did you expect to see?

No panics.

What did you see instead?

ERRO Running error: 1 error occurred:
        * can't run linter goanalysis_metalinter: goanalysis_metalinter: buildssa:
        package "ent" (isInitialPkg: true, needAnalyzeSource: true): in
        github.com/Antonboom/golangci-vs-ent-generics/ent.withHooks$1:
        cannot convert *t0 (M) to PM
Full stack trace
ERRO [runner] Panic: buildssa: package "ent" (isInitialPkg: true, needAnalyzeSource: true): in github.com/Antonboom/golangci-vs-ent-generics/ent.withHooks$1: cannot convert *t0 (M) to PM: goroutine 4179 [running]:
runtime/debug.Stack()
        /usr/local/go/src/runtime/debug/stack.go:24 +0x64
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func1()
        /Users/anthony/golangci-lint/pkg/golinters/goanalysis/runner_action.go:102 +0x108
panic({0x101d904a0, 0x140058f16a0})
        /usr/local/go/src/runtime/panic.go:884 +0x1f4
golang.org/x/tools/go/ssa.emitConv(0x140058a9080, {0x101f72740, 0x140058f6d80}, {0x101f69d48?, 0x140033fb290})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/emit.go:286 +0xb40
golang.org/x/tools/go/ssa.emitStore(0x140058a9080, {0x101f72740, 0x140058f6cc0}, {0x101f72740, 0x140058f6d80}, 0x2aa377f)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/emit.go:377 +0x58
golang.org/x/tools/go/ssa.(*address).store(0x140058fa0f0, 0x140058a9080?, {0x101f72740?, 0x140058f6d80?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/lvalue.go:40 +0x4c
golang.org/x/tools/go/ssa.(*storebuf).emit(...)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:533
golang.org/x/tools/go/ssa.(*builder).assignStmt(0x140058a9080?, 0x140058a9080, {0x140035bc870, 0x1, 0x101f06d60?}, {0x140035bc890, 0x1, 0x100fd9900?}, 0x0)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:1207 +0x370
golang.org/x/tools/go/ssa.(*builder).stmt(0x14003852838?, 0x140058a9080, {0x101f6cbd0?, 0x14002ec1a40?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2181 +0x380
golang.org/x/tools/go/ssa.(*builder).stmtList(0x140058e9ec0?, 0x14000a67520?, {0x14002ec1a80?, 0x4, 0x140058e9ec0?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:946 +0x48
golang.org/x/tools/go/ssa.(*builder).stmt(0x140058a9080?, 0x140058a9080, {0x101f6ccf0?, 0x1400347c0c0?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2277 +0x718
golang.org/x/tools/go/ssa.(*builder).buildFunctionBody(0x0?, 0x140058a9080)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2391 +0x354
golang.org/x/tools/go/ssa.(*builder).expr0(0x140038539f8, 0x1400300de00, {0x101f6cf90?, 0x140035bc900?}, {0x7, {0x101f69c58, 0x14003340740}, {0x0, 0x0}})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:656 +0x42c
golang.org/x/tools/go/ssa.(*builder).expr(0x101dfec00?, 0x1400300de00, {0x101f6cf90, 0x140035bc900})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:625 +0x11c
golang.org/x/tools/go/ssa.(*builder).expr0(0x140038539f8, 0x1400300de00, {0x101f6cd50?, 0x14002ec1b00?}, {0x7, {0x101f69bb8, 0x14002587260}, {0x0, 0x0}})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:676 +0x5f8
golang.org/x/tools/go/ssa.(*builder).expr(0x101ef8e60?, 0x1400300de00, {0x101f6cd50, 0x14002ec1b00})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:625 +0x11c
golang.org/x/tools/go/ssa.(*builder).assign(0x1400300de00?, 0x1400300de00?, {0x101f6f668?, 0x140058e9e30}, {0x101f6cd50?, 0x14002ec1b00?}, 0x0?, 0x0)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:598 +0x30c
golang.org/x/tools/go/ssa.(*builder).localValueSpec(0x1400300de00?, 0x1400300de00, 0x14002c46190)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:1147 +0xb8
golang.org/x/tools/go/ssa.(*builder).stmt(0x14003853548?, 0x1400300de00, {0x101f6ce40?, 0x140035bc950?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2147 +0x14b0
golang.org/x/tools/go/ssa.(*builder).stmtList(0x140038535c8?, 0x101014e70?, {0x14000a6c100?, 0x8, 0x10?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:946 +0x48
golang.org/x/tools/go/ssa.(*builder).stmt(0x1400300de00?, 0x1400300de00, {0x101f6ccf0?, 0x1400347c3f0?})
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2277 +0x718
golang.org/x/tools/go/ssa.(*builder).buildFunctionBody(0x14002fe3500?, 0x1400300de00)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2391 +0x354
golang.org/x/tools/go/ssa.(*builder).buildFunction(0x101503cc0?, 0x1400300de00)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2326 +0x30
golang.org/x/tools/go/ssa.(*builder).buildCreated(0x140038539f8)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2413 +0x28
golang.org/x/tools/go/ssa.(*Package).build(0x14002726900)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2606 +0xa60
sync.(*Once).doSlow(0x140003c6480?, 0x14003c59ae0?)
        /usr/local/go/src/sync/once.go:74 +0x100
sync.(*Once).Do(...)
        /usr/local/go/src/sync/once.go:65
golang.org/x/tools/go/ssa.(*Package).Build(...)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/ssa/builder.go:2477
golang.org/x/tools/go/analysis/passes/buildssa.run(0x1400362c1e0)
        /Users/anthony/golang_workspace/pkg/mod/golang.org/x/tools@v0.6.0/go/analysis/passes/buildssa/buildssa.go:72 +0x13c
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyze(0x140015f2310)
        /Users/anthony/golangci-lint/pkg/golinters/goanalysis/runner_action.go:188 +0x94c
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func2()
        /Users/anthony/golangci-lint/pkg/golinters/goanalysis/runner_action.go:106 +0x20
github.com/golangci/golangci-lint/pkg/timeutils.(*Stopwatch).TrackStage(0x140006e6050, {0x101a7e2c1, 0x8}, 0x14001138f30)
        /Users/anthony/golangci-lint/pkg/timeutils/stopwatch.go:111 +0x44
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe(0x14000580d00?)
        /Users/anthony/golangci-lint/pkg/golinters/goanalysis/runner_action.go:105 +0x74
github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze.func2(0x140015f2310)
        /Users/anthony/golangci-lint/pkg/golinters/goanalysis/runner_loadingpackage.go:80 +0xb0
created by github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze
        /Users/anthony/golangci-lint/pkg/golinters/goanalysis/runner_loadingpackage.go:75 +0x17c 
WARN [runner] Can't run linter goanalysis_metalinter: goanalysis_metalinter: buildssa: package "ent" (isInitialPkg: true, needAnalyzeSource: true): in github.com/Antonboom/golangci-vs-ent-generics/ent.withHooks$1: cannot convert *t0 (M) to PM 
WARN [linters_context] rowserrcheck is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649. 
WARN [linters_context] wastedassign is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649. 
INFO [runner] processing took 2.622µs with stages: max_same_issues: 500ns, skip_dirs: 292ns, nolint: 250ns, source_code: 208ns, exclude-rules: 167ns, sort_results: 125ns, filename_unadjuster: 125ns, max_from_linter: 125ns, cgo: 125ns, path_prettifier: 84ns, path_shortener: 84ns, skip_files: 83ns, identifier_marker: 83ns, max_per_file_from_linter: 83ns, diff: 83ns, uniq_by_line: 41ns, severity-rules: 41ns, path_prefixer: 41ns, exclude: 41ns, autogenerated_exclude: 41ns 
INFO [runner] linters took 1.620278917s with stages: goanalysis_metalinter: 1.620215167s, rowserrcheck: 13.75µs, wastedassign: 6.792µs 
ERRO Running error: 1 error occurred:
        * can't run linter goanalysis_metalinter: goanalysis_metalinter: buildssa: package "ent" (isInitialPkg: true, needAnalyzeSource: true): in github.com/Antonboom/golangci-vs-ent-generics/ent.withHooks$1: cannot convert *t0 (M) to PM

Additional info

  1. Related to bodyclose: panic "interface conversion: interface {} is nil, not *buildssa.SSA" golangci/golangci-lint#3086

  2. Suggested problematic code:

func withHooks[V Value, M any, PM interface {
	*M
	Mutation
}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) {
    /* ... */
}
@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label Feb 22, 2023
@gopherbot gopherbot added this to the Unreleased milestone Feb 22, 2023
@thanm
Copy link
Contributor

thanm commented Feb 22, 2023

@golang/tools-team

@thanm thanm added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Feb 22, 2023
@ravive-neosec
Copy link

any workaround ?

@adonovan
Copy link
Member

adonovan commented Mar 1, 2023

You could make the following change to the analyzed code in golangci-vs-ent-generics/ent/ent.go:

	var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
		mutationT, ok := any(m).(PM) // redundant any() conversion is a workaround for golang/go#58633
		if !ok {
			return nil, fmt.Errorf("unexpected mutation type %T", m)
		}
		// Set the mutation to the builder.
		*mutation = *mutationT
		return exec(ctx)
	})

@Antonboom

This comment was marked as outdated.

@adonovan
Copy link
Member

adonovan commented Mar 1, 2023

Ah, you also need to have run "go get golang.org/x/tools@master" in the golangci-lint module and rebuilt the tool, since that picks up a fix that allows the workaround to work. (I had done that step, which was not sufficient by itself, and then forgotten that it enabled the workaround.)

I admit it is inconvenient that both the tool and the analyzed code must be adjusted, but it is a workaround.

@Antonboom

This comment was marked as off-topic.

@adonovan
Copy link
Member

adonovan commented Mar 2, 2023

When can we expect the next release of x/tools (tag)?
I see you do this every first week of the month, right?

Yes, recently it has become an automated monthly process.

@jufemaiz
Copy link
Contributor

jufemaiz commented Mar 3, 2023

Yes, recently it has become an automated monthly process.

QQ » does that make it March or April? (Organising tasks)

@Antonboom
Copy link
Author

Related to #57272

@Antonboom
Copy link
Author

Antonboom commented Mar 19, 2023

@adonovan, hello!

I cannot explain why 🤦 , but when I tested locally your workaround (several times) it worked. But in official build it doesn't work for some reason.

I wrote a test based on example above and it really doesn't pass on the x/tools master

TestGenericBodies (sorry, I tried simpler variants but they passed)
// go/ssa/builder_generic_test.go
// ...
{
        pkg: "k",
        contents: `
        package k

        type Value any

        type Mutation interface { Type() string }
        type Mutator interface { Mutate(Mutation) (Value, error)}
        type Hook func(Mutator) Mutator

        type MutateFunc func(Mutation) (Value, error)
        func (f MutateFunc) Mutate(m Mutation) (Value, error) { return f(m) }

        func withHooks[V Value, M any, PM interface {
                *M
                Mutation
        }](exec func() (V, error), mutation PM, hooks []Hook) (value V, err error) {
                var mut Mutator = MutateFunc(func(m Mutation) (Value, error) {
                        m1 := *(m.(PM))
                        m2 := *(any(m).(PM))
                        
                        print(m1)  /*@ types(M)*/
                        print(m2)  /*@ types(M)*/

                        *mutation, *mutation = m1, m2
                        return exec()
                })

                for i := len(hooks) - 1; i >= 0; i-- {
                        mut = hooks[i](mut)
                }

                v, _ := mut.Mutate(mutation)
                nv, _ := v.(V)
                return nv, nil
        }
        `,
},
=== RUN   TestGenericBodies/k
--- FAIL: TestGenericBodies (0.00s)
    --- FAIL: TestGenericBodies/k (0.00s)
panic: in k.withHooks$1: cannot convert *t0 (M) to PM [recovered]
	panic: in k.withHooks$1: cannot convert *t0 (M) to PM

I do not exclude that I am doing something wrong, or my local environment has generated some side effects.

I will try to find the cause of the panic, or I hope the test above will help Golang team do this.
Thanks!

@gopherbot
Copy link

Change https://go.dev/cl/477635 mentions this issue: go/ssa: deref core type in emitStore

@mgabeler-lee-6rs
Copy link

This is now affecting govulncheck (x/vuln) as well, as of v0.1.0, despite it using a recent x/tools commit from master.

I attempted to bisect what commit introduced the problem there, and came up with golang/vuln@4fb01e0, but the nature of that commit makes me suspicious of my testing.

@gopherbot
Copy link

Change https://go.dev/cl/492598 mentions this issue: go/ssa: use core type in address

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

8 participants