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

cmd/compile: internal compiler error using type parameters #48016

Closed
dsnet opened this issue Aug 27, 2021 · 10 comments
Closed

cmd/compile: internal compiler error using type parameters #48016

dsnet opened this issue Aug 27, 2021 · 10 comments
Assignees
Milestone

Comments

@dsnet
Copy link
Member

@dsnet dsnet commented Aug 27, 2021

Using go version devel go1.18-2c60a99f72 Fri Aug 27 05:13:44 2021 +0000 linux/amd64

When trying to compile some generic code, I get:

./arshal_funcs_generic.go:18:44: internal compiler error: found illegal assignment .shape.string -> json.T₁; 

goroutine 1 [running]:
runtime/debug.Stack()
	/usr/local/go.tip/src/runtime/debug/stack.go:24 +0x65
cmd/compile/internal/base.FatalfAt({0x0, 0x0}, {0xd0b468, 0x27}, {0xc0008cdb60, 0x3, 0x3})
	/usr/local/go.tip/src/cmd/compile/internal/base/print.go:227 +0x154
cmd/compile/internal/base.Fatalf(...)
	/usr/local/go.tip/src/cmd/compile/internal/base/print.go:196
cmd/compile/internal/noder.assignconvfn({0xe64da8, 0xc000ef2960}, 0xc000d01260)
	/usr/local/go.tip/src/cmd/compile/internal/noder/transform.go:413 +0x167
cmd/compile/internal/noder.typecheckaste(0x90, {0xc000ef6990, 0xc000ef6990}, 0x0, 0xc000ef2960, {0xc000ef4540, 0x1, 0x5b46f2}, 0x0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/transform.go:465 +0x186
cmd/compile/internal/noder.transformCall(0xc000ef6990)
	/usr/local/go.tip/src/cmd/compile/internal/noder/transform.go:160 +0x199
cmd/compile/internal/noder.(*subster).node.func1({0xe645d8, 0xc000917050})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1045 +0xebd
cmd/compile/internal/ir.editNodes({0xc000ef4530, 0x1, 0xccfd80}, 0xc000efe9a8)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1521 +0x74
cmd/compile/internal/ir.(*AssignListStmt).editChildren(0xc000ef26c0, 0xe64060)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:108 +0x6e
cmd/compile/internal/ir.EditChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:185
cmd/compile/internal/noder.(*subster).node.func1({0xe64060, 0xc00076efc0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:903 +0x423
cmd/compile/internal/noder.(*subster).node(0xc000e97600, {0xe64060, 0xc00076efc0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1208 +0xa5
cmd/compile/internal/noder.(*subster).namelist(0xc000efd2c0, {0xc00087bc00, 0x7, 0xc0008ce2a0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1284 +0xb7
cmd/compile/internal/noder.(*subster).node.func1({0xe64830, 0xc000951f40})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1082 +0x1173
cmd/compile/internal/ir.(*ConvExpr).editChildren(0xc000efd220, 0xc000efe990)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:445 +0x58
cmd/compile/internal/ir.EditChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:185
cmd/compile/internal/noder.(*subster).node.func1({0xe64b50, 0xc00095b180})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:903 +0x423
cmd/compile/internal/ir.(*StructKeyExpr).editChildren(0xc000efd1d0, 0xc000efe990)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1272 +0x58
cmd/compile/internal/ir.EditChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:185
cmd/compile/internal/noder.(*subster).node.func1({0xe66770, 0xc00095b130})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:903 +0x423
cmd/compile/internal/ir.editNodes({0xc000eee7c0, 0x2, 0x6234ef}, 0xc000efe990)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1521 +0x74
cmd/compile/internal/ir.(*CompLitExpr).editChildren(0xc000e97680, 0xc000efe990)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:405 +0xc9
cmd/compile/internal/ir.EditChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:185
cmd/compile/internal/noder.(*subster).node.func1({0xe649c0, 0xc0008c1380})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:903 +0x423
cmd/compile/internal/ir.editNodes({0xc000ef4500, 0x1, 0xcd1880}, 0xc000efe990)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1521 +0x74
cmd/compile/internal/ir.(*ReturnStmt).editChildren(0xc000efd130, 0xe66130)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1056 +0x53
cmd/compile/internal/ir.EditChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:185
cmd/compile/internal/noder.(*subster).node.func1({0xe66130, 0xc00095b1d0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:903 +0x423
cmd/compile/internal/noder.(*subster).node(0xc000e97600, {0xe66130, 0xc00095b1d0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1208 +0xa5
cmd/compile/internal/noder.(*subster).list(0xc000d05fe0, {0xc00094dda0, 0x2, 0xc0000bc5f0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:1296 +0x8e
cmd/compile/internal/noder.(*irgen).genericSubst(0xc00042a600, 0xc000efcb40, 0xc000cfed00, {0xc000d05f70, 0x1, 0x1}, 0x0, 0xc0007697c0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:722 +0xcc6
cmd/compile/internal/noder.(*irgen).getInstantiation(0xc00042a600, 0xc000cfed00, {0xc000d05f68, 0x1, 0x1}, 0x80)
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:608 +0x33d
cmd/compile/internal/noder.(*irgen).stencil.func1({0xe645d8, 0xc0009173b0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:109 +0x2df
cmd/compile/internal/ir.Visit.func1({0xe645d8, 0xc0009173b0})
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:105 +0x30
cmd/compile/internal/ir.(*ConvExpr).doChildren(0xc00095b770, 0xc000efe798)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:437 +0x62
cmd/compile/internal/ir.DoChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:94
cmd/compile/internal/ir.Visit.func1({0xe64b50, 0xc00095b770})
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:106 +0x57
cmd/compile/internal/ir.doNodes({0xc0004b70b0, 0x1, 0xc000d022c0}, 0xc000efe798)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1512 +0x67
cmd/compile/internal/ir.(*CallExpr).doChildren(0xc000917440, 0xc000efe798)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:263 +0x85
cmd/compile/internal/ir.DoChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:94
cmd/compile/internal/ir.Visit.func1({0xe645d8, 0xc000917440})
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:106 +0x57
cmd/compile/internal/ir.doNodes({0xc0004b7310, 0x1, 0x0}, 0xc000efe798)
	/usr/local/go.tip/src/cmd/compile/internal/ir/node_gen.go:1512 +0x67
cmd/compile/internal/ir.(*Func).doChildren(0xe64f38, 0xc000d022c0)
	/usr/local/go.tip/src/cmd/compile/internal/ir/func.go:152 +0x2e
cmd/compile/internal/ir.DoChildren(...)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:94
cmd/compile/internal/ir.Visit.func1({0xe64f38, 0xc000d022c0})
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:106 +0x57
cmd/compile/internal/ir.Visit({0xe64f38, 0xc000d022c0}, 0xc000769780)
	/usr/local/go.tip/src/cmd/compile/internal/ir/visit.go:108 +0xb8
cmd/compile/internal/noder.(*irgen).stencil(0xc00042a600)
	/usr/local/go.tip/src/cmd/compile/internal/noder/stencil.go:91 +0x26a
cmd/compile/internal/noder.(*irgen).generate(0xc00042a600, {0xc0000b7a40, 0xc, 0x0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/irgen.go:294 +0x2d8
cmd/compile/internal/noder.check2({0xc0000b7a40, 0xc, 0xc})
	/usr/local/go.tip/src/cmd/compile/internal/noder/irgen.go:92 +0x177
cmd/compile/internal/noder.LoadPackage({0xc000082aa0, 0xc, 0x0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/noder.go:90 +0x335
cmd/compile/internal/gc.Main(0xd1e6d0)
	/usr/local/go.tip/src/cmd/compile/internal/gc/main.go:190 +0xaf3
main.main()
	/usr/local/go.tip/src/cmd/compile/main.go:55 +0xdd

Reproduction:

$ git clone https://github.com/go-json-experiment/json.git
$ cd json
$ git checkout origin/generics-bug
$ go build

\cc @mdempsky @ianlancetaylor @griesemer

@ALTree
Copy link
Member

@ALTree ALTree commented Aug 27, 2021

If you have closure variables in a range statement, this may be #47676.

Loading

@ALTree ALTree added this to the Go1.18 milestone Aug 27, 2021
@dsnet
Copy link
Member Author

@dsnet dsnet commented Aug 27, 2021

The relevant generic code is:

func MarshalFuncV1[T any](fn func(T) ([]byte, error)) typedMarshaler {
	t := reflect.TypeOf((*T)(nil)).Elem()
	return typedMarshaler{
		typ: t,
		fnc: func(mo MarshalOptions, enc *Encoder, va addressableValue) error {
			val, err := fn(va.Convert(t).Interface().(T))
			if err != nil {
				if err == SkipFunc {
					err = errors.New("marshal function of type func(T) ([]byte, error) cannot be skipped")
				}
				// TODO: Avoid wrapping semantic errors.
				return &SemanticError{action: "marshal", GoType: t, Err: err}
			}
			if err := enc.WriteValue(val); err != nil {
				// TODO: Avoid wrapping semantic or I/O errors.
				return &SemanticError{action: "marshal", JSONKind: RawValue(val).Kind(), GoType: t, Err: err}
			}
			return nil
		},
	}
}

func init() {
	NewMarshalers(
		MarshalFuncV1(func(string) ([]byte, error) {
			return []byte("hello"), nil
		}),
	)
}

Closures are involved, but no range statements. Interestingly the compiler or crashes when calling MarshalFuncV1 in the init function.

Loading

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Aug 27, 2021

Works with GOEXPERIMENT=unified.

Loading

@dsnet
Copy link
Member Author

@dsnet dsnet commented Aug 27, 2021

For those who aren't involved with generics work, what's the significance of GOEXPERIMENT=unified?

Loading

@mdempsky
Copy link
Member

@mdempsky mdempsky commented Aug 27, 2021

cmd/compile currently has three frontends: -G=0 is the legacy, pre-generics frontend; -G=3 is the first generics-aware frontend that's currently enabled by default and has some support for stenciling; GOEXPERIMENT=unified is the second generics-aware frontend that I wrote to minimize complexity and hopefully avoid compiler errors.

Loading

@dsnet
Copy link
Member Author

@dsnet dsnet commented Aug 27, 2021

GOEXPERIMENT=unified is the second generics-aware frontend that I wrote to minimize complexity and hopefully avoid compiler errors.

Thanks for the explanation. Well, this seems like an example bug that favors your experiment 😄

Loading

@danscales
Copy link

@danscales danscales commented Aug 29, 2021

Here's a fairly minimized case:

package main

func test1[T any](fn func(T) int) {
	fn1 := func() {
		var i interface{}
		val := fn(i.(T))
		println(val)
	}
	println(fn1)
}

func main() {
	test1(func(string) int {
		return 5
	})
}

The key is the function call with an arg that is the result of a '.(T)' type assert, but all inside a closure. Things work fine if the function call is not inside a closure.

@randall77

Loading

@danscales
Copy link

@danscales danscales commented Aug 29, 2021

This is related/similar to issue #47676 . We probably need to do the substitution of the Defn nodes after the body of the function, since they often point into the body being stenciled.

Loading

@danscales danscales self-assigned this Aug 29, 2021
@gopherbot
Copy link

@gopherbot gopherbot commented Aug 30, 2021

Change https://golang.org/cl/346290 mentions this issue: cmd/compile: fix handling of Defn field during stenciling

Loading

@dsnet
Copy link
Member Author

@dsnet dsnet commented Aug 31, 2021

Thanks @danscales for the fix! I'm unfortunately hitting another different internal compiler error: #48103.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants