From 6bdfff112f098b371bca718efffa47225cc1b608 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 19 May 2021 16:25:31 -0700 Subject: [PATCH] [dev.typeparams] cmd/compile/internal/types2: use correct type parameter list in missingMethod For #46275 Change-Id: Iaed9d8ba034ad793e5c57f2be174f01a535fee95 Reviewed-on: https://go-review.googlesource.com/c/go/+/321232 Trust: Robert Griesemer Reviewed-by: Robert Findley --- src/cmd/compile/internal/types2/lookup.go | 21 ++++++++++++++- .../types2/testdata/fixedbugs/issue46275.go2 | 26 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go2 diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go index 78299502e9..eb2b17dd4d 100644 --- a/src/cmd/compile/internal/types2/lookup.go +++ b/src/cmd/compile/internal/types2/lookup.go @@ -333,6 +333,9 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, if len(ftyp.tparams) != len(mtyp.tparams) { return m, f } + if !acceptMethodTypeParams && len(ftyp.tparams) > 0 { + panic("internal error: method with type parameters") + } // If the methods have type parameters we don't care whether they // are the same or not, as long as they match up. Use unification @@ -386,6 +389,9 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, if len(ftyp.tparams) != len(mtyp.tparams) { return m, f } + if !acceptMethodTypeParams && len(ftyp.tparams) > 0 { + panic("internal error: method with type parameters") + } // If V is a (instantiated) generic type, its methods are still // parameterized using the original (declaration) receiver type @@ -413,7 +419,20 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, // TODO(gri) is this always correct? what about type bounds? // (Alternative is to rename/subst type parameters and compare.) u := newUnifier(check, true) - u.x.init(ftyp.tparams) + if len(ftyp.tparams) > 0 { + // We reach here only if we accept method type parameters. + // In this case, unification must consider any receiver + // and method type parameters as "free" type parameters. + assert(acceptMethodTypeParams) + // We don't have a test case for this at the moment since + // we can't parse method type parameters. Keeping the + // unimplemented call so that we test this code if we + // enable method type parameters. + unimplemented() + u.x.init(append(ftyp.rparams, ftyp.tparams...)) + } else { + u.x.init(ftyp.rparams) + } if !u.unify(ftyp, mtyp) { return m, f } diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go2 new file mode 100644 index 0000000000..f41ae26e4b --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go2 @@ -0,0 +1,26 @@ +// 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 issue46275 + +type N[T any] struct { + *N[T] + t T +} + +func (n *N[T]) Elem() T { + return n.t +} + +type I interface { + Elem() string +} + +func _() { + var n1 *N[string] + var _ I = n1 + type NS N[string] + var n2 *NS + var _ I = n2 +}