[dev.typeparams] cmd/compile/internal/types2: embedded type cannot be a (pointer to) a type parameter

Change-Id: I5eb03ae349925f0799dd866e207221429bc9fb3c
Reviewed-on: https://go-review.googlesource.com/c/go/+/337353
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-07-26 12:13:45 -07:00
parent d6753fd491
commit 37d2219960
5 changed files with 17 additions and 15 deletions

View File

@ -135,7 +135,7 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
embeddedPos := pos embeddedPos := pos
check.later(func() { check.later(func() {
t, isPtr := deref(embeddedTyp) t, isPtr := deref(embeddedTyp)
switch t := optype(t).(type) { switch t := under(t).(type) {
case *Basic: case *Basic:
if t == Typ[Invalid] { if t == Typ[Invalid] {
// error was reported before // error was reported before
@ -147,6 +147,8 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
} }
case *Pointer: case *Pointer:
check.error(embeddedPos, "embedded field type cannot be a pointer") check.error(embeddedPos, "embedded field type cannot be a pointer")
case *TypeParam:
check.error(embeddedPos, "embedded field type cannot be a (pointer to a) type parameter")
case *Interface: case *Interface:
if isPtr { if isPtr {
check.error(embeddedPos, "embedded field type cannot be a pointer to an interface") check.error(embeddedPos, "embedded field type cannot be a pointer to an interface")

View File

@ -79,11 +79,11 @@ var _ *int = new[int]()
func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable
func f1[T1 any](struct{T1}) int func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int
var _ = f1[int](struct{T1}{}) var _ = f1[int](struct{T1}{})
type T1 = int type T1 = int
func f2[t1 any](struct{t1; x float32}) int func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int
var _ = f2[t1](struct{t1; x float32}{}) var _ = f2[t1](struct{t1; x float32}{})
type t1 = int type t1 = int

View File

@ -8,8 +8,8 @@ package p
type E0[P any] P type E0[P any] P
type E1[P any] *P type E1[P any] *P
type E2[P any] struct{ P } type E2[P any] struct{ _ P }
type E3[P any] struct{ *P } type E3[P any] struct{ _ *P }
type T0 /* ERROR illegal cycle */ struct { type T0 /* ERROR illegal cycle */ struct {
_ E0[T0] _ E0[T0]

View File

@ -9,14 +9,14 @@ package main
type I interface{} type I interface{}
type _S[T any] struct { type _S[T any] struct {
*T x *T
} }
// F is a non-generic function, but has a type _S[I] which is instantiated from a // F is a non-generic function, but has a type _S[I] which is instantiated from a
// generic type. Test that _S[I] is successfully exported. // generic type. Test that _S[I] is successfully exported.
func F() { func F() {
v := _S[I]{} v := _S[I]{}
if v.T != nil { if v.x != nil {
panic(v) panic(v)
} }
} }
@ -33,9 +33,9 @@ func _F1[T interface{ M() }](t T) {
} }
func F2() { func F2() {
_F1(&S1{}) _F1(&S1{})
_F1(S2{}) _F1(S2{})
_F1(&S2{}) _F1(&S2{})
} }
func main() { func main() {

View File

@ -11,7 +11,7 @@ import "sync"
// A Lockable is a value that may be safely simultaneously accessed // A Lockable is a value that may be safely simultaneously accessed
// from multiple goroutines via the Get and Set methods. // from multiple goroutines via the Get and Set methods.
type Lockable[T any] struct { type Lockable[T any] struct {
T x T
mu sync.Mutex mu sync.Mutex
} }
@ -19,18 +19,18 @@ type Lockable[T any] struct {
func (l *Lockable[T]) get() T { func (l *Lockable[T]) get() T {
l.mu.Lock() l.mu.Lock()
defer l.mu.Unlock() defer l.mu.Unlock()
return l.T return l.x
} }
// set sets the value in a Lockable. // set sets the value in a Lockable.
func (l *Lockable[T]) set(v T) { func (l *Lockable[T]) set(v T) {
l.mu.Lock() l.mu.Lock()
defer l.mu.Unlock() defer l.mu.Unlock()
l.T = v l.x = v
} }
func main() { func main() {
sl := Lockable[string]{T: "a"} sl := Lockable[string]{x: "a"}
if got := sl.get(); got != "a" { if got := sl.get(); got != "a" {
panic(got) panic(got)
} }
@ -39,7 +39,7 @@ func main() {
panic(got) panic(got)
} }
il := Lockable[int]{T: 1} il := Lockable[int]{x: 1}
if got := il.get(); got != 1 { if got := il.get(); got != 1 {
panic(got) panic(got)
} }