]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] import operand.go changes from dev.go2go
authorRob Findley <rfindley@google.com>
Thu, 7 Jan 2021 15:55:00 +0000 (10:55 -0500)
committerRobert Findley <rfindley@google.com>
Mon, 11 Jan 2021 18:23:01 +0000 (18:23 +0000)
This involved some non-trivial changes from dev.go2go, due to the
refactoring of assignability in master.

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

src/go/types/operand.go

index 3e1ac312d9a5e46d33c1518c3f5cefbd9eb0198e..336babcadcb99dd9d732bd1fdd92709d348f89ac 100644 (file)
@@ -158,7 +158,16 @@ func operandString(x *operand, qf Qualifier) string {
        // <typ>
        if hasType {
                if x.typ != Typ[Invalid] {
-                       buf.WriteString(" of type ")
+                       var intro string
+                       switch {
+                       case isGeneric(x.typ):
+                               intro = " of generic type "
+                       case asTypeParam(x.typ) != nil:
+                               intro = " of type parameter type "
+                       default:
+                               intro = " of type "
+                       }
+                       buf.WriteString(intro)
                        WriteType(&buf, x.typ, qf)
                } else {
                        buf.WriteString(" with invalid type")
@@ -228,20 +237,30 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
                return true, 0
        }
 
-       Vu := V.Underlying()
-       Tu := T.Underlying()
+       Vu := optype(V)
+       Tu := optype(T)
 
        // x is an untyped value representable by a value of type T.
        if isUntyped(Vu) {
-               if t, ok := Tu.(*Basic); ok && x.mode == constant_ {
-                       return representableConst(x.val, check, t, nil), _IncompatibleAssign
+               // TODO(rFindley) synchronize this block of code with types2
+               switch t := Tu.(type) {
+               case *Basic:
+                       if x.mode == constant_ {
+                               return representableConst(x.val, check, t, nil), _IncompatibleAssign
+                       }
+               case *Sum:
+                       return t.is(func(t Type) bool {
+                               // TODO(gri) this could probably be more efficient
+                               ok, _ := x.assignableTo(check, t, reason)
+                               return ok
+                       }), _IncompatibleAssign
                }
                return check.implicitType(x, Tu) != nil, _IncompatibleAssign
        }
        // Vu is typed
 
-       // x's type V and T have identical underlying types and at least one of V or
-       // T is not a named type.
+       // x's type V and T have identical underlying types
+       // and at least one of V or T is not a named type
        if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
                return true, 0
        }