cmd/compile/internal/types2: avoid duplicate errors for invalid bounds

Resolve a TODO from an earlier CL: we should only check type parameter
bounds once in collectTypeParams.

Change-Id: Icf6053ec359f8ac8143cf68ee2defd504f8f86e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/355069
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Robert Findley 2021-10-11 09:59:40 -04:00
parent c1b0ae4154
commit d90f0b9200
2 changed files with 12 additions and 5 deletions

View File

@ -627,24 +627,29 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list []*syntax.Fiel
// Example: type T[P T[P]] interface{}
*dst = bindTParams(tparams)
// Keep track of bounds for later validation.
var bound Type
var bounds []Type
var posers []poser
for i, f := range list {
// Optimization: Re-use the previous type bound if it hasn't changed.
// This also preserves the grouped output of type parameter lists
// when printing type strings.
if i == 0 || f.Type != list[i-1].Type {
bound = check.bound(f.Type)
bounds = append(bounds, bound)
posers = append(posers, f.Type)
}
tparams[i].bound = bound
}
check.later(func() {
for i, tpar := range tparams {
// TODO(rfindley): this results in duplicate error messages for type
// parameters that share a constraint.
if _, ok := under(tpar.bound).(*TypeParam); ok {
check.error(list[i].Type, "cannot use a type parameter as constraint")
for i, bound := range bounds {
if _, ok := under(bound).(*TypeParam); ok {
check.error(posers[i], "cannot use a type parameter as constraint")
}
}
for _, tpar := range tparams {
tpar.iface() // compute type set
}
})

View File

@ -46,6 +46,8 @@ func _() *int {
// A type parameter may not be embedded in an interface;
// so it can also not be used as a constraint.
func _[A any, B A /* ERROR cannot use a type parameter as constraint */ ]() {}
func _[A any, B, C A /* ERROR cannot use a type parameter as constraint */ ]() {}
// Error messages refer to the type constraint as it appears in the source.
// (No implicit interface should be exposed.)