1
0
mirror of https://github.com/golang/go synced 2024-09-29 04:14:27 -06:00

go/types, types2: ensure that signature type bounds are interfaces

Do this by running verification for instantiated signatures
later, after the delayed type parameter set-up had a chance
to wrap type bounds in implicit interfaces where needed.

Fixes #50450

Change-Id: If3ff7dc0be6af14af854830bfddb81112ac575cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/375737
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2022-01-05 12:25:43 -08:00
parent 10f1ed131c
commit c5540e53b1
4 changed files with 50 additions and 20 deletions

View File

@ -74,17 +74,21 @@ func (check *Checker) instantiateSignature(pos syntax.Pos, typ *Signature, targs
inst := check.instance(pos, typ, targs, check.bestContext(nil)).(*Signature)
assert(len(xlist) <= len(targs))
tparams := typ.TypeParams().list()
if i, err := check.verify(pos, tparams, targs); err != nil {
// best position for error reporting
pos := pos
if i < len(xlist) {
pos = syntax.StartPos(xlist[i])
// verify instantiation lazily (was issue #50450)
check.later(func() {
tparams := typ.TypeParams().list()
if i, err := check.verify(pos, tparams, targs); err != nil {
// best position for error reporting
pos := pos
if i < len(xlist) {
pos = syntax.StartPos(xlist[i])
}
check.softErrorf(pos, "%s", err)
} else {
check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
}
check.softErrorf(pos, "%s", err)
} else {
check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
}
})
return inst
}

View File

@ -0,0 +1,11 @@
// Copyright 2022 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 S struct{}
func f[P S]() {}
var _ = f[S]

View File

@ -75,17 +75,21 @@ func (check *Checker) instantiateSignature(pos token.Pos, typ *Signature, targs
inst := check.instance(pos, typ, targs, check.bestContext(nil)).(*Signature)
assert(len(xlist) <= len(targs))
tparams := typ.TypeParams().list()
if i, err := check.verify(pos, tparams, targs); err != nil {
// best position for error reporting
pos := pos
if i < len(xlist) {
pos = xlist[i].Pos()
// verify instantiation lazily (was issue #50450)
check.later(func() {
tparams := typ.TypeParams().list()
if i, err := check.verify(pos, tparams, targs); err != nil {
// best position for error reporting
pos := pos
if i < len(xlist) {
pos = xlist[i].Pos()
}
check.softErrorf(atPos(pos), _InvalidTypeArg, "%s", err)
} else {
check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
}
check.softErrorf(atPos(pos), _InvalidTypeArg, "%s", err)
} else {
check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
}
})
return inst
}

View File

@ -0,0 +1,11 @@
// Copyright 2022 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 S struct{}
func f[P S]() {}
var _ = f[S]