]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: roll-forward removal of asX converters
authorRobert Findley <rfindley@google.com>
Mon, 8 Nov 2021 18:08:59 +0000 (18:08 +0000)
committerRobert Findley <rfindley@google.com>
Tue, 9 Nov 2021 16:55:47 +0000 (16:55 +0000)
This CL reverts CL 361964, rolling forward the original CL 362254 with a
fix for re-entrant expansion via type hashing (compare patchsets 1 and
2).

Change-Id: I62869e50e919f42eb8d6fef5b0d7a5ec8960bd84
Reviewed-on: https://go-review.googlesource.com/c/go/+/362118
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

13 files changed:
src/cmd/compile/internal/types2/assignments.go
src/cmd/compile/internal/types2/builtins.go
src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/context.go
src/cmd/compile/internal/types2/conversions.go
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/index.go
src/cmd/compile/internal/types2/lookup.go
src/cmd/compile/internal/types2/predicates.go
src/cmd/compile/internal/types2/sizes.go
src/cmd/compile/internal/types2/type.go
src/cmd/compile/internal/types2/typestring.go
src/cmd/compile/internal/types2/typexpr.go

index bfc55786830cb88dad7d2927820c10b0841802e9..609d7d0962e6cbf594a148c6550a8c6a8ec32425 100644 (file)
@@ -71,7 +71,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
        // x.typ is typed
 
        // A generic (non-instantiated) function value cannot be assigned to a variable.
-       if sig := asSignature(x.typ); sig != nil && sig.TypeParams().Len() > 0 {
+       if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
                check.errorf(x, "cannot use generic function %s without instantiation in %s", x, context)
        }
 
index ade4c0a49f2677d4acf2f9a499545cbaf05f746f..916aed40b32f094fb20ba4c382919cfcc7a9eefa 100644 (file)
@@ -294,7 +294,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                // (applyTypeFunc never calls f with a type parameter)
                f := func(typ Type) Type {
                        assert(asTypeParam(typ) == nil)
-                       if t := asBasic(typ); t != nil {
+                       if t, _ := under(typ).(*Basic); t != nil {
                                switch t.kind {
                                case Float32:
                                        return Typ[Complex64]
@@ -418,7 +418,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                // (applyTypeFunc never calls f with a type parameter)
                f := func(typ Type) Type {
                        assert(asTypeParam(typ) == nil)
-                       if t := asBasic(typ); t != nil {
+                       if t, _ := under(typ).(*Basic); t != nil {
                                switch t.kind {
                                case Complex64:
                                        return Typ[Float32]
@@ -704,7 +704,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                        return
                }
 
-               typ := asPointer(x.typ)
+               typ, _ := under(x.typ).(*Pointer)
                if typ == nil {
                        check.errorf(x, invalidArg+"%s is not a pointer", x)
                        return
@@ -894,7 +894,7 @@ func makeSig(res Type, args ...Type) *Signature {
 // otherwise it returns typ.
 func arrayPtrDeref(typ Type) Type {
        if p, ok := typ.(*Pointer); ok {
-               if a := asArray(p.base); a != nil {
+               if a, _ := under(p.base).(*Array); a != nil {
                        return a
                }
        }
index 74edd4d4429d891fdbc9e69e5a9883226e795ed9..3a571285c1d64fbdbb11cf4133eb142170af9e76 100644 (file)
@@ -132,7 +132,7 @@ func (check *Checker) callExpr(x *operand, call *syntax.CallExpr) exprKind {
                case 1:
                        check.expr(x, call.ArgList[0])
                        if x.mode != invalid {
-                               if t := asInterface(T); t != nil {
+                               if t, _ := under(T).(*Interface); t != nil {
                                        if !t.IsMethodSet() {
                                                check.errorf(call, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
                                                break
index a8f859124387a99ba3ed43304d5db61761bb6d5b..f6137eea43588a6419debff4afe8057231228a02 100644 (file)
@@ -39,6 +39,9 @@ func (ctxt *Context) TypeHash(typ Type, targs []Type) string {
        var buf bytes.Buffer
 
        h := newTypeHasher(&buf, ctxt)
+       // Caution: don't use asNamed here. TypeHash may be called for unexpanded
+       // types. We don't need anything other than name and type arguments below,
+       // which do not require expansion.
        if named, _ := typ.(*Named); named != nil && len(targs) > 0 {
                // Don't use WriteType because we need to use the provided targs
                // and not any targs that might already be with the *Named type.
index ccabbaf0d740d751fd448066876171508410342a..dd89f297623f1dbb30a7bed757661cbefb9c7d3d 100644 (file)
@@ -18,7 +18,7 @@ func (check *Checker) conversion(x *operand, T Type) {
        constArg := x.mode == constant_
 
        constConvertibleTo := func(T Type, val *constant.Value) bool {
-               switch t := asBasic(T); {
+               switch t, _ := under(T).(*Basic); {
                case t == nil:
                        // nothing to do
                case representableConst(x.val, check, t, val):
@@ -173,9 +173,9 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
 
        // "V a slice, T is a pointer-to-array type,
        // and the slice and array types have identical element types."
-       if s := asSlice(V); s != nil {
-               if p := asPointer(T); p != nil {
-                       if a := asArray(p.Elem()); a != nil {
+       if s, _ := under(V).(*Slice); s != nil {
+               if p, _ := under(T).(*Pointer); p != nil {
+                       if a, _ := under(p.Elem()).(*Array); a != nil {
                                if Identical(s.Elem(), a.Elem()) {
                                        if check == nil || check.allowVersion(check.pkg, 1, 17) {
                                                return true
@@ -262,26 +262,27 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
 // use the toT convenience converters in the predicates below.
 
 func isUintptr(typ Type) bool {
-       t := asBasic(typ)
+       t, _ := under(typ).(*Basic)
        return t != nil && t.kind == Uintptr
 }
 
 func isUnsafePointer(typ Type) bool {
-       // TODO(gri): Is this asBasic(typ) instead of typ.(*Basic) correct?
+       // TODO(gri): Is this under(typ).(*Basic) instead of typ.(*Basic) correct?
        //            (The former calls under(), while the latter doesn't.)
        //            The spec does not say so, but gc claims it is. See also
        //            issue 6326.
-       t := asBasic(typ)
+       t, _ := under(typ).(*Basic)
        return t != nil && t.kind == UnsafePointer
 }
 
 func isPointer(typ Type) bool {
-       return asPointer(typ) != nil
+       _, ok := under(typ).(*Pointer)
+       return ok
 }
 
 func isBytesOrRunes(typ Type) bool {
-       if s := asSlice(typ); s != nil {
-               t := asBasic(s.elem)
+       if s, _ := under(typ).(*Slice); s != nil {
+               t, _ := under(s.elem).(*Basic)
                return t != nil && (t.kind == Byte || t.kind == Rune)
        }
        return false
index d24532d780d26ceea91c16bebb275c6922d710c8..8125fba7170d0d53701c8b4631de4a8f81a1b49d 100644 (file)
@@ -116,7 +116,7 @@ func (check *Checker) overflow(x *operand) {
        // x.typ cannot be a type parameter (type
        // parameters cannot be constant types).
        if isTyped(x.typ) {
-               check.representable(x, asBasic(x.typ))
+               check.representable(x, under(x.typ).(*Basic))
                return
        }
 
@@ -617,7 +617,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
        // If the new type is not final and still untyped, just
        // update the recorded type.
        if !final && isUntyped(typ) {
-               old.typ = asBasic(typ)
+               old.typ = under(typ).(*Basic)
                check.untyped[x] = old
                return
        }
@@ -1394,7 +1394,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
                                        duplicate := false
                                        // if the key is of interface type, the type is also significant when checking for duplicates
                                        xkey := keyVal(x.val)
-                                       if asInterface(utyp.key) != nil {
+                                       if IsInterface(utyp.key) {
                                                for _, vtyp := range visited[xkey] {
                                                        if Identical(vtyp, x.typ) {
                                                                duplicate = true
index 67110704e97f0d79d197b62f79ea3dd0181a9167..f09667453616644141f816106b6cc685f5d17057 100644 (file)
@@ -34,7 +34,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                return false
 
        case value:
-               if sig := asSignature(x.typ); sig != nil && sig.TypeParams().Len() > 0 {
+               if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
                        // function instantiation
                        return true
                }
@@ -72,7 +72,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                x.typ = typ.elem
 
        case *Pointer:
-               if typ := asArray(typ.base); typ != nil {
+               if typ, _ := under(typ.base).(*Array); typ != nil {
                        valid = true
                        length = typ.len
                        x.mode = variable
@@ -120,7 +120,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                                        mode = value
                                }
                        case *Pointer:
-                               if t := asArray(t.base); t != nil {
+                               if t, _ := under(t.base).(*Array); t != nil {
                                        l = t.len
                                        e = t.elem
                                }
@@ -245,7 +245,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
                x.typ = &Slice{elem: u.elem}
 
        case *Pointer:
-               if u := asArray(u.base); u != nil {
+               if u, _ := under(u.base).(*Array); u != nil {
                        valid = true
                        length = u.len
                        x.typ = &Slice{elem: u.elem}
index e0fd74482ab04307272fb20b972e6a1811cc8ac4..061240059030b8f5d94a4f148449d0da3b625d63 100644 (file)
@@ -122,7 +122,6 @@ func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
                                seen[named] = true
 
                                // look for a matching attached method
-                               named.resolve(nil)
                                if i, m := lookupMethod(named.methods, pkg, name); m != nil {
                                        // potential match
                                        // caution: method may not have a proper signature yet
@@ -306,7 +305,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
                return
        }
 
-       if ityp := asInterface(V); ityp != nil {
+       if ityp, _ := under(V).(*Interface); ityp != nil {
                // TODO(gri) the methods are sorted - could do this more efficiently
                for _, m := range T.typeSet().methods {
                        _, f := ityp.typeSet().LookupMethod(m.pkg, m.name)
@@ -417,7 +416,7 @@ func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Fun
        // no static check is required if T is an interface
        // spec: "If T is an interface type, x.(T) asserts that the
        //        dynamic type of x implements the interface T."
-       if asInterface(T) != nil && !forceStrict {
+       if IsInterface(T) && !forceStrict {
                return
        }
        return check.missingMethod(T, V, false)
@@ -435,8 +434,8 @@ func deref(typ Type) (Type, bool) {
 // derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
 // (named or unnamed) struct and returns its base. Otherwise it returns typ.
 func derefStructPtr(typ Type) Type {
-       if p := asPointer(typ); p != nil {
-               if asStruct(p.base) != nil {
+       if p, _ := under(typ).(*Pointer); p != nil {
+               if _, ok := under(p.base).(*Struct); ok {
                        return p.base
                }
        }
index 7fbb91eb61256495fc20903937b41a4fb7c417fa..8d676ed8f686f2e7985fed4606fac7f9d784d06d 100644 (file)
@@ -72,7 +72,7 @@ func hasName(t Type) bool {
 // are not fully set up.
 func isTyped(t Type) bool {
        // isTyped is called with types that are not fully
-       // set up. Must not call asBasic()!
+       // set up. Must not call under()!
        b, _ := t.(*Basic)
        return b == nil || b.info&IsUntyped == 0
 }
@@ -84,7 +84,8 @@ func isUntyped(t Type) bool {
 
 // IsInterface reports whether t is an interface type.
 func IsInterface(t Type) bool {
-       return asInterface(t) != nil
+       _, ok := under(t).(*Interface)
+       return ok
 }
 
 // isTypeParam reports whether t is a type parameter.
index 6a3d19d8eaf293971266e4424ab57e97698092b1..609b6f585eb584586d98b9b7b296e296e7fb5d77 100644 (file)
@@ -243,7 +243,7 @@ func (conf *Config) offsetsof(T *Struct) []int64 {
 func (conf *Config) offsetof(typ Type, index []int) int64 {
        var o int64
        for _, i := range index {
-               s := asStruct(typ)
+               s := under(typ).(*Struct)
                o += conf.offsetsof(s)[i]
                typ = s.fields[i].typ
        }
index 300c81f5fac84a6afd4004bbdb51329e160e966f..d1655c55f896101c9e6aabd5761fa7fc84207d1a 100644 (file)
@@ -27,45 +27,8 @@ func under(t Type) Type {
        return t
 }
 
-// Convenience converters
-
-func asBasic(t Type) *Basic {
-       u, _ := under(t).(*Basic)
-       return u
-}
-
-func asArray(t Type) *Array {
-       u, _ := under(t).(*Array)
-       return u
-}
-
-func asSlice(t Type) *Slice {
-       u, _ := under(t).(*Slice)
-       return u
-}
-
-func asStruct(t Type) *Struct {
-       u, _ := under(t).(*Struct)
-       return u
-}
-
-func asPointer(t Type) *Pointer {
-       u, _ := under(t).(*Pointer)
-       return u
-}
-
-func asSignature(t Type) *Signature {
-       u, _ := under(t).(*Signature)
-       return u
-}
-
-func asInterface(t Type) *Interface {
-       u, _ := under(t).(*Interface)
-       return u
-}
-
 // If the argument to asNamed, or asTypeParam is of the respective type
-// (possibly after expanding resolving a *Named type), these methods return that type.
+// (possibly after resolving a *Named type), these methods return that type.
 // Otherwise the result is nil.
 
 func asNamed(t Type) *Named {
index f18a32016f77fa028374bb2cd30cd151411e28c8..f151f47a5ed4ba7291256c49bc82ac3b1ef1382b 100644 (file)
@@ -361,7 +361,7 @@ func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
                                } else {
                                        // special case:
                                        // append(s, "foo"...) leads to signature func([]byte, string...)
-                                       if t := asBasic(typ); t == nil || t.kind != String {
+                                       if t, _ := under(typ).(*Basic); t == nil || t.kind != String {
                                                w.error("expected string type")
                                                continue
                                        }
index dcd7cfebe829712cae03211787ed16d21a72776d..a08e4727033f046828d452dfc63ae6d0a690591e 100644 (file)
@@ -148,7 +148,7 @@ func (check *Checker) varType(e syntax.Expr) Type {
        // are in the middle of type-checking parameter declarations that might belong to
        // interface methods. Delay this check to the end of type-checking.
        check.later(func() {
-               if t := asInterface(typ); t != nil {
+               if t, _ := under(typ).(*Interface); t != nil {
                        pos := syntax.StartPos(e)
                        tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
                        if !tset.IsMethodSet() {