From cb357835d9c62232e70f7bf0eb7b105a2901bd1a Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 29 Aug 2022 16:40:31 -0700 Subject: [PATCH] cmd/compile/internal/types2: match go/types error for invalid instantiations Also: add a missing test. For #54511. Change-Id: Ie9828c6ba5186feb5a79db0d58beb2cda2beae56 Reviewed-on: https://go-review.googlesource.com/c/go/+/426478 Reviewed-by: Robert Findley Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer Run-TryBot: Robert Griesemer TryBot-Result: Gopher Robot --- src/cmd/compile/internal/types2/signature.go | 2 +- .../types2/testdata/fixedbugs/issue48827.go | 19 +++++++++++++++++++ src/cmd/compile/internal/types2/typexpr.go | 16 +++++++++++----- 3 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go diff --git a/src/cmd/compile/internal/types2/signature.go b/src/cmd/compile/internal/types2/signature.go index 1b61b368d2..d6a8e70902 100644 --- a/src/cmd/compile/internal/types2/signature.go +++ b/src/cmd/compile/internal/types2/signature.go @@ -130,7 +130,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, _ := check.genericType(rname, false).(*Named); recv != nil { + if recv, _ := check.genericType(rname, nil).(*Named); recv != nil { recvTParams = recv.TypeParams().list() } } diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go new file mode 100644 index 0000000000..52ccd1ce0c --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48827.go @@ -0,0 +1,19 @@ +// 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 G[P any] int + +type ( + _ G[int] + _ G[G /* ERROR "cannot use.*without instantiation" */] + _ bool /* ERROR "invalid operation: bool\[int\] \(bool is not a generic type\)" */ [int] + _ bool /* ERROR "invalid operation: bool\[G\] \(bool is not a generic type\)" */[G] +) + +// The example from the issue. +func _() { + _ = &([10]bool /* ERROR "invalid operation.*bool is not a generic type" */ [1]{}) +} diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go index 692feb9751..262f5af332 100644 --- a/src/cmd/compile/internal/types2/typexpr.go +++ b/src/cmd/compile/internal/types2/typexpr.go @@ -191,13 +191,15 @@ func (check *Checker) definedType(e syntax.Expr, def *Named) Type { return typ } -// genericType is like typ but the type must be an (uninstantiated) generic type. -func (check *Checker) genericType(e syntax.Expr, reportErr bool) Type { +// genericType is like typ but the type must be an (uninstantiated) generic +// type. If reason is non-nil and the type expression was a valid type but not +// generic, reason will be populated with a message describing the error. +func (check *Checker) genericType(e syntax.Expr, reason *string) Type { typ := check.typInternal(e, nil) assert(isTyped(typ)) if typ != Typ[Invalid] && !isGeneric(typ) { - if reportErr { - check.errorf(e, "%s is not a generic type", typ) + if reason != nil { + *reason = check.sprintf("%s is not a generic type", typ) } typ = Typ[Invalid] } @@ -415,7 +417,11 @@ func (check *Checker) instantiatedType(x syntax.Expr, xlist []syntax.Expr, def * }() } - gtyp := check.genericType(x, true) + var reason string + gtyp := check.genericType(x, &reason) + if reason != "" { + check.errorf(x, invalidOp+"%s%s (%s)", x, xlist, reason) + } if gtyp == Typ[Invalid] { return gtyp // error already reported } -- 2.48.1