]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: avoid duplicate errors for invalid bounds
authorRobert Findley <rfindley@google.com>
Mon, 11 Oct 2021 13:59:40 +0000 (09:59 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 11 Oct 2021 22:34:49 +0000 (22:34 +0000)
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>
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/testdata/examples/typesets.go2

index d427f26b7c75718fbdeb9e96c53c6f24a17239f5..26a16d99179507064ac4725bf8093f54437d3261 100644 (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
                }
        })
index cf01072d8cb06003ea8a8e7a0a5a19fd86c716ff..e19dcf8da378f3e1f4b1748d5a46ec092c057c0e 100644 (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.)