]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: better error message when using comparable in union
authorRobert Griesemer <gri@golang.org>
Fri, 17 Dec 2021 00:28:38 +0000 (16:28 -0800)
committerRobert Findley <rfindley@google.com>
Mon, 20 Dec 2021 15:13:56 +0000 (15:13 +0000)
This is a port of CL 372674 from types2 to go/types with
minor adjustments for error handling.

For #49602.

Change-Id: I726081325a2ff2d5690d11ddc8a830bbcbd8ab33
Reviewed-on: https://go-review.googlesource.com/c/go/+/372954
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/go/types/testdata/fixedbugs/issue49602.go2 [new file with mode: 0644]
src/go/types/union.go

diff --git a/src/go/types/testdata/fixedbugs/issue49602.go2 b/src/go/types/testdata/fixedbugs/issue49602.go2
new file mode 100644 (file)
index 0000000..208501f
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2021 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 M interface {
+       m()
+}
+
+type C interface {
+       comparable
+}
+
+type _ interface {
+       int | M          // ERROR cannot use p\.M in union \(p\.M contains methods\)
+       int | comparable // ERROR cannot use comparable in union
+       int | C          // ERROR cannot use p\.C in union \(p\.C embeds comparable\)
+}
index 7cd5b2a88be77d9024711aa01992581254a23fb2..9c59279447f58b2ba90fef8712b64ce8193839b3 100644 (file)
@@ -111,7 +111,16 @@ func parseUnion(check *Checker, uexpr ast.Expr) Type {
                        // in the beginning. Embedded interfaces with tilde are excluded above. If we reach
                        // here, we must have at least two terms in the union.
                        if f != nil && !f.typeSet().IsTypeSet() {
-                               check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (interface contains methods)", t)
+                               switch {
+                               case f.typeSet().NumMethods() != 0:
+                                       check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
+                               case t.typ == universeComparable.Type():
+                                       check.error(tlist[i], _InvalidUnion, "cannot use comparable in union")
+                               case f.typeSet().comparable:
+                                       check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
+                               default:
+                                       panic("not a type set but no methods and not comparable")
+                               }
                                continue // don't report another error for t
                        }