aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2024-03-12 09:31:06 -0700
committerThan McIntosh <thanm@google.com>2024-03-27 19:24:11 +0000
commitefb7cc4275d20628d670493997c8952c49391f6e (patch)
tree7e57d2853f1c6639450a459c2bf0ea9e3a8f9273
parent0bd1a2289d0e37ec5015ce3c05a5873c3a6da3e5 (diff)
downloadgo-efb7cc4275d20628d670493997c8952c49391f6e.tar.gz
go-efb7cc4275d20628d670493997c8952c49391f6e.zip
[release-branch.go1.21] go/types, types2: don't do version checks for embedded types of imported interfaces
[This is a re-apply of CL 571075] Imported interfaces don't have position information for embedded types. When computing the type set of such interfaces, doing a version check may fail because it will rely on the Go version of the current package. We must not do a version check for features of types from imported packages - those types have already been typechecked and are "correct". The version check code does look at packages to avoid such incorrect version checks, but we don't have the package information available in an interface type (divorced from its object). Instead, for now rely on the fact that imported interfaces don't have position information for embedded types: if the position is unknown, don't do a version check. We may want to assert that positions are known in all other cases, but since this is an older release, don't add such additional changes to avoid introducing other bugs. Fixes #66326. Updates #66064. Change-Id: I158cf51aa382f85d612ab958ba4b591de1c5fdb2 Reviewed-on: https://go-review.googlesource.com/c/go/+/574736 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
-rw-r--r--src/cmd/compile/internal/types2/typeset.go11
-rw-r--r--src/go/types/typeset.go11
-rw-r--r--src/internal/types/testdata/fixedbugs/issue66064.go15
3 files changed, 25 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/types2/typeset.go b/src/cmd/compile/internal/types2/typeset.go
index 8d33597ffd..14039ac9d6 100644
--- a/src/cmd/compile/internal/types2/typeset.go
+++ b/src/cmd/compile/internal/types2/typeset.go
@@ -255,9 +255,8 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
allTerms := allTermlist
allComparable := false
for i, typ := range ityp.embeddeds {
- // The embedding position is nil for imported interfaces
- // and also for interface copies after substitution (but
- // in that case we don't need to report errors again).
+ // The embedding position is nil for imported interfaces.
+ // We don't need to do version checks in those cases.
var pos syntax.Pos // embedding position
if ityp.embedPos != nil {
pos = (*ityp.embedPos)[i]
@@ -270,7 +269,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
assert(!isTypeParam(typ))
tset := computeInterfaceTypeSet(check, pos, u)
// If typ is local, an error was already reported where typ is specified/defined.
- if check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(pos, go1_18, "embedding constraint interface %s", typ) {
+ if pos.IsKnown() && check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(pos, go1_18, "embedding constraint interface %s", typ) {
continue
}
comparable = tset.comparable
@@ -279,7 +278,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
}
terms = tset.terms
case *Union:
- if check != nil && !check.verifyVersionf(pos, go1_18, "embedding interface element %s", u) {
+ if pos.IsKnown() && check != nil && !check.verifyVersionf(pos, go1_18, "embedding interface element %s", u) {
continue
}
tset := computeUnionTypeSet(check, unionSets, pos, u)
@@ -293,7 +292,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
if u == Typ[Invalid] {
continue
}
- if check != nil && !check.verifyVersionf(pos, go1_18, "embedding non-interface type %s", typ) {
+ if pos.IsKnown() && check != nil && !check.verifyVersionf(pos, go1_18, "embedding non-interface type %s", typ) {
continue
}
terms = termlist{{false, typ}}
diff --git a/src/go/types/typeset.go b/src/go/types/typeset.go
index 4cd118a226..a7d4485d0e 100644
--- a/src/go/types/typeset.go
+++ b/src/go/types/typeset.go
@@ -253,9 +253,8 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
allTerms := allTermlist
allComparable := false
for i, typ := range ityp.embeddeds {
- // The embedding position is nil for imported interfaces
- // and also for interface copies after substitution (but
- // in that case we don't need to report errors again).
+ // The embedding position is nil for imported interfaces.
+ // We don't need to do version checks in those cases.
var pos token.Pos // embedding position
if ityp.embedPos != nil {
pos = (*ityp.embedPos)[i]
@@ -268,7 +267,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
assert(!isTypeParam(typ))
tset := computeInterfaceTypeSet(check, pos, u)
// If typ is local, an error was already reported where typ is specified/defined.
- if check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(atPos(pos), go1_18, "embedding constraint interface %s", typ) {
+ if pos.IsValid() && check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(atPos(pos), go1_18, "embedding constraint interface %s", typ) {
continue
}
comparable = tset.comparable
@@ -277,7 +276,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
}
terms = tset.terms
case *Union:
- if check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding interface element %s", u) {
+ if pos.IsValid() && check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding interface element %s", u) {
continue
}
tset := computeUnionTypeSet(check, unionSets, pos, u)
@@ -291,7 +290,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
if u == Typ[Invalid] {
continue
}
- if check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding non-interface type %s", typ) {
+ if pos.IsValid() && check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding non-interface type %s", typ) {
continue
}
terms = termlist{{false, typ}}
diff --git a/src/internal/types/testdata/fixedbugs/issue66064.go b/src/internal/types/testdata/fixedbugs/issue66064.go
new file mode 100644
index 0000000000..d4a361754b
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue66064.go
@@ -0,0 +1,15 @@
+// -lang=go1.16
+
+// Copyright 2024 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.
+
+//go:build go1.21
+
+package main
+
+import "slices"
+
+func main() {
+ _ = slices.Clone([]string{}) // no error should be reported here
+}