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/gopls: crashes when instantiating generic function types with multiple parameters #47943

Closed
lu4p opened this issue Aug 24, 2021 · 3 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@lu4p
Copy link

lu4p commented Aug 24, 2021

gopls version: v0.7.1
gopls flags: 
update flags: proxy
extension version: 0.27.1
go version: devel go1.18-8eeb1bff1d
environment: Visual Studio Code linux
initialization error: undefined
manual restart count: 0
total start count: 1

What did you do?

I tried to implement a simple reduce function similar to https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce with the current generics implementation.

This works fine with gopls:

func Reduce[Elem, Res any](s []Elem, fn func(accumulator Res, currentValue Elem) Res) Res {
	var accumulator Res
	for _, el := range s {
		accumulator = fn(accumulator, el)
	}

	return accumulator
}

However when trying to extract the type for the reduce function (for better readability) gopls crashes while instantiating the reduce function with multiple parameters.

Pre crash:

type Reducer[Elem, Res any] func(accumulator Res, currentValue Elem) Res

func Reduce[Elem, Res any](s []Elem, fn Reducer[Elem]) Res {
	var accumulator Res
	for _, el := range s {
		accumulator = fn(accumulator, el)
	}

	return accumulator
}

When trying to instantiate another type parameter in the reducer (note the trailing comma), gopls crashes instantly, restarting gopls doesn't help.

...
func Reduce[Elem, Res any](s []Elem, fn Reducer[Elem,]) Res {
...

The final code doesn't crash gopls:

...

func Reduce[Elem, Res any](s []Elem, fn Reducer[Elem, Res]) Res {
...

gopls crash logs

panic: assertion failed

goroutine 433 [running]:
go/types.(*Checker).handleBailout(0xc000740a00, 0xc001297690)
	  check.go:244  0x8b
panic({0xc0cca0, 0xe6da40})
	  panic.go:814  0x214
go/types.assert(...)
	  errors.go:20
go/types.(*subster).typ(0xc0012958d8, {0xe841d8, 0xc0003f6750})
	  subst.go:194  0x18bb
go/types.(*subster).var_(0xc0016329c0, 0xc000db0050)
	  subst.go:305  0x32
go/types.(*subster).varList(0xeabb38, {0xc001156a20, 0x2, 0xc000740a00})
	  subst.go:326  0x90
go/types.(*subster).tuple(0x1390360, 0xc00115a930)
	  subst.go:316  0x35
go/types.(*subster).typ(0xc0012958d8, {0xe842a0, 0xc00115a930})
	  subst.go:123  0xbd1
go/types.(*Checker).subst(0xc0011569c0, 0x2, {0xe842a0, 0xc00115a930}, 0x1, 0xc001295950)
	  subst.go:80  0x114
go/types.(*Checker).infer(0xc000740a00, {0xe71800, 0xc000124d40}, {0xc0011569c0, 0x2, 0xc003471980}, {0x0, 0xc000a9e040, 0x0}, 0xc00115a930, ...)
	  infer.go:89  0x20e
go/types.(*Checker).arguments(0xc000740a00, 0xc000124d40, 0xc001167ac0, {0x0, 0xc000740a00, 0x404429}, {0xc0011ffec0, 0x2, 0xce36c0})
	  call.go:329  0x4f0
go/types.(*Checker).callExpr(0xc000740a00, 0xc003471900, 0xc000124d40)
	  call.go:175  0x845
go/types.(*Checker).exprInternal(0xc000740a00, 0xc003471900, {0xe86200, 0xc000124d40}, {0x0, 0x0})
	  expr.go:1408  0x945
go/types.(*Checker).rawExpr(0xc003471900, 0x0, {0xe86200, 0xc000124d40}, {0x0, 0x0})
	  expr.go:1075  0x3a
go/types.(*Checker).multiExpr(0xd0, 0xc0012965b0, {0xe86200, 0xc000124d40})
	  expr.go:1538  0x32
go/types.(*Checker).exprList(0xc00346fc20, {0xc0003df420, 0x0, 0xc003469450}, 0x0)
	  call.go:213  0x97
go/types.(*Checker).initVars(0xc3c940, {0xc00341a838, 0x1, 0x0}, {0xc0003df420, 0xc000740a01, 0x18c8f7c29a92ae72}, 0x0)
	  assignments.go:235  0x7b
go/types.(*Checker).shortVarDecl(0xc000740a00, {0xe730a0, 0xc002f7e240}, {0xc0003df400, 0x1, 0x0}, {0xc0003df420, 0xc00129e978, 0x1})
	  assignments.go:367  0x9c5
go/types.(*Checker).stmt(0xc000740a00, 0x0, {0xe86080, 0xc000124d80})
	  stmt.go:429  0x1687
go/types.(*Checker).stmtList(0x0, 0x0, {0xc000124dc0, 0x0, 0x0})
	  stmt.go:130  0xc9
go/types.(*Checker).funcBody(0xc000740a00, 0xc00346ca80, {0x0, 0xc3ebc0}, 0xc003470200, 0xc0005f5560, {0x0, 0x0})
	  stmt.go:46  0x259
go/types.(*Checker).funcDecl.func1()
	  decl.go:786  0x45
go/types.(*Checker).processDelayed(0xc000740a00, 0x0)
	  check.go:298  0x35
go/types.(*Checker).checkFiles(0xc000740a00, {0xc000512318, 0xc000f729b0, 0x2})
	  check.go:266  0xcb
go/types.(*Checker).Files(...)
	  check.go:249
golang.org/x/tools/internal/lsp/cache.doTypeCheck({0xe890d8, 0xc000f93b40}, 0xc000137e00, 0xc0000f0780, 0x2, 0xc000b5ed80, 0xe86cb0)
	  check.go:544  0x893
golang.org/x/tools/internal/lsp/cache.typeCheck({0xe890d8, 0xc000f93b40}, 0xc000137e00, 0xc0000f0780, 0x2, 0xc000b5ed80)
	  check.go:321  0xe5
golang.org/x/tools/internal/lsp/cache.(*snapshot).buildPackageHandle.func1({0xe890d8, 0xc000f93b40}, {0xe72060, 0xc000137e00})
	  check.go:124  0x23e
golang.org/x/tools/internal/memoize.(*Handle).run.func1()
	  memoize.go:322  0xa9
created by golang.org/x/tools/internal/memoize.(*Handle).run
	  memoize.go:315  0x1c5
[Error - 8:07:47 PM] 
@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Aug 24, 2021
@gopherbot gopherbot added this to the Unreleased milestone Aug 24, 2021
@hyangah
Copy link
Contributor

hyangah commented Aug 25, 2021

Thanks for the report @lu4p. Can you reproduce the issue if you build gopls following the instruction here?
https://github.com/golang/tools/blob/master/gopls/doc/advanced.md#working-with-generic-code
(since dev.typeparams branch was merged to the main branch, you won't need to use dev.typeparams branch, but sill need -tags=typeparams)

cc @findleyr

@hyangah hyangah modified the milestones: Unreleased, gopls/unplanned Aug 27, 2021
@hyangah hyangah added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Aug 27, 2021
@findleyr
Copy link
Contributor

Apologies for missing this.

Unfortunately I am unable to reproduce, either at tip or at that exact go commit, or even an older commit (I tried both with a go/types test and a gopls session, in case gopls' AST mangling had something to do with it). I just get the expected error from go/types: "got 1 argument but 2 type parameters".

Is there any additional information you can share? Are you sure you had built gopls at that exact Go commit, or is it possible you had built gopls earlier?

Otherwise, I'll see if I can reverse engineer a repro from the stack trace.

CC @griesemer

@lu4p
Copy link
Author

lu4p commented Sep 13, 2021

I can confirm that this works with the lastest gotip + gopls

@lu4p lu4p closed this as completed Sep 13, 2021
@golang golang locked and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

5 participants