mirror of https://github.com/golang/go.git
[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:
parent
d6753fd491
commit
37d2219960
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue