]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile/internal/types2: expand is only required for *Named...
authorRobert Griesemer <gri@golang.org>
Sun, 8 Aug 2021 19:37:35 +0000 (12:37 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 10 Aug 2021 01:20:32 +0000 (01:20 +0000)
Now that the pointer identity for a *Named type doesn't change
anymore when going from lazy instantiated to actually instantiated
(= expanded) state, expand() only needs to be called when we deal
with *Named types and only if we care about a *Named type's internals.

Remove the expand function and respective calls for all types and
replace with specific t.expand() method calls where t is a *Named.

Change-Id: If82299360d60108b00adc4013b29399aec90b940
Reviewed-on: https://go-review.googlesource.com/c/go/+/340749
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/builtins.go
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/named.go
src/cmd/compile/internal/types2/predicates.go
src/cmd/compile/internal/types2/signature.go
src/cmd/compile/internal/types2/type.go
src/cmd/compile/internal/types2/typexpr.go
src/cmd/compile/internal/types2/unify.go
src/cmd/compile/internal/types2/union.go

index eafe6e9eb823063633eedf153edbe14e2c84738d..da2dcf54aa36537814f05015ea4db6f4f9a40949 100644 (file)
@@ -46,7 +46,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
        default:
                // make argument getter
                xlist, _ := check.exprList(call.ArgList, 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 008c2446fcdd18bcec1f3cf4397cda8b338b2c9e..3c2b10cd7e0784128d66c3ef70659343ff61cad7 100644 (file)
@@ -682,7 +682,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 14e073bfaeb39056c916067ac2e678ccb0ccb969..e09966048197f1516d3a42e89b623413c9a2970d 100644 (file)
@@ -279,12 +279,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 afef488b9642c0a5bcd9db5a9652f39c519f242e..1541b3f416dafb56e69335549a4792fdf16c586b 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 14112462e18e14aaca84f935cb3706be5c346eb6..48b11b289cdfb1fb9cecc4dc06efed180e41395a 100644 (file)
@@ -208,7 +208,6 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
                // 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)
@@ -216,6 +215,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
                        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 7ae2db3412d8ead5757e07d08959d6a7f8e444ef..637829613b1915e296dd41d325954fa14c616cd6 100644 (file)
@@ -114,7 +114,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 fa4a1638b6ce0eef31b424a6708a97556f9b53e6..6a9eacd31df9931ecbe98a4bcc991dd5bdd6df75 100644 (file)
@@ -446,8 +446,7 @@ func (check *Checker) instantiatedType(x syntax.Expr, targsx []syntax.Expr, def
        // 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 75b9a121979800f76c99ae96dd4935a48b5dd82a..ae81382fb0ebc554ea1c8b432bb50142ffafb0eb 100644 (file)
@@ -229,10 +229,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
@@ -436,6 +432,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 85aa3d91040ab8673eaaa3cac3b04b0b6222dff1..f61c37a6afd97f760ad950c155284eb8f36da812 100644 (file)
@@ -68,8 +68,7 @@ func parseUnion(check *Checker, tlist []syntax.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
                        }
 
@@ -85,16 +84,16 @@ func parseUnion(check *Checker, tlist []syntax.Expr) Type {
                                }
                        }
 
-                       u := under(typ)
+                       u := under(t.typ)
                        f, _ := u.(*Interface)
                        if t.tilde {
                                if f != nil {
-                                       check.errorf(x, "invalid use of ~ (%s is an interface)", typ)
+                                       check.errorf(x, "invalid use of ~ (%s is an interface)", t.typ)
                                        continue // don't report another error for t
                                }
 
-                               if !Identical(u, typ) {
-                                       check.errorf(x, "invalid use of ~ (underlying type of %s is %s)", typ, u)
+                               if !Identical(u, t.typ) {
+                                       check.errorf(x, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
                                        continue // don't report another error for t
                                }
                        }