]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: expand is only required for *Named types
authorRobert Findley <rfindley@google.com>
Mon, 16 Aug 2021 14:49:10 +0000 (10:49 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 16 Aug 2021 18:43:57 +0000 (18:43 +0000)
This is a port of CL 340749 to go/types.

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

src/go/types/builtins.go
src/go/types/expr.go
src/go/types/named.go
src/go/types/predicates.go
src/go/types/signature.go
src/go/types/type.go
src/go/types/typexpr.go
src/go/types/unify.go
src/go/types/union.go

index a11f395947581848d98860b3ad2105a1cf5d327f..9c772d3844285af6636ed73e17e1723759c39fd9 100644 (file)
@@ -47,7 +47,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
        default:
                // make argument getter
                xlist, _ := check.exprList(call.Args, false)
-               arg = func(x *operand, i int) { *x = *xlist[i]; x.typ = expand(x.typ) }
+               arg = func(x *operand, i int) { *x = *xlist[i] }
                nargs = len(xlist)
                // evaluate first argument, if present
                if nargs > 0 {
index c9a55aa871e2c8131066913f93f3d4d61d24def9..5bb9b7c2809cab21fda9a72213276944099e2262 100644 (file)
@@ -621,7 +621,6 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
 // If x is a constant operand, the returned constant.Value will be the
 // representation of x in this context.
 func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) {
-       target = expand(target)
        if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
                return x.typ, nil, 0
        }
index 020b9827e804488cf7501ee212258b6dab47a8a4..791ab787780e888845fa9c9b97ecba32e97f60f8 100644 (file)
@@ -285,12 +285,3 @@ func (n *Named) expand() {
                n.instance = nil
        }
 }
-
-// expand expands uninstantiated named types and leaves all other types alone.
-// expand does not recurse.
-func expand(typ Type) Type {
-       if t, _ := typ.(*Named); t != nil {
-               t.expand()
-       }
-       return typ
-}
index 5a2c08322fbe1ff2a1c142270e7c60f905d6f352..d7adca1d337c888f4fcf3605f75a0217d3394e58 100644 (file)
@@ -140,10 +140,6 @@ func (p *ifacePair) identical(q *ifacePair) bool {
 
 // For changes to this code the corresponding changes should be made to unifier.nify.
 func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
-       // types must be expanded for comparison
-       x = expand(x)
-       y = expand(y)
-
        if x == y {
                return true
        }
@@ -306,6 +302,8 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
                // Two named types are identical if their type names originate
                // in the same type declaration.
                if y, ok := y.(*Named); ok {
+                       x.expand()
+                       y.expand()
                        // TODO(gri) Why is x == y not sufficient? And if it is,
                        //           we can just return false here because x == y
                        //           is caught in the very beginning of this function.
index 4624b54acb5bc5c31c4c040591902fe61b24159a..f0a9f011eaaa75a22873075014d66ea0d40de9d3 100644 (file)
@@ -198,7 +198,6 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
                // TODO(gri) We should delay rtyp expansion to when we actually need the
                //           receiver; thus all checks here should be delayed to later.
                rtyp, _ := deref(recv.typ)
-               rtyp = expand(rtyp)
 
                // spec: "The receiver type must be of the form T or *T where T is a type name."
                // (ignore invalid types - error was reported before)
@@ -206,6 +205,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
                        var err string
                        switch T := rtyp.(type) {
                        case *Named:
+                               T.expand()
                                // spec: "The type denoted by T is called the receiver base type; it must not
                                // be a pointer or interface type and it must be declared in the same package
                                // as the method."
index c042a819b84154242542f3f4c9277f9a172c76d3..87242ccf62547abe3981304b1e39f762762b2dbd 100644 (file)
@@ -113,7 +113,10 @@ func asInterface(t Type) *Interface {
 }
 
 func asNamed(t Type) *Named {
-       e, _ := expand(t).(*Named)
+       e, _ := t.(*Named)
+       if e != nil {
+               e.expand()
+       }
        return e
 }
 
index 03dd7c26c4f5568824c2849a0d0a69f9d1bbe42f..f14fbe18779e7ae880ef25514d8df9962456ebfb 100644 (file)
@@ -435,8 +435,7 @@ func (check *Checker) instantiatedType(x ast.Expr, targsx []ast.Expr, def *Named
        // make sure we check instantiation works at least once
        // and that the resulting type is valid
        check.later(func() {
-               t := expand(typ)
-               check.validType(t, nil)
+               check.validType(typ, nil)
        })
 
        return typ
index a94a5f35c6add4f8395bc58f4556ec25b2f5281e..0be4d3a62ae611112dc0c746a49a82090c3ccefd 100644 (file)
@@ -226,10 +226,6 @@ func (u *unifier) nifyEq(x, y Type, p *ifacePair) bool {
 // code the corresponding changes should be made here.
 // Must not be called directly from outside the unifier.
 func (u *unifier) nify(x, y Type, p *ifacePair) bool {
-       // types must be expanded for comparison
-       x = expand(x)
-       y = expand(y)
-
        if !u.exact {
                // If exact unification is known to fail because we attempt to
                // match a type name against an unnamed type literal, consider
@@ -433,6 +429,8 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
                //      return x.obj == y.obj
                // }
                if y, ok := y.(*Named); ok {
+                       x.expand()
+                       y.expand()
                        // TODO(gri) This is not always correct: two types may have the same names
                        //           in the same package if one of them is nested in a function.
                        //           Extremely unlikely but we need an always correct solution.
index a0cf33c93874648df626174472b69bc55529efcf..1ba99adaca2c02a65ef7711bd7e9c9af475e32c4 100644 (file)
@@ -71,8 +71,7 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
        // Note: This is a quadratic algorithm, but unions tend to be short.
        check.later(func() {
                for i, t := range terms {
-                       typ := expand(t.typ)
-                       if typ == Typ[Invalid] {
+                       if t.typ == Typ[Invalid] {
                                continue
                        }
 
@@ -88,16 +87,16 @@ func parseUnion(check *Checker, tlist []ast.Expr) Type {
                                }
                        }
 
-                       u := under(typ)
+                       u := under(t.typ)
                        f, _ := u.(*Interface)
                        if t.tilde {
                                if f != nil {
-                                       check.errorf(x, _Todo, "invalid use of ~ (%s is an interface)", typ)
+                                       check.errorf(x, _Todo, "invalid use of ~ (%s is an interface)", t.typ)
                                        continue // don't report another error for t
                                }
 
-                               if !Identical(u, typ) {
-                                       check.errorf(x, _Todo, "invalid use of ~ (underlying type of %s is %s)", typ, u)
+                               if !Identical(u, t.typ) {
+                                       check.errorf(x, _Todo, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
                                        continue // don't report another error for t
                                }
                        }