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: able to use interface with type constraints #51578

Closed
dsnet opened this issue Mar 9, 2022 · 5 comments
Closed

cmd/compile: able to use interface with type constraints #51578

dsnet opened this issue Mar 9, 2022 · 5 comments
Labels
NeedsFix release-blocker
Milestone

Comments

@dsnet
Copy link
Member

@dsnet dsnet commented Mar 9, 2022

I'm a little behind on the latest with generics, but my understanding is that interfaces with type sets can currently only be used as type constraints.

If so, I would expect the following to not compile:

type TypeSet interface{ int | string }

func main() {
	t := reflect.TypeOf((*TypeSet)(nil)).Elem()
	fmt.Println(t)
	fmt.Println(t.Kind())
	fmt.Println(t.NumMethod())

	v := reflect.New(t).Elem()
	v.Set(reflect.ValueOf([]byte("hello"))) // this should panic
	fmt.Println(v.Elem().Type())
}

However, not only does it compile, it also executes with incorrect results:

main.TypeSet
interface
0
[]uint8

The v.Set(reflect.ValueOf([]byte("hello"))) is expected to panic since the underlying interface is specified to only hold int or string.

\cc @mdempsky @griesemer @ianlancetaylor

@griesemer griesemer self-assigned this Mar 9, 2022
@griesemer griesemer added NeedsFix release-blocker labels Mar 9, 2022
@griesemer griesemer added this to the Go1.18 milestone Mar 9, 2022
@griesemer
Copy link
Contributor

@griesemer griesemer commented Mar 9, 2022

The declaration

type TypeSet interface{ int | string }

is ok, but one shouldn't be able to use this type in the conversion of nil. This is a simple oversight. Fix forthcoming.

@dsnet
Copy link
Member Author

@dsnet dsnet commented Mar 9, 2022

Also, compiling with GOEXPERIMENT=unified produces an internal compiler error:

<unknown line number>: internal compiler error: panic: unexpected type: 10

goroutine 1 [running]:
runtime/debug.Stack()
	/usr/local/go.tip/src/runtime/debug/stack.go:24 +0x65
cmd/compile/internal/base.FatalfAt({0x222d0?, 0xc0?}, {0xd0a13b, 0x9}, {0xc0005b63c8, 0x1, 0x1})
	/usr/local/go.tip/src/cmd/compile/internal/base/print.go:227 +0x1d7
cmd/compile/internal/base.Fatalf(...)
	/usr/local/go.tip/src/cmd/compile/internal/base/print.go:196
cmd/compile/internal/gc.handlePanic()
	/usr/local/go.tip/src/cmd/compile/internal/gc/main.go:48 +0x85
panic({0xc79220, 0xc00010b410})
	/usr/local/go.tip/src/runtime/panic.go:838 +0x207
cmd/compile/internal/noder.(*reader).doTyp(0xc0000b9a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:415 +0x2bd
cmd/compile/internal/noder.(*pkgReader).typIdx(0xc0000360c0, {0xc0005b6690?, 0xf2?}, 0xc000137c20, 0x1)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:350 +0x171
cmd/compile/internal/noder.(*reader).typWrapped(0xc0000b98c0, 0x1?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:322 +0x45
cmd/compile/internal/noder.(*reader).typ(...)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:316
cmd/compile/internal/noder.(*reader).interfaceType(0xc0000b98c0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:467 +0x285
cmd/compile/internal/noder.(*reader).doTyp(0xc0000b98c0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:445 +0x249
cmd/compile/internal/noder.(*pkgReader).typIdx(0xc0000360c0, {0xc0005b68d0?, 0xff?}, 0xc000137c20, 0x0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:350 +0x171
cmd/compile/internal/noder.(*reader).typWrapped(0xc0000b9600, 0xc0?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:322 +0x45
cmd/compile/internal/noder.(*pkgReader).objIdx(0xc0000360c0, 0x6?, {0x0, 0x0, 0x0}, {0x13afe60, 0x0, 0x0})
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:661 +0x5d2
cmd/compile/internal/noder.(*reader).obj(0xc0000b91e0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:564 +0x1ee
cmd/compile/internal/noder.(*reader).doTyp(0xc0000b91e0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:421 +0x59
cmd/compile/internal/noder.(*pkgReader).typIdx(0xc0000360c0, {0xc0000b9080?, 0xc0?}, 0xc000136140, 0x1)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:350 +0x171
cmd/compile/internal/noder.(*reader).typWrapped(0xc0000b9080, 0x80?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:322 +0x45
cmd/compile/internal/noder.(*reader).typ(0x7fa308fb7d30?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:316 +0x1e
cmd/compile/internal/noder.(*reader).doTyp(0xc0000b9080)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:437 +0x145
cmd/compile/internal/noder.(*pkgReader).typIdx(0xc0000360c0, {0xc000429a20?, 0x80?}, 0xc000136140, 0x1)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:350 +0x171
cmd/compile/internal/noder.(*reader).typWrapped(0xc000429a20, 0x20?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:322 +0x45
cmd/compile/internal/noder.(*reader).typ(0x4eadc2?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:316 +0x1e
cmd/compile/internal/noder.(*reader).expr(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1668 +0xcb7
cmd/compile/internal/noder.(*reader).exprs(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1768 +0x8d
cmd/compile/internal/noder.(*reader).expr(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1663 +0xe85
cmd/compile/internal/noder.(*reader).expr(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1656 +0xd5b
cmd/compile/internal/noder.(*reader).exprs(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1768 +0x8d
cmd/compile/internal/noder.(*reader).exprList(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1758 +0x2f
cmd/compile/internal/noder.(*reader).stmt1(0xc000429a20?, 0x30?, 0xc0005b77e0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1222 +0xba
cmd/compile/internal/noder.(*reader).stmts(0xc000429a20)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:1199 +0xa5
cmd/compile/internal/noder.(*reader).funcBody.func1()
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:984 +0x52
cmd/compile/internal/ir.WithFunc(0x586?, 0xb7?)
	/usr/local/go.tip/src/cmd/compile/internal/ir/func.go:293 +0xab
cmd/compile/internal/noder.(*reader).funcBody(0xc000429a20, 0xc0004298c0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:977 +0xaf
cmd/compile/internal/noder.pkgReaderIndex.funcBody({0xc0000360c0?, 0xc00013f928?, 0xc000136140?}, 0xc000700000?)
	/usr/local/go.tip/src/cmd/compile/internal/noder/reader.go:970 +0x3c
cmd/compile/internal/noder.readBodies(0xc0001746c0)
	/usr/local/go.tip/src/cmd/compile/internal/noder/unified.go:150 +0xca
cmd/compile/internal/noder.unified({0xc00011c430?, 0x0?, 0x2?})
	/usr/local/go.tip/src/cmd/compile/internal/noder/unified.go:119 +0x42a
cmd/compile/internal/noder.LoadPackage({0xc000124100, 0x1, 0x0?})
	/usr/local/go.tip/src/cmd/compile/internal/noder/noder.go:73 +0x2b4
cmd/compile/internal/gc.Main(0xd398b0)
	/usr/local/go.tip/src/cmd/compile/internal/gc/main.go:190 +0xb13
main.main()
	/usr/local/go.tip/src/cmd/compile/main.go:55 +0xdd

@griesemer
Copy link
Contributor

@griesemer griesemer commented Mar 9, 2022

Simpler reproducer:

var _ = (*interface{int})(nil)

should not be permitted.

@gopherbot
Copy link

@gopherbot gopherbot commented Mar 9, 2022

Change https://go.dev/cl/391275 mentions this issue: go/types, types2: pointer base types cannot be type constraints

@gopherbot
Copy link

@gopherbot gopherbot commented Mar 10, 2022

Change https://go.dev/cl/391357 mentions this issue: [release-branch.go1.18] go/types, types2: pointer base types cannot be type constraints

gopherbot pushed a commit that referenced this issue Mar 11, 2022
…e type constraints

Pointer types may appear in expressions *P and we don't know if
we have an indirection (P is a pointer value) or a pointer type
(P is a type) until we type-check P. Don't forget to check that
a type P must be an ordinary (not a constraint) type in this
special case.

Fixes #51578.

Change-Id: If782cc6dd2a602a498574c78c99e40c3b72274a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/391275
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 3a5e3d8)
Reviewed-on: https://go-review.googlesource.com/c/go/+/391357
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix release-blocker
Projects
None yet
Development

No branches or pull requests

3 participants