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
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@dsnet
Copy link
Member

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 commented Aug 27, 2021

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

@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 27, 2021
@ALTree ALTree added this to the Go1.18 milestone Aug 27, 2021
@dsnet
Copy link
Member Author

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.

@mdempsky
Copy link
Member

Works with GOEXPERIMENT=unified.

@dsnet
Copy link
Member Author

dsnet commented Aug 27, 2021

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

@mdempsky
Copy link
Member

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.

@dsnet
Copy link
Member Author

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 😄

@danscales
Copy link
Contributor

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

@danscales
Copy link
Contributor

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.

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

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

@dsnet
Copy link
Member Author

dsnet commented Aug 31, 2021

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants