]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: replace optype() with under() in various cases (cleanup)
authorRob Findley <rfindley@google.com>
Fri, 16 Jul 2021 17:03:06 +0000 (13:03 -0400)
committerRobert Findley <rfindley@google.com>
Sat, 17 Jul 2021 01:52:18 +0000 (01:52 +0000)
This is a port of CL 332555 to go/types.

Change-Id: I9b26bba8b605f5bbbd8f0f81fd6651a4a3ff4b57
Reviewed-on: https://go-review.googlesource.com/c/go/+/335111
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/go/types/builtins.go
src/go/types/expr.go
src/go/types/index.go
src/go/types/predicates.go
src/go/types/testdata/check/typeparams.go2
src/go/types/typeset.go

index e976e76cf1da086c34562a78c95c40e3328aab9b..9b2a75458cb6a4146fafca1deccd733569aab6a6 100644 (file)
@@ -337,13 +337,15 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                        return
                }
                var src Type
-               switch t := optype(y.typ).(type) {
+               switch t := under(y.typ).(type) {
                case *Basic:
                        if isString(y.typ) {
                                src = universeByte
                        }
                case *Slice:
                        src = t.elem
+               case *TypeParam:
+                       check.error(x, _Todo, "copy on generic operands not yet implemented")
                }
 
                if dst == nil || src == nil {
@@ -464,12 +466,12 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                var valid func(t Type) bool
                valid = func(t Type) bool {
                        var m int
-                       switch t := optype(t).(type) {
+                       switch t := under(t).(type) {
                        case *Slice:
                                m = 2
                        case *Map, *Chan:
                                m = 1
-                       case *Union:
+                       case *TypeParam:
                                return t.underIs(valid)
                        default:
                                return false
index edd7caf1c93ac8cd349a3defd56fa44c22acb256..46f6e3346311833b325b246dfd41243a7abed78f 100644 (file)
@@ -622,7 +622,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                return x.typ, nil, 0
        }
 
-       switch t := optype(target).(type) {
+       switch t := under(target).(type) {
        case *Basic:
                if x.mode == constant_ {
                        v, code := check.representation(x, t)
@@ -661,7 +661,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                default:
                        return nil, nil, _InvalidUntypedConversion
                }
-       case *Union:
+       case *TypeParam:
                ok := t.underIs(func(t Type) bool {
                        target, _, _ := check.implicitTypeAndValue(x, t)
                        return target != nil
@@ -1151,7 +1151,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                        goto Error
                }
 
-               switch utyp := optype(base).(type) {
+               switch utyp := under(base).(type) {
                case *Struct:
                        if len(e.Elts) == 0 {
                                break
index 036752c7340e428bc6fb21bf6493c9608c3fadc7..b2a5a2e94888017b261a179757b160eb42c787f1 100644 (file)
@@ -199,7 +199,7 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
 
        valid := false
        length := int64(-1) // valid if >= 0
-       switch typ := optype(x.typ).(type) {
+       switch typ := under(x.typ).(type) {
        case *Basic:
                if isString(typ) {
                        if e.Slice3 {
@@ -239,8 +239,8 @@ func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
                valid = true
                // x.typ doesn't change
 
-       case *Union, *TypeParam:
-               check.errorf(x, 0, "generic slice expressions not yet implemented")
+       case *TypeParam:
+               check.errorf(x, _Todo, "generic slice expressions not yet implemented")
                x.mode = invalid
                return
        }
index c3c168647daf5ea5cd34a7f1a3c25ca42c301a4c..c9be12183944fe744445ff94613db21909ad6396 100644 (file)
@@ -25,10 +25,10 @@ func isGeneric(typ Type) bool {
 }
 
 func is(typ Type, what BasicInfo) bool {
-       switch t := optype(typ).(type) {
+       switch t := under(typ).(type) {
        case *Basic:
                return t.info&what != 0
-       case *Union:
+       case *TypeParam:
                return t.underIs(func(typ Type) bool { return is(typ, what) })
        }
        return false
@@ -97,18 +97,19 @@ func comparable(T Type, seen map[Type]bool) bool {
        seen[T] = true
 
        // If T is a type parameter not constrained by any type
-       // list (i.e., it's operational type is the top type),
+       // (i.e., it's operational type is the top type),
        // T is comparable if it has the == method. Otherwise,
        // the operational type "wins". For instance
        //
        //     interface{ comparable; type []byte }
        //
        // is not comparable because []byte is not comparable.
+       // TODO(gri) this code is not 100% correct (see comment for TypeSet.IsComparable)
        if t := asTypeParam(T); t != nil && optype(t) == theTop {
                return t.Bound().IsComparable()
        }
 
-       switch t := optype(T).(type) {
+       switch t := under(T).(type) {
        case *Basic:
                // assume invalid types to be comparable
                // to avoid follow-up errors
@@ -124,24 +125,22 @@ func comparable(T Type, seen map[Type]bool) bool {
                return true
        case *Array:
                return comparable(t.elem, seen)
-       case *Union:
+       case *TypeParam:
                return t.underIs(func(t Type) bool {
                        return comparable(t, seen)
                })
-       case *TypeParam:
-               return t.Bound().IsComparable()
        }
        return false
 }
 
 // hasNil reports whether a type includes the nil value.
 func hasNil(typ Type) bool {
-       switch t := optype(typ).(type) {
+       switch t := under(typ).(type) {
        case *Basic:
                return t.kind == UnsafePointer
        case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
                return true
-       case *Union:
+       case *TypeParam:
                return t.underIs(hasNil)
        }
        return false
index b832e6b760cf26524dfc34535a6d32e89292f5f4..0e3795724b3a00f6aba5c2a33d1ffab17111b94b 100644 (file)
@@ -119,7 +119,7 @@ func _[T interface{ [10]int | *[20]int | []int }](x T, i int) { _ = x[i]; _ = x[
 // slicing
 // TODO(gri) implement this
 
-func _[T interface{ ~string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] }
+func _[T interface{ ~string }] (x T, i, j, k int) { _ = x /* ERROR generic slice expressions not yet implemented */ [i:j:k] }
 
 // len/cap built-ins
 
index 3fe48892fe9c04b5f4b07b700ba714f9d4f4f902..d8fe42f7d08f10f8171c93d17024558b5f4db6fd 100644 (file)
@@ -28,6 +28,7 @@ func (s *TypeSet) IsTop() bool { return len(s.methods) == 0 && s.types == nil }
 func (s *TypeSet) IsMethodSet() bool { return s.types == nil && !s.IsComparable() }
 
 // IsComparable reports whether each type in the set is comparable.
+// TODO(gri) this is not correct - there may be s.types values containing non-comparable types
 func (s *TypeSet) IsComparable() bool {
        _, m := s.LookupMethod(nil, "==")
        return m != nil