]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2, go/ast, go/parser: remove support for type lists
authorRobert Findley <rfindley@google.com>
Wed, 27 Oct 2021 15:14:24 +0000 (11:14 -0400)
committerRobert Findley <rfindley@google.com>
Thu, 28 Oct 2021 15:34:22 +0000 (15:34 +0000)
This is a rough port of CL 354131 to go/* libraries, though in practice
I just tried to reconcile any places where the phrase "type list"
occurred in the source. This resulted in adjusting quite a bit more code
than initially expected, including a few lingering cases in the
compiler.

Change-Id: Ie62a9e1aeb831b73931bc4c78bbb6ccb24f53fb0
Reviewed-on: https://go-review.googlesource.com/c/go/+/359135
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>
28 files changed:
src/cmd/compile/internal/types2/interface.go
src/cmd/compile/internal/types2/predicates.go
src/cmd/compile/internal/types2/testdata/check/typeinst2.go2
src/cmd/compile/internal/types2/testdata/examples/types.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go2
src/cmd/gofmt/testdata/typeparams.golden
src/cmd/gofmt/testdata/typeparams.input
src/go/ast/ast.go
src/go/parser/parser.go
src/go/parser/resolver.go
src/go/parser/short_test.go
src/go/parser/testdata/interface.go2
src/go/parser/testdata/linalg.go2
src/go/parser/testdata/resolution/typeparams.go2
src/go/printer/nodes.go
src/go/printer/testdata/generics.golden
src/go/printer/testdata/generics.input
src/go/types/call.go
src/go/types/exprstring.go
src/go/types/exprstring_test.go
src/go/types/interface.go
src/go/types/predicates.go
src/go/types/testdata/check/issues.go2
src/go/types/testdata/check/typeinst2.go2
src/go/types/testdata/examples/constraints.go2
src/go/types/testdata/examples/types.go2
src/go/types/testdata/fixedbugs/issue39711.go2
src/go/types/union.go

index 048fcab024efe9813b8b8adcff775fa0da147742..96c92ccaecd6b2f177338d22f6cd03635672a6c4 100644 (file)
@@ -116,7 +116,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *syntax.InterfaceType
                }
                // f.Name != nil
 
-               // We have a method with name f.Name, or a type of a type list (f.Name.Value == "type").
+               // We have a method with name f.Name.
                name := f.Name.Value
                if name == "_" {
                        if check.conf.CompilerErrorMessages {
index 409715ad9d4479dc24067b7cfd72b37204580de2..380fb6489cf0adc343d93efa00393f7258e3a5c0 100644 (file)
@@ -44,7 +44,7 @@ func isNumeric(typ Type) bool  { return is(typ, IsNumeric) }
 func isString(typ Type) bool   { return is(typ, IsString) }
 
 // Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
-// produce the expected result because a type list that contains both an integer
+// produce the expected result because a type set that contains both an integer
 // and a floating-point type is neither (all) integers, nor (all) floats.
 // Use isIntegerOrFloat instead.
 func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }
index 5529bd093df7c1d4ba3b7fbbdae77736fddcce98..cd56c81bb93f6bcd4633050b0785b207b9a28c83 100644 (file)
@@ -172,7 +172,7 @@ type _ interface {
        ~struct{f int} | ~struct{g int} | ~struct /* ERROR overlapping terms */ {f int}
 }
 
-// Interface type lists can contain any type, incl. *Named types.
+// Interface term lists can contain any type, incl. *Named types.
 // Verify that we use the underlying type to compute the operational type.
 type MyInt int
 func add1[T interface{MyInt}](x T) T {
@@ -184,9 +184,9 @@ func double[T interface{MyInt|MyString}](x T) T {
        return x + x
 }
 
-// Embedding of interfaces with type lists leads to interfaces
-// with type lists that are the intersection of the embedded
-// type lists.
+// Embedding of interfaces with term lists leads to interfaces
+// with term lists that are the intersection of the embedded
+// term lists.
 
 type E0 interface {
        ~int | ~bool | ~string
@@ -277,4 +277,4 @@ func _[T none]() {
         _ = gg[T]
        _ = hh[int]
        _ = hh[T]
-}
\ No newline at end of file
+}
index 72b74cee016a1d37138e5a3c2415f09ce867974a..077fcfdbb76119caf45f104d6751e648347512b7 100644 (file)
@@ -276,8 +276,8 @@ func _() {
 
 // Type parameters are never const types, i.e., it's
 // not possible to declare a constant of type parameter type.
-// (If a type list contains just a single const type, we could
-// allow it, but such type lists don't make much sense in the
+// (If a type set contains just a single const type, we could
+// allow it, but such type sets don't make much sense in the
 // first place.)
 func _[T interface{~int|~float64}]() {
        // not valid
index 85eb0a78fe284a21b464b612bc7efafa8820b3ed..8f3101235410c091910641c928113718e66d2bc4 100644 (file)
@@ -4,10 +4,10 @@
 
 package p
 
-// Do not report a duplicate type error for this type list.
+// Do not report a duplicate type error for this term list.
 // (Check types after interfaces have been completed.)
 type _ interface {
        // TODO(gri) Once we have full type sets we can enable this again.
-       // Fow now we don't permit interfaces in type lists.
+       // Fow now we don't permit interfaces in term lists.
        // type interface{ Error() string }, interface{ String() string }
 }
index f71bd130db4ab075aa5f8296ff6315958688c82f..d57a2ba59b03e6b42ff96656a08c2910c7c2b984 100644 (file)
@@ -21,7 +21,7 @@ func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
 func f[P interface{}](x P)
 func f[P1, P2, P3 interface {
        m1(P1)
-       type P2, P3
+       ~P2 | ~P3
 }](x1 P1, x2 P2, x3 P3) struct{}
 func f[P any](T1[P], T2[P]) T3[P]
 
index 5d4c53d9f767a97e0f9cff8be06b8a2662e9004b..775cf9eb7bdc85242b3af2864803855976e08c5c 100644 (file)
@@ -19,7 +19,7 @@ func f[P any](x P)
 func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
 
 func f[P interface{}](x P)
-func f[P1, P2, P3 interface{ m1(P1); type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{}
+func f[P1, P2, P3 interface{ m1(P1); ~P2|~P3 }](x1 P1, x2 P2, x3 P3) struct{}
 func f[P any](T1[P], T2[P]) T3[P]
 
 func (x T[P]) m()
index 38b6de57d3f98a05bf58b7d630397f7bc2fdc603..bc140473d58d2fbc634a70197b34956d447a3e3a 100644 (file)
@@ -193,14 +193,10 @@ func isDirective(c string) bool {
 // in a signature.
 // Field.Names is nil for unnamed parameters (parameter lists which only contain types)
 // and embedded struct fields. In the latter case, the field name is the type name.
-// Field.Names contains a single name "type" for elements of interface type lists.
-// Types belonging to the same type list share the same "type" identifier which also
-// records the position of that keyword.
-//
 type Field struct {
        Doc     *CommentGroup // associated documentation; or nil
-       Names   []*Ident      // field/method/(type) parameter names, or type "type"; or nil
-       Type    Expr          // field/method/parameter type, type list type; or nil
+       Names   []*Ident      // field/method/(type) parameter names; or nil
+       Type    Expr          // field/method/parameter type; or nil
        Tag     *BasicLit     // field tag; or nil
        Comment *CommentGroup // line comments; or nil
 }
index 999663b98c74550cf588712e25f233c4fa25135e..792fe4141c8367dee1ee8271527d1175946b2f0b 100644 (file)
@@ -1128,18 +1128,6 @@ parseElements:
                        p.expectSemi()
                        comment := p.lineComment
                        list = append(list, &ast.Field{Type: typ, Comment: comment})
-               case p.tok == token.TYPE && p.allowGenerics():
-                       // TODO(rfindley): remove TypeList syntax and refactor the clauses above.
-
-                       // all types in a type list share the same field name "type"
-                       // (since type is a keyword, a Go program cannot have that field name)
-                       name := []*ast.Ident{{NamePos: p.pos, Name: "type"}}
-                       p.next()
-                       // add each type as a field named "type"
-                       for _, typ := range p.parseTypeList() {
-                               list = append(list, &ast.Field{Names: name, Type: typ})
-                       }
-                       p.expectSemi()
                case p.allowGenerics():
                        if t := p.tryIdentOrType(); t != nil {
                                typ := p.embeddedElem(t)
index 527f1691bda6fe295b4eded752e27873f7dee611..54732a7fd6f15eb8e0f39cb1f4acb8d00be7e5e9 100644 (file)
@@ -117,12 +117,6 @@ func (r *resolver) closeLabelScope() {
 
 func (r *resolver) declare(decl, data interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
        for _, ident := range idents {
-               // "type" is used for type lists in interfaces, and is otherwise an invalid
-               // identifier. The 'type' identifier is also artificially duplicated in the
-               // type list, so could cause panics below if we were to proceed.
-               if ident.Name == "type" {
-                       continue
-               }
                assert(ident.Obj == nil, "identifier already declared or resolved")
                obj := ast.NewObj(kind, ident.Name)
                // remember the corresponding declaration for redeclaration
@@ -188,10 +182,9 @@ func (r *resolver) resolve(ident *ast.Ident, collectUnresolved bool) {
        if ident.Obj != nil {
                panic(fmt.Sprintf("%s: identifier %s already declared or resolved", r.handle.Position(ident.Pos()), ident.Name))
        }
-       // '_' and 'type' should never refer to existing declarations: '_' because it
-       // has special handling in the spec, and 'type' because it is a keyword, and
-       // only valid in an interface type list.
-       if ident.Name == "_" || ident.Name == "type" {
+       // '_' should never refer to existing declarations, because it has special
+       // handling in the spec.
+       if ident.Name == "_" {
                return
        }
        for s := r.topScope; s != nil; s = s.Outer {
index bfc6f6714b9f59f0bb31079709f620a184aba0b4..20450bfe8ed362b88d5d12646cc81490ad4cc31f 100644 (file)
@@ -119,8 +119,7 @@ var validWithTParamsOnly = []string{
        `package p; func _(T[P] /* ERROR "missing element type" */ ) T[P]`,
        `package p; type _ struct{ T[P] /* ERROR "missing element type" */ }`,
        `package p; type _ struct{ T[struct /* ERROR "expected expression" */ {a, b, c int}] }`,
-       `package p; type _ interface{type /* ERROR "expected '}', found 'type'" */ int}`,
-       `package p; type _ interface{type /* ERROR "expected '}', found 'type'" */ int, float32; type bool; m(); type string;}`,
+       `package p; type _ interface{int| /* ERROR "expected ';'" */ float32; bool; m(); string;}`,
        `package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2 interface{ I1[int] }`,
        `package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2[T any] interface{ I1[T] }`,
        `package p; type _ interface { f[ /* ERROR "expected ';', found '\['" */ T any]() }`,
index b399d7514889f39c5e8889088dd2c4ada0d2c857..2ed9339c5204d6525b57bf9961bef8ae954c2d99 100644 (file)
@@ -4,16 +4,13 @@
 
 // This file contains test cases for interfaces containing
 // constraint elements.
-//
-// For now, we accept both ordinary type lists and the
-// more complex constraint elements.
 
 package p
 
 type _ interface {
        m()
-       type int
-       type int, string
+       ~int
+       ~int|string
        E
 }
 
@@ -31,7 +28,6 @@ type _ interface {
        T[int, string] | string
        int | ~T[string, struct{}]
        ~int | ~string
-       type bool, int, float64
 }
 
 type _ interface {
index fba0d02eb2fe045370515aaed3b35e0cf8709594..7ccb19c08d3f1ff9dfde94113b618a6c3c627197 100644 (file)
@@ -9,10 +9,10 @@ import "math"
 // Numeric is type bound that matches any numeric type.
 // It would likely be in a constraints package in the standard library.
 type Numeric interface {
-       type int, int8, int16, int32, int64,
-               uint, uint8, uint16, uint32, uint64, uintptr,
-               float32, float64,
-               complex64, complex128
+       ~int|~int8|~int16|~int32|~int64|
+               ~uint|~uint8|~uint16|~uint32|~uint64|~uintptr|
+               ~float32|~float64|
+               ~complex64|~complex128
 }
 
 func DotProduct[T Numeric](s1, s2 []T) T {
@@ -42,14 +42,14 @@ func AbsDifference[T NumericAbs](a, b T) T {
 
 // OrderedNumeric is a type bound that matches numeric types that support the < operator.
 type OrderedNumeric interface {
-       type int, int8, int16, int32, int64,
-               uint, uint8, uint16, uint32, uint64, uintptr,
-               float32, float64
+       ~int|~int8|~int16|~int32|~int64|
+               ~uint|~uint8|~uint16|~uint32|~uint64|~uintptr|
+               ~float32|~float64
 }
 
 // Complex is a type bound that matches the two complex types, which do not have a < operator.
 type Complex interface {
-       type complex64, complex128
+       ~complex64|~complex128
 }
 
 // OrderedAbs is a helper type that defines an Abs method for
index 0ffecd69b5b8a49985b57de39b340d335e865201..8c243afda7eb396dca137458f74a44ce7f2d66ab 100644 (file)
@@ -15,7 +15,7 @@ type Pair /* =@Pair */ [L /* =@L */, R /* =@R */ any] struct {
 var _ = Pair /* @Pair */ [int, string]{}
 
 type Addable /* =@Addable */ interface {
-       type int64, float64
+       ~int64|~float64
 }
 
 func Add /* =@AddDecl */[T /* =@T */ Addable /* @Addable */](l /* =@l */, r /* =@r */ T /* @T */) T /* @T */ {
@@ -30,7 +30,7 @@ type Receiver /* =@Receiver */[P /* =@P */ any] struct {}
 // parameter below.
 func (r /* =@recv */ Receiver /* @Receiver */ [P]) m() P {}
 
-func f /* =@f */[T1 /* =@T1 */ interface{type []T2 /* @T2 */}, T2 /* =@T2 */ any](
+func f /* =@f */[T1 /* =@T1 */ interface{~[]T2 /* @T2 */}, T2 /* =@T2 */ any](
   x /* =@x */ T1 /* @T1 */, T1 /* =@T1_duplicate */ y,  // Note that this is a bug:
                                                         // the duplicate T1 should
                                                        // not be allowed.
index 567b2339b435a0ad3037c2242c833b25bf75fdbd..19d4ab6663d3d0f067a33cef99a375995d2dcfe9 100644 (file)
@@ -471,17 +471,9 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
                                p.expr(f.Type)
                        } else { // interface
                                if len(f.Names) > 0 {
-                                       // type list type or method
-                                       name := f.Names[0] // "type" or method name
+                                       name := f.Names[0] // method name
                                        p.expr(name)
-                                       if name.Name == "type" {
-                                               // type list type
-                                               p.print(blank)
-                                               p.expr(f.Type)
-                                       } else {
-                                               // method
-                                               p.signature(f.Type.(*ast.FuncType)) // don't print "func"
-                                       }
+                                       p.signature(f.Type.(*ast.FuncType)) // don't print "func"
                                } else {
                                        // embedded interface
                                        p.expr(f.Type)
@@ -568,24 +560,10 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
                        p.setComment(f.Doc)
                        p.recordLine(&line)
                        if name != nil {
-                               // type list type or method
-                               if name.Name == "type" {
-                                       // type list type
-                                       if name == prev {
-                                               // type is part of a list of types
-                                               p.print(token.COMMA, blank)
-                                       } else {
-                                               // type starts a new list of types
-                                               p.print(name, blank)
-                                       }
-                                       p.expr(f.Type)
-                                       prev = name
-                               } else {
-                                       // method
-                                       p.expr(name)
-                                       p.signature(f.Type.(*ast.FuncType)) // don't print "func"
-                                       prev = nil
-                               }
+                               // method
+                               p.expr(name)
+                               p.signature(f.Type.(*ast.FuncType)) // don't print "func"
+                               prev = nil
                        } else {
                                // embedded interface
                                p.expr(f.Type)
index 31ab7716dd7b1f7d05b1df670399e952b7b7bba5..3d95eda5b2ac4a56ce79d7837f0766e42d3fe6e0 100644 (file)
@@ -22,7 +22,7 @@ func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
 func f[P interface{}](x P)
 func f[P1, P2, P3 interface {
        m1(P1)
-       type P2, P3
+       ~P2 | ~P3
 }](x1 P1, x2 P2, x3 P3) struct{}
 func f[P any](T1[P], T2[P]) T3[P]
 
@@ -35,14 +35,6 @@ func _() {
        _ = []T[P]{}
 }
 
-// properly format one-line type lists
-// TODO(rfindley): remove support for type lists
-type _ interface{ type a }
-
-type _ interface {
-       type a, b, c
-}
-
 // type constraint literals with elided interfaces
 func _[P ~int, Q int | string]()       {}
 func _[P struct{ f int }, Q *P]()      {}
index 11431c5a0a21119f3c6c05226ebb6d6f347ff73d..746dfdd2358ba987efc0847035ad6f759151e07f 100644 (file)
@@ -20,7 +20,7 @@ func f[P any](x P)
 func f[P1, P2, P3 any](x1 P1, x2 P2, x3 P3) struct{}
 
 func f[P interface{}](x P)
-func f[P1, P2, P3 interface{ m1(P1); type P2, P3 }](x1 P1, x2 P2, x3 P3) struct{}
+func f[P1, P2, P3 interface{ m1(P1); ~P2|~P3 }](x1 P1, x2 P2, x3 P3) struct{}
 func f[P any](T1[P], T2[P]) T3[P]
 
 func (x T[P]) m()
@@ -32,12 +32,6 @@ func _() {
        _ = []T[P]{}
 }
 
-// properly format one-line type lists
-// TODO(rfindley): remove support for type lists
-type _ interface { type a }
-
-type _ interface { type a,b,c }
-
 // type constraint literals with elided interfaces
 func _[P ~int, Q int | string]() {}
 func _[P struct{f int}, Q *P]() {}
index 4731c696197e43f3e111466053764ddcf7534507..6894f1c1821e0184ccbf3888e3848decd9f6380e 100644 (file)
@@ -141,6 +141,7 @@ func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
                                }
                                if t := asInterface(T); t != nil {
                                        if !t.IsMethodSet() {
+                                               // TODO(rfindley): remove the phrase "type list" from this error.
                                                check.errorf(call, _Todo, "cannot use interface %s in conversion (contains type list or is comparable)", T)
                                                break
                                        }
index 06e7a9dcb4435ed529e953e6fd944bb596cc2f3c..aa4f403c1f1e8019ea444d14498469ced4746ce5 100644 (file)
@@ -145,29 +145,8 @@ func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
                writeSigExpr(buf, x)
 
        case *ast.InterfaceType:
-               // separate type list types from method list
-               // TODO(gri) we can get rid of this extra code if writeExprList does the separation
-               var types []ast.Expr
-               var methods []*ast.Field
-               for _, f := range x.Methods.List {
-                       if len(f.Names) > 1 && f.Names[0].Name == "type" {
-                               // type list type
-                               types = append(types, f.Type)
-                       } else {
-                               // method or embedded interface
-                               methods = append(methods, f)
-                       }
-               }
-
                buf.WriteString("interface{")
-               writeFieldList(buf, methods, "; ", true)
-               if len(types) > 0 {
-                       if len(methods) > 0 {
-                               buf.WriteString("; ")
-                       }
-                       buf.WriteString("type ")
-                       writeExprList(buf, types)
-               }
+               writeFieldList(buf, x.Methods.List, "; ", true)
                buf.WriteByte('}')
 
        case *ast.MapType:
index a67f6a978a9509ce8f251041f0e2e92d82a91876..27cd532c97c2715a3de8941774e37f15a36cfefe 100644 (file)
@@ -36,15 +36,8 @@ var testExprs = []testEntry{
        dup("func(int, float32) string"),
        dup("interface{m()}"),
        dup("interface{m() string; n(x int)}"),
-       dup("interface{type int}"),
-
-       // The following exprs do not get formatted correctly: each element in the
-       // type list is printed on a separate line. This is left as a placeholder
-       // until type lists are removed.
-       // TODO(rfindley): remove this once type lists are gone.
-       // dup("interface{type int, float64, string}"),
-       // dup("interface{type int; m()}"),
-       // dup("interface{type int, float64, string; m() string; n(x int)}"),
+       dup("interface{~int}"),
+
        dup("map[string]int"),
        dup("chan E"),
        dup("<-chan E"),
index 3d5573373f1431e62e5cc1123967ca883867d343..c170ed4a6062536cfac25f2c108b42953fac8c06 100644 (file)
@@ -142,9 +142,6 @@ func (t *Interface) String() string   { return TypeString(t, nil) }
 // Implementation
 
 func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
-       var tlist []ast.Expr
-       var tname *ast.Ident // "type" name of first entry in a type list declaration
-
        addEmbedded := func(pos token.Pos, typ Type) {
                ityp.embeddeds = append(ityp.embeddeds, typ)
                if ityp.embedPos == nil {
@@ -158,41 +155,15 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                        addEmbedded(f.Type.Pos(), parseUnion(check, flattenUnion(nil, f.Type)))
                        continue
                }
+               // f.Name != nil
 
-               // We have a method with name f.Names[0], or a type
-               // of a type list (name.Name == "type").
-               // (The parser ensures that there's only one method
-               // and we don't care if a constructed AST has more.)
+               // We have a method with name f.Names[0].
                name := f.Names[0]
                if name.Name == "_" {
                        check.errorf(name, _BlankIfaceMethod, "invalid method name _")
                        continue // ignore
                }
 
-               // TODO(rfindley) Remove type list handling once the parser doesn't accept type lists anymore.
-               if name.Name == "type" {
-                       // Report an error for the first type list per interface
-                       // if we don't allow type lists, but continue.
-                       if !allowTypeLists && tlist == nil {
-                               check.softErrorf(name, _Todo, "use generalized embedding syntax instead of a type list")
-                       }
-                       // For now, collect all type list entries as if it
-                       // were a single union, where each union element is
-                       // of the form ~T.
-                       // TODO(rfindley) remove once we disallow type lists
-                       op := new(ast.UnaryExpr)
-                       op.Op = token.TILDE
-                       op.X = f.Type
-                       tlist = append(tlist, op)
-                       // Report an error if we have multiple type lists in an
-                       // interface, but only if they are permitted in the first place.
-                       if allowTypeLists && tname != nil && tname != name {
-                               check.errorf(name, _Todo, "cannot have multiple type lists in an interface")
-                       }
-                       tname = name
-                       continue
-               }
-
                typ := check.typ(f.Type)
                sig, _ := typ.(*Signature)
                if sig == nil {
@@ -225,13 +196,6 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                ityp.methods = append(ityp.methods, m)
        }
 
-       // type constraints
-       if tlist != nil {
-               // TODO(rfindley): this differs from types2 due to the use of Pos() below,
-               // which should actually be on the ~. Confirm that this position is correct.
-               addEmbedded(tlist[0].Pos(), parseUnion(check, tlist))
-       }
-
        // All methods and embedded elements for this interface are collected;
        // i.e., this interface may be used in a type set computation.
        ityp.complete = true
index a5d4be9bcc4680fc7428a556ce1b504e0ed0a0da..b687c151c7c8a5b5a58d375c3cf9dad137edee7a 100644 (file)
@@ -45,7 +45,7 @@ func isNumeric(typ Type) bool  { return is(typ, IsNumeric) }
 func isString(typ Type) bool   { return is(typ, IsString) }
 
 // Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
-// produce the expected result because a type list that contains both an integer
+// produce the expected result because a type set that contains both an integer
 // and a floating-point type is neither (all) integers, nor (all) floats.
 // Use isIntegerOrFloat instead.
 func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }
index c46a34e2ebc76ab8f73af2dcf68f9f6f516e7ae6..6a93bcc9ac26900c3286453891623516de37cddf 100644 (file)
@@ -53,8 +53,8 @@ func _() {
 }
 
 // When a type parameter is used as an argument to instantiate a parameterized
-// type with a type list constraint, all of the type argument's types in its
-// bound, but at least one (!), must be in the type list of the bound of the
+// type with a type set constraint, all of the type argument's types in its
+// bound, but at least one (!), must be in the type set of the bound of the
 // corresponding parameterized type's type parameter.
 type T1[P interface{~uint}] struct{}
 
@@ -152,7 +152,7 @@ type inf2 /* ERROR illegal cycle */ [T any] struct{ inf2[T] }
 // The implementation of conversions T(x) between integers and floating-point
 // numbers checks that both T and x have either integer or floating-point
 // type. When the type of T or x is a type parameter, the respective simple
-// predicate disjunction in the implementation was wrong because if a type list
+// predicate disjunction in the implementation was wrong because if a term list
 // contains both an integer and a floating-point type, the type parameter is
 // neither an integer or a floating-point number.
 func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
@@ -185,13 +185,13 @@ func _[T interface{}, PT interface{~*T}] (x T) PT {
     return &x
 }
 
-// Indexing of generic types containing type parameters in their type list:
+// Indexing of generic types containing type parameters in their term list:
 func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
         return x[i]
 }
 
 // A generic type inside a function acts like a named type. Its underlying
-// type is itself, its "operational type" is defined by the type list in
+// type is itself, its "operational type" is defined by the term list in
 // the tybe bound, if any.
 func _[T interface{~int}](x T) {
        type myint int
@@ -224,9 +224,9 @@ func _[T interface{ ~func() }](f T) {
        go f()
 }
 
-// We must compare against the underlying type of type list entries
+// We must compare against the underlying type of term list entries
 // when checking if a constraint is satisfied by a type. The under-
-// lying type of each type list entry must be computed after the
+// lying type of each term list entry must be computed after the
 // interface has been instantiated as its typelist may contain a
 // type parameter that was substituted with a defined type.
 // Test case from an (originally) failing example.
index 88913785c8d9429a7da3b6d37eba30d2aa70c968..37d32263d4accba949b5a8871ddce2796ecc8c7c 100644 (file)
@@ -159,10 +159,7 @@ type _ interface {
        ~rune
 }
 
-// Interface type lists may contain each type at most once.
-// (If there are multiple lists, we assume the author intended
-// for them to be all in a single list, and we report the error
-// as well.)
+// Type sets may contain each type at most once.
 type _ interface {
        ~int|~ /* ERROR overlapping terms ~int */ int
        ~int|int /* ERROR overlapping terms int */
@@ -173,7 +170,7 @@ type _ interface {
        ~struct{f int} | ~struct{g int} | ~ /* ERROR overlapping terms */ struct {f int}
 }
 
-// Interface type lists can contain any type, incl. *Named types.
+// Interface term lists can contain any type, incl. *Named types.
 // Verify that we use the underlying type to compute the operational type.
 type MyInt int
 func add1[T interface{MyInt}](x T) T {
@@ -185,9 +182,9 @@ func double[T interface{MyInt|MyString}](x T) T {
        return x + x
 }
 
-// Embedding of interfaces with type lists leads to interfaces
-// with type lists that are the intersection of the embedded
-// type lists.
+// Embedding of interfaces with term lists leads to interfaces
+// with term lists that are the intersection of the embedded
+// term lists.
 
 type E0 interface {
        ~int | ~bool | ~string
index ecc75c1a46f98b7fa7e57fe0d1d8e2517ff9660c..4d7f70313a20ae48cf0afea39d9efe88c4f1f4dc 100644 (file)
@@ -6,18 +6,6 @@
 
 package p
 
-type (
-       // Type lists are processed as unions but an error is reported.
-       // TODO(gri) remove this once the parser doesn't accept type lists anymore.
-       _ interface{
-               type /* ERROR use generalized embedding syntax instead of a type list */ int
-       }
-       _ interface{
-               type /* ERROR use generalized embedding syntax instead of a type list */ int
-               type float32
-       }
-)
-
 type MyInt int
 
 type (
index 807c03238fff206b7c259b1cf9439ab88037b971..367b73120c037fff445a3f335f44c18a6472023f 100644 (file)
@@ -281,8 +281,8 @@ func _() {
 
 // Type parameters are never const types, i.e., it's
 // not possible to declare a constant of type parameter type.
-// (If a type list contains just a single const type, we could
-// allow it, but such type lists don't make much sense in the
+// (If a type set contains just a single const type, we could
+// allow it, but such type sets don't make much sense in the
 // first place.)
 func _[T interface {~int|~float64}]() {
        // not valid
index cf1f90545f6e8026fa53529db85ff47334117277..d85fa03fc433bc77d34c4e16f4fbb923cfee8d32 100644 (file)
@@ -4,10 +4,10 @@
 
 package p
 
-// Do not report a duplicate type error for this type list.
+// Do not report a duplicate type error for this term list.
 // (Check types after interfaces have been completed.)
 type _ interface {
        // TODO(rfindley) Once we have full type sets we can enable this again.
-       // Fow now we don't permit interfaces in type lists.
+       // Fow now we don't permit interfaces in term lists.
        // type interface{ Error() string }, interface{ String() string }
 }
index 88b2a9ff8f074a2c53d73ea054dc5f4f6927090d..c715839315cd1e4402972019e3b6348908a5a3aa 100644 (file)
@@ -78,28 +78,16 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
                                continue
                        }
 
-                       x := tlist[i]
-                       pos := x.Pos()
-                       // We may not know the position of x if it was a typechecker-
-                       // introduced ~T term for a type list entry T. Use the position
-                       // of T instead.
-                       // TODO(rfindley) remove this test once we don't support type lists anymore
-                       if !pos.IsValid() {
-                               if op, _ := x.(*ast.UnaryExpr); op != nil {
-                                       pos = op.X.Pos()
-                               }
-                       }
-
                        u := under(t.typ)
                        f, _ := u.(*Interface)
                        if t.tilde {
                                if f != nil {
-                                       check.errorf(x, _Todo, "invalid use of ~ (%s is an interface)", t.typ)
+                                       check.errorf(tlist[i], _Todo, "invalid use of ~ (%s is an interface)", t.typ)
                                        continue // don't report another error for t
                                }
 
                                if !Identical(u, t.typ) {
-                                       check.errorf(x, _Todo, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
+                                       check.errorf(tlist[i], _Todo, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
                                        continue // don't report another error for t
                                }
                        }
@@ -108,14 +96,14 @@ func parseUnion(check *Checker, tlist []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(atPos(pos), _Todo, "cannot use %s in union (interface contains methods)", t)
+                               check.errorf(tlist[i], _Todo, "cannot use %s in union (interface contains methods)", t)
                                continue // don't report another error for t
                        }
 
                        // Report overlapping (non-disjoint) terms such as
                        // a|a, a|~a, ~a|~a, and ~a|A (where under(A) == a).
                        if j := overlappingTerm(terms[:i], t); j >= 0 {
-                               check.softErrorf(atPos(pos), _Todo, "overlapping terms %s and %s", t, terms[j])
+                               check.softErrorf(tlist[i], _Todo, "overlapping terms %s and %s", t, terms[j])
                        }
                }
        })