aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/types2')
-rw-r--r--src/cmd/compile/internal/types2/instantiate.go2
-rw-r--r--src/cmd/compile/internal/types2/signature.go8
-rw-r--r--src/cmd/compile/internal/types2/subst.go6
-rw-r--r--src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go221
-rw-r--r--src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go28
-rw-r--r--src/cmd/compile/internal/types2/typelists.go13
6 files changed, 50 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/types2/instantiate.go b/src/cmd/compile/internal/types2/instantiate.go
index f9cde24dfc..4113d248b8 100644
--- a/src/cmd/compile/internal/types2/instantiate.go
+++ b/src/cmd/compile/internal/types2/instantiate.go
@@ -75,7 +75,7 @@ func Instantiate(env *Environment, typ Type, targs []Type, validate bool) (Type,
func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, posList []syntax.Pos) (res Type) {
assert(check != nil)
if check.conf.Trace {
- check.trace(pos, "-- instantiating %s with %s", typ, typeListString(targs))
+ check.trace(pos, "-- instantiating %s with %s", typ, NewTypeList(targs))
check.indent++
defer func() {
check.indent--
diff --git a/src/cmd/compile/internal/types2/signature.go b/src/cmd/compile/internal/types2/signature.go
index d28e7b8944..ddad1f0311 100644
--- a/src/cmd/compile/internal/types2/signature.go
+++ b/src/cmd/compile/internal/types2/signature.go
@@ -132,7 +132,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
// Also: Don't report an error via genericType since it will be reported
// again when we type-check the signature.
// TODO(gri) maybe the receiver should be marked as invalid instead?
- if recv := asNamed(check.genericType(rname, false)); recv != nil {
+ if recv, _ := check.genericType(rname, false).(*Named); recv != nil {
recvTParams = recv.TParams().list()
}
}
@@ -211,6 +211,12 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
switch T := rtyp.(type) {
case *Named:
T.expand(nil)
+ // The receiver type may be an instantiated type referred to
+ // by an alias (which cannot have receiver parameters for now).
+ if T.TArgs() != nil && sig.RParams() == nil {
+ check.errorf(recv.pos, "cannot define methods on instantiated type %s", recv.typ)
+ break
+ }
// spec: "The type denoted by T is called the receiver base type; it must not
// be a pointer or interface type and it must be declared in the same package
// as the method."
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go
index ff8dd13b6d..7c33e7ade4 100644
--- a/src/cmd/compile/internal/types2/subst.go
+++ b/src/cmd/compile/internal/types2/subst.go
@@ -281,12 +281,6 @@ func instantiatedHash(typ *Named, targs []Type) string {
return string(res[:i])
}
-func typeListString(list []Type) string {
- var buf bytes.Buffer
- writeTypeList(&buf, list, nil, nil)
- return buf.String()
-}
-
// typOrNil is like typ but if the argument is nil it is replaced with Typ[Invalid].
// A nil type may appear in pathological cases such as type T[P any] []func(_ T([]_))
// where an array/slice element is accessed before it is set up.
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go2
new file mode 100644
index 0000000000..bbbe6805f2
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go2
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T[P any] struct{}
+
+func (T[P]) m1()
+
+type A1 = T
+
+func (A1[P]) m2() {}
+
+type A2 = T[int]
+
+func (A2 /* ERROR cannot define methods on instantiated type T\[int\] */) m3() {}
+func (_ /* ERROR cannot define methods on instantiated type T\[int\] */ A2) m4() {}
+
+func (T[int]) m5() {} // int is the type parameter name, not an instantiation
+func (T[* /* ERROR must be an identifier */ int]) m6() {} // syntax error
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go2
new file mode 100644
index 0000000000..56e90942ab
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go2
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// don't crash
+func T /* ERROR missing */ [P /* ERROR named */ ] m /* ERROR m */ () /* ERROR \) */ { /* ERROR { */ } /* ERROR } */
diff --git a/src/cmd/compile/internal/types2/typelists.go b/src/cmd/compile/internal/types2/typelists.go
index 3258a5e9f8..c3befb077f 100644
--- a/src/cmd/compile/internal/types2/typelists.go
+++ b/src/cmd/compile/internal/types2/typelists.go
@@ -4,6 +4,8 @@
package types2
+import "bytes"
+
// TParamList holds a list of type parameters.
type TParamList struct{ tparams []*TypeParam }
@@ -52,6 +54,17 @@ func (l *TypeList) list() []Type {
return l.types
}
+func (l *TypeList) String() string {
+ if l == nil || len(l.types) == 0 {
+ return "[]"
+ }
+ var buf bytes.Buffer
+ buf.WriteByte('[')
+ writeTypeList(&buf, l.types, nil, nil)
+ buf.WriteByte(']')
+ return buf.String()
+}
+
// ----------------------------------------------------------------------------
// Implementation