From 18e0503724e64c3d55dbc705eb4f08be2fde1b32 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Tue, 3 Aug 2021 16:32:23 -0400 Subject: [dev.typeparams] go/types: embedded type cannot be a (pointer to) a type parameter This is a port of CL 337353 to go/types, adjusted for the error API and to comment out a test for MethodSet. Some nearby error messages that were using errorf rather than error were also adjusted. Fixes #43621 Change-Id: I28c9747e044ec7a2863f6890db69475fb8c29231 Reviewed-on: https://go-review.googlesource.com/c/go/+/339651 Trust: Robert Findley Run-TryBot: Robert Findley TryBot-Result: Go Bot Reviewed-by: Robert Griesemer --- src/go/types/methodset_test.go | 12 +++++++----- src/go/types/struct.go | 10 ++++++---- src/go/types/testdata/check/typeparams.go2 | 4 ++-- src/go/types/testdata/fixedbugs/issue39938.go2 | 4 ++-- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/go/types/methodset_test.go b/src/go/types/methodset_test.go index 5b29b2f0fe..73a8442f21 100644 --- a/src/go/types/methodset_test.go +++ b/src/go/types/methodset_test.go @@ -46,12 +46,14 @@ func TestNewMethodSet(t *testing.T) { genericTests := map[string][]method{ // By convention, look up a in the scope of "g" - "type C interface{ f() }; func g[T C](a T){}": {{"f", []int{0}, true}}, - "type C interface{ f() }; func g[T C]() { var a T; _ = a }": {{"f", []int{0}, true}}, - "type C interface{ f() }; func g[T C]() { var a struct{T}; _ = a }": {{"f", []int{0, 0}, true}}, + "type C interface{ f() }; func g[T C](a T){}": {{"f", []int{0}, true}}, + "type C interface{ f() }; func g[T C]() { var a T; _ = a }": {{"f", []int{0}, true}}, - // Issue #45639: We don't allow this anymore. Keep this code in case we - // decide to revisit this decision. + // Issue #43621: We don't allow this anymore. Keep this code in case we + // decide to revisit this decision. + // "type C interface{ f() }; func g[T C]() { var a struct{T}; _ = a }": {{"f", []int{0, 0}, true}}, + + // Issue #45639: We also don't allow this anymore. // "type C interface{ f() }; func g[T C]() { type Y T; var a Y; _ = a }": {}, } diff --git a/src/go/types/struct.go b/src/go/types/struct.go index d1fb813c14..48b07346dc 100644 --- a/src/go/types/struct.go +++ b/src/go/types/struct.go @@ -136,7 +136,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) { check.later(func() { t, isPtr := deref(embeddedTyp) - switch t := optype(t).(type) { + switch t := under(t).(type) { case *Basic: if t == Typ[Invalid] { // error was reported before @@ -144,13 +144,15 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) { } // unsafe.Pointer is treated like a regular pointer if t.kind == UnsafePointer { - check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer") + check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer") } case *Pointer: - check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer") + check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer") + case *TypeParam: + check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a (pointer to a) type parameter") case *Interface: if isPtr { - check.errorf(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface") + check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface") } } }) diff --git a/src/go/types/testdata/check/typeparams.go2 b/src/go/types/testdata/check/typeparams.go2 index b03725ff2a..77cd65d19a 100644 --- a/src/go/types/testdata/check/typeparams.go2 +++ b/src/go/types/testdata/check/typeparams.go2 @@ -79,11 +79,11 @@ var _ *int = new[int]() func _[T any](map[T /* ERROR incomparable 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}{}) 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}{}) type t1 = int diff --git a/src/go/types/testdata/fixedbugs/issue39938.go2 b/src/go/types/testdata/fixedbugs/issue39938.go2 index 76e7e369ca..0da6e103fd 100644 --- a/src/go/types/testdata/fixedbugs/issue39938.go2 +++ b/src/go/types/testdata/fixedbugs/issue39938.go2 @@ -8,8 +8,8 @@ package p type E0[P any] P type E1[P any] *P -type E2[P any] struct{ P } -type E3[P any] struct{ *P } +type E2[P any] struct{ _ P } +type E3[P any] struct{ _ *P } type T0 /* ERROR illegal cycle */ struct { _ E0[T0] -- cgit v1.2.3-54-g00ecf