Skip to content

Commit efb7cc4

Browse files
griesemerthanm
authored andcommitted
[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 <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 0bd1a22 commit efb7cc4

3 files changed

Lines changed: 25 additions & 12 deletions

File tree

src/cmd/compile/internal/types2/typeset.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,8 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
255255
allTerms := allTermlist
256256
allComparable := false
257257
for i, typ := range ityp.embeddeds {
258-
// The embedding position is nil for imported interfaces
259-
// and also for interface copies after substitution (but
260-
// in that case we don't need to report errors again).
258+
// The embedding position is nil for imported interfaces.
259+
// We don't need to do version checks in those cases.
261260
var pos syntax.Pos // embedding position
262261
if ityp.embedPos != nil {
263262
pos = (*ityp.embedPos)[i]
@@ -270,7 +269,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
270269
assert(!isTypeParam(typ))
271270
tset := computeInterfaceTypeSet(check, pos, u)
272271
// If typ is local, an error was already reported where typ is specified/defined.
273-
if check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(pos, go1_18, "embedding constraint interface %s", typ) {
272+
if pos.IsKnown() && check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(pos, go1_18, "embedding constraint interface %s", typ) {
274273
continue
275274
}
276275
comparable = tset.comparable
@@ -279,7 +278,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
279278
}
280279
terms = tset.terms
281280
case *Union:
282-
if check != nil && !check.verifyVersionf(pos, go1_18, "embedding interface element %s", u) {
281+
if pos.IsKnown() && check != nil && !check.verifyVersionf(pos, go1_18, "embedding interface element %s", u) {
283282
continue
284283
}
285284
tset := computeUnionTypeSet(check, unionSets, pos, u)
@@ -293,7 +292,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
293292
if u == Typ[Invalid] {
294293
continue
295294
}
296-
if check != nil && !check.verifyVersionf(pos, go1_18, "embedding non-interface type %s", typ) {
295+
if pos.IsKnown() && check != nil && !check.verifyVersionf(pos, go1_18, "embedding non-interface type %s", typ) {
297296
continue
298297
}
299298
terms = termlist{{false, typ}}

src/go/types/typeset.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,8 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
253253
allTerms := allTermlist
254254
allComparable := false
255255
for i, typ := range ityp.embeddeds {
256-
// The embedding position is nil for imported interfaces
257-
// and also for interface copies after substitution (but
258-
// in that case we don't need to report errors again).
256+
// The embedding position is nil for imported interfaces.
257+
// We don't need to do version checks in those cases.
259258
var pos token.Pos // embedding position
260259
if ityp.embedPos != nil {
261260
pos = (*ityp.embedPos)[i]
@@ -268,7 +267,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
268267
assert(!isTypeParam(typ))
269268
tset := computeInterfaceTypeSet(check, pos, u)
270269
// If typ is local, an error was already reported where typ is specified/defined.
271-
if check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(atPos(pos), go1_18, "embedding constraint interface %s", typ) {
270+
if pos.IsValid() && check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(atPos(pos), go1_18, "embedding constraint interface %s", typ) {
272271
continue
273272
}
274273
comparable = tset.comparable
@@ -277,7 +276,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
277276
}
278277
terms = tset.terms
279278
case *Union:
280-
if check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding interface element %s", u) {
279+
if pos.IsValid() && check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding interface element %s", u) {
281280
continue
282281
}
283282
tset := computeUnionTypeSet(check, unionSets, pos, u)
@@ -291,7 +290,7 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
291290
if u == Typ[Invalid] {
292291
continue
293292
}
294-
if check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding non-interface type %s", typ) {
293+
if pos.IsValid() && check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding non-interface type %s", typ) {
295294
continue
296295
}
297296
terms = termlist{{false, typ}}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// -lang=go1.16
2+
3+
// Copyright 2024 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
//go:build go1.21
8+
9+
package main
10+
11+
import "slices"
12+
13+
func main() {
14+
_ = slices.Clone([]string{}) // no error should be reported here
15+
}

0 commit comments

Comments
 (0)