aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
authorRobert Griesemer <gri@google.com>2026-02-18 14:41:50 -0800
committerGopher Robot <gobot@golang.org>2026-03-09 12:16:20 -0700
commite84da0405bcf64c7dbaafb0afc14388049a9b6fc (patch)
treecee6be97994cdf4ee43f8eb13302e6c9aeda451a /src/cmd/compile
parentd4ace6b007224ef71348f500f1515510bd2c282c (diff)
downloadgo-e84da0405bcf64c7dbaafb0afc14388049a9b6fc.tar.xz
cmd/compile, go/*: allow generic methods starting with Go 1.27
This only changes the type checkers and tests. Backend compiler changes are not included. For #77273. Change-Id: I8cf0b6fddf6afd6b08b06ba6fdf9c726af4bea8d Reviewed-on: https://go-review.googlesource.com/c/go/+/746820 Reviewed-by: Robert Griesemer <gri@google.com> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile')
-rw-r--r--src/cmd/compile/internal/types2/resolver.go22
-rw-r--r--src/cmd/compile/internal/types2/version.go1
2 files changed, 12 insertions, 11 deletions
diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go
index 0911ae9c90..ef9d0ed4ec 100644
--- a/src/cmd/compile/internal/types2/resolver.go
+++ b/src/cmd/compile/internal/types2/resolver.go
@@ -415,22 +415,27 @@ func (check *Checker) collectObjects() {
case *syntax.FuncDecl:
name := s.Name.Value
- obj := NewFunc(s.Name.Pos(), pkg, name, nil)
- hasTParamError := false // avoid duplicate type parameter errors
+ obj := NewFunc(s.Name.Pos(), pkg, name, nil) // signature set later
+ var tparam0 *syntax.Field
+ if len(s.TParamList) > 0 {
+ tparam0 = s.TParamList[0]
+ }
if s.Recv == nil {
// regular function
if name == "init" || name == "main" && pkg.name == "main" {
+ // init and main functions must not declare type and ordinary parameters or results
code := InvalidInitDecl
if name == "main" {
code = InvalidMainDecl
}
- if len(s.TParamList) != 0 {
- check.softErrorf(s.TParamList[0], code, "func %s must have no type parameters", name)
- hasTParamError = true
+ if tparam0 != nil {
+ check.softErrorf(tparam0, code, "func %s must have no type parameters", name)
}
if t := s.Type; len(t.ParamList) != 0 || len(t.ResultList) != 0 {
check.softErrorf(s.Name, code, "func %s must have no arguments and no return values", name)
}
+ } else {
+ _ = tparam0 != nil && check.verifyVersionf(tparam0, go1_18, "type parameter")
}
// don't declare init functions in the package scope - they are invisible
if name == "init" {
@@ -452,14 +457,9 @@ func (check *Checker) collectObjects() {
if recv, _ := base.(*syntax.Name); recv != nil && name != "_" {
methods = append(methods, methodInfo{obj, ptr, recv})
}
- // methods cannot have type parameters for now
- if len(s.TParamList) != 0 {
- check.softErrorf(s.TParamList[0], InvalidMethodTypeParams, "method %s must have no type parameters", name)
- hasTParamError = true
- }
+ _ = tparam0 != nil && check.verifyVersionf(tparam0, go1_27, "generic method")
check.recordDef(s.Name, obj)
}
- _ = len(s.TParamList) != 0 && !hasTParamError && check.verifyVersionf(s.TParamList[0], go1_18, "type parameter")
info := &declInfo{file: fileScope, version: check.version, fdecl: s}
// Methods are not package-level objects but we still track them in the
// object map so that we can handle them like regular functions (if the
diff --git a/src/cmd/compile/internal/types2/version.go b/src/cmd/compile/internal/types2/version.go
index 512285055c..05cb9391b9 100644
--- a/src/cmd/compile/internal/types2/version.go
+++ b/src/cmd/compile/internal/types2/version.go
@@ -44,6 +44,7 @@ var (
go1_22 = asGoVersion("go1.22")
go1_23 = asGoVersion("go1.23")
go1_26 = asGoVersion("go1.26")
+ go1_27 = asGoVersion("go1.27")
// current (deployed) Go version
go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version))