]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] all: merge master (690a8c3) into dev.typeparams
authorCherry Mui <cherryyz@google.com>
Tue, 18 May 2021 18:49:21 +0000 (14:49 -0400)
committerCherry Mui <cherryyz@google.com>
Tue, 18 May 2021 18:49:21 +0000 (14:49 -0400)
Merge List:

+ 2021-05-18 690a8c3fb1 make.bash: fix misuse of continue
+ 2021-05-18 8b0901fd32 doc/go1.17: fix typo "avoding" -> "avoiding"
+ 2021-05-18 5e191f8f48 time: rewrite the documentation for layout strings
+ 2021-05-17 bfe3573d58 go/token: correct the interval notation used in some panic messages
+ 2021-05-17 a2c07a9a1a all: update golang.org/x/net to latest
+ 2021-05-17 b9b2bed893 syscall: some containers may fail syscall.TestSetuidEtc
+ 2021-05-17 b1aff42900 cmd/go: don't print 'go get' deprecation notices in the main module
+ 2021-05-17 bade680867 runtime/cgo: fix crosscall2 on ppc64x
+ 2021-05-15 ce92a2023c cmd/go: error out of 'go mod tidy' if the go version is newer than supported
+ 2021-05-14 02699f810a runtime: mark osyield nosplit on OpenBSD
+ 2021-05-14 3d324f127d net/http: prevent infinite wait during TestMissingStatusNoPanic
+ 2021-05-14 0eb38f2b16 cmd/go/internal/load: override Package.Root in module mode
+ 2021-05-14 a938e52986 cmd/go: fix a portability issue in the cd script command
+ 2021-05-14 d137b74539 cmd/go: fix spacing in help text of -overlay flag
+ 2021-05-14 c925e1546e cmd/internal/obj/arm64: disable AL and NV for some condition operation instructions
+ 2021-05-14 12d383c7c7 debug/macho: fix a typo in macho.go
+ 2021-05-14 3a0453514a all: fix spelling
+ 2021-05-13 b4833f7c06 cmd/link: always mark runtime.unreachableMethod symbol
+ 2021-05-13 92c189f211 cmd/link: resolve ABI alias for runtime.unreachableMethod
+ 2021-05-13 7a7624a3fa cmd/go: permit .tbd files as a linker flag
+ 2021-05-13 cde2d857fe cmd/go: be less strict about go version syntax in dependency go.mod files
+ 2021-05-13 2a61b3c590 regexp: fix repeat of preferred empty match
+ 2021-05-13 fd4631e24f cmd/compile/internal/dwarfgen: fix DWARF param DIE ordering
+ 2021-05-13 a63cded5e4 debug/dwarf: delay array type fixup to handle type cycles
+ 2021-05-13 0fa2302ee5 cmd/vendor: update golang.org/x/sys to latest
+ 2021-05-13 2c76a6f7f8 all: add //go:build lines to assembly files
+ 2021-05-12 6db7480f59 cmd/go/internal/modload: in updateLazyRoots, do not require the main module explicitly
+ 2021-05-12 f93b951f33 cmd/compile/abi-internal.md: fix table format
+ 2021-05-12 3b321a9d12 cmd/compile: add arch-specific inlining for runtime.memmove
+ 2021-05-12 07ff596404 runtime/internal/atomic: add LSE atomics instructions to arm64
+ 2021-05-12 03886707f9 runtime: fix handling of SPWRITE functions in traceback
+ 2021-05-12 e03383a2e2 cmd/link: check mmap error
+ 2021-05-12 af0f8c149e cmd/link: don't cast end address to int32
+ 2021-05-12 485474d204 cmd/go/testdata/script: fix test failing on nocgo builders
+ 2021-05-12 1a0ea1a08b runtime: fix typo in proc.go
+ 2021-05-11 9995c6b50a cmd/go: ignore implicit imports when the -find flag is set

Change-Id: I843fe029b8ac09424a83e8a4e8bdcc86edd40603

17 files changed:
codereview.cfg
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/noder/expr.go
src/cmd/compile/internal/noder/stencil.go
src/cmd/compile/internal/noder/types.go
src/cmd/compile/internal/types/type.go
src/cmd/compile/internal/types2/api_test.go
src/cmd/compile/internal/types2/check.go
src/cmd/compile/internal/types2/type.go
src/cmd/compile/internal/types2/types_test.go
src/cmd/compile/internal/types2/typestring.go
src/cmd/compile/internal/types2/typestring_test.go
src/go/constant/kind_string.go [new file with mode: 0644]
src/go/constant/value.go
src/runtime/os_freebsd2.go
src/runtime/os_freebsd_amd64.go
test/typeparam/issue45817.go [new file with mode: 0644]

index 77a74f108eae362626abcdbfcf41ddb9a33b02cd..1f58fdbeb2139bb9debfc5c6bc7715af5b403150 100644 (file)
@@ -1 +1,2 @@
-branch: master
+branch: dev.typeparams
+parent-branch: master
index f70645f07913f8c309023d0fc84208d8e09b85b3..9ea8b619653a4907c29f6516c28e26bd8d7bae48 100644 (file)
@@ -494,8 +494,13 @@ func NewNameOffsetExpr(pos src.XPos, name *Name, offset int64, typ *types.Type)
 // A SelectorExpr is a selector expression X.Sel.
 type SelectorExpr struct {
        miniExpr
-       X         Node
-       Sel       *types.Sym
+       X Node
+       // Sel is the name of the field or method being selected, without (in the
+       // case of methods) any preceding type specifier. If the field/method is
+       // exported, than the Sym uses the local package regardless of the package
+       // of the containing type.
+       Sel *types.Sym
+       // The actual selected field - may not be filled in until typechecking.
        Selection *types.Field
        Prealloc  *Name // preallocated storage for OCALLPART, if any
 }
index c7695ed920435291bab7c64a0cbfdfb08b8b8a7e..b7f7a34953a81c707728cc2968fc70abdd90c6ea 100644 (file)
@@ -266,7 +266,7 @@ func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.Selecto
                                recvType2 = recvType2Base
                                // method is the generic method associated with the gen type
                                method := g.obj(types2.AsNamed(recvType2).Method(last))
-                               n = ir.NewSelectorExpr(pos, ir.OCALLPART, x, method.Sym())
+                               n = ir.NewSelectorExpr(pos, ir.OCALLPART, x, typecheck.Lookup(expr.Sel.Value))
                                n.(*ir.SelectorExpr).Selection = types.NewField(pos, method.Sym(), method.Type())
                                n.(*ir.SelectorExpr).Selection.Nname = method
                                typed(method.Type(), n)
index 3ebc8dff6d84322d2d5c2379e9497a87ebb1d73b..adcea2c087de627c15881081ce8ca353c555e65f 100644 (file)
@@ -87,19 +87,20 @@ func (g *irgen) stencil() {
                        call := n.(*ir.CallExpr)
                        inst := call.X.(*ir.InstExpr)
                        st := g.getInstantiationForNode(inst)
-                       // Replace the OFUNCINST with a direct reference to the
-                       // new stenciled function
-                       call.X = st.Nname
                        if inst.X.Op() == ir.OCALLPART {
-                               // When we create an instantiation of a method
-                               // call, we make it a function. So, move the
-                               // receiver to be the first arg of the function
-                               // call.
-                               withRecv := make([]ir.Node, len(call.Args)+1)
-                               dot := inst.X.(*ir.SelectorExpr)
-                               withRecv[0] = dot.X
-                               copy(withRecv[1:], call.Args)
-                               call.Args = withRecv
+                               // Replace the OFUNCINST with the selector
+                               // expression, and update the selector expression
+                               // to refer to the new stenciled function.
+                               call.X = inst.X
+                               se := call.X.(*ir.SelectorExpr)
+                               se.Selection = types.NewField(se.Pos(), se.Sel, st.Type())
+                               se.Selection.Nname = st.Nname
+                               se.SetOp(ir.ODOTMETH)
+                               se.SetType(st.Type())
+                       } else {
+                               // Replace the OFUNCINST with a direct reference to the
+                               // new stenciled function
+                               call.X = st.Nname
                        }
                        // Transform the Call now, which changes OCALL
                        // to OCALLFUNC and does typecheckaste/assignconvfn.
@@ -112,14 +113,30 @@ func (g *irgen) stencil() {
                // EditChildren rather than Visit), where we actually change the
                // OFUNCINST node to an ONAME for the instantiated function.
                // EditChildren is more expensive than Visit, so we only do this
-               // in the infrequent case of an OFUNCINSt without a corresponding
+               // in the infrequent case of an OFUNCINST without a corresponding
                // call.
                if foundFuncInst {
                        var edit func(ir.Node) ir.Node
                        edit = func(x ir.Node) ir.Node {
                                if x.Op() == ir.OFUNCINST {
-                                       st := g.getInstantiationForNode(x.(*ir.InstExpr))
-                                       return st.Nname
+                                       // inst.X is either a function name node
+                                       // or a selector expression for a method.
+                                       inst := x.(*ir.InstExpr)
+                                       st := g.getInstantiationForNode(inst)
+                                       modified = true
+                                       if inst.X.Op() == ir.ONAME {
+                                               return st.Nname
+                                       }
+                                       assert(inst.X.Op() == ir.OCALLPART)
+
+                                       // Return a new selector expression referring
+                                       // to the newly stenciled function.
+                                       oldse := inst.X.(*ir.SelectorExpr)
+                                       newse := ir.NewSelectorExpr(oldse.Pos(), ir.OCALLPART, oldse.X, oldse.Sel)
+                                       newse.Selection = types.NewField(oldse.Pos(), st.Sym(), st.Type())
+                                       newse.Selection.Nname = st
+                                       typed(inst.Type(), newse)
+                                       return newse
                                }
                                ir.EditChildren(x, edit)
                                return x
@@ -149,13 +166,13 @@ func (g *irgen) instantiateMethods() {
                baseSym := typ.Sym().Pkg.Lookup(genericTypeName(typ.Sym()))
                baseType := baseSym.Def.(*ir.Name).Type()
                for j, m := range typ.Methods().Slice() {
-                       name := m.Nname.(*ir.Name)
                        targs := make([]ir.Node, len(typ.RParams()))
                        for k, targ := range typ.RParams() {
                                targs[k] = ir.TypeNode(targ)
                        }
                        baseNname := baseType.Methods().Slice()[j].Nname.(*ir.Name)
-                       name.Func = g.getInstantiation(baseNname, targs, true)
+                       f := g.getInstantiation(baseNname, targs, true)
+                       m.Nname = f.Nname
                }
        }
        g.instTypeList = nil
@@ -299,15 +316,25 @@ func (g *irgen) genericSubst(newsym *types.Sym, nameNode *ir.Name, targs []ir.No
                newf.Dcl[i] = subst.node(n).(*ir.Name)
        }
 
-       // Ugly: we have to insert the Name nodes of the parameters/results into
+       // Replace the types in the function signature.
+       // Ugly: also, we have to insert the Name nodes of the parameters/results into
        // the function type. The current function type has no Nname fields set,
        // because it came via conversion from the types2 type.
        oldt := nameNode.Type()
-       // We also transform a generic method type to the corresponding
-       // instantiated function type where the receiver is the first parameter.
-       newt := types.NewSignature(oldt.Pkg(), nil, nil,
-               subst.fields(ir.PPARAM, append(oldt.Recvs().FieldSlice(), oldt.Params().FieldSlice()...), newf.Dcl),
-               subst.fields(ir.PPARAMOUT, oldt.Results().FieldSlice(), newf.Dcl))
+       dcl := newf.Dcl
+       var newrecv *types.Field
+       if oldt.Recv() != nil {
+               newrecv = subst.fields(ir.PPARAM, oldt.Recvs().FieldSlice(), dcl)[0]
+               if newrecv.Nname != nil {
+                       // If we found the receiver in the dcl list, then skip it
+                       // when we scan for the remaining params below.
+                       assert(newrecv.Nname == dcl[0])
+                       dcl = dcl[1:]
+               }
+       }
+       newt := types.NewSignature(oldt.Pkg(), newrecv, nil,
+               subst.fields(ir.PPARAM, oldt.Params().FieldSlice(), dcl),
+               subst.fields(ir.PPARAMOUT, oldt.Results().FieldSlice(), dcl))
 
        newf.Nname.SetType(newt)
        ir.MarkFunc(newf.Nname)
index 8680559a412970277e2513fe6d1620a55d4393cc..8a2c023a1a3627237e01e5a4a032acad81fc75be 100644 (file)
@@ -204,18 +204,15 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
                return types.NewInterface(g.tpkg(typ), append(embeddeds, methods...))
 
        case *types2.TypeParam:
-               tp := types.NewTypeParam(g.tpkg(typ))
                // Save the name of the type parameter in the sym of the type.
                // Include the types2 subscript in the sym name
                sym := g.pkg(typ.Obj().Pkg()).Lookup(types2.TypeString(typ, func(*types2.Package) string { return "" }))
-               tp.SetSym(sym)
+               tp := types.NewTypeParam(sym, typ.Index())
                // Set g.typs[typ] in case the bound methods reference typ.
                g.typs[typ] = tp
 
-               // TODO(danscales): we don't currently need to use the bounds
-               // anywhere, so eventually we can probably remove.
                bound := g.typ1(typ.Bound())
-               *tp.Methods() = *bound.Methods()
+               tp.SetBound(bound)
                return tp
 
        case *types2.Tuple:
index 1a9aa6916a2faca5a12a999226cea51cef0c4234..d3c02fc56d35c214e75812f01f45f34b8bf3cda6 100644 (file)
@@ -151,7 +151,7 @@ type Type struct {
        // TARRAY: *Array
        // TSLICE: Slice
        // TSSA: string
-       // TTYPEPARAM:  *Interface (though we may not need to store/use the Interface info)
+       // TTYPEPARAM:  *Typeparam
        Extra interface{}
 
        // Width is the width of this Type in bytes.
@@ -377,6 +377,12 @@ type Interface struct {
        pkg *Pkg
 }
 
+// Typeparam contains Type fields specific to typeparam types.
+type Typeparam struct {
+       index int // type parameter index in source order, starting at 0
+       bound *Type
+}
+
 // Ptr contains Type fields specific to pointer types.
 type Ptr struct {
        Elem *Type // element type
@@ -558,7 +564,7 @@ func New(et Kind) *Type {
        case TRESULTS:
                t.Extra = new(Results)
        case TTYPEPARAM:
-               t.Extra = new(Interface)
+               t.Extra = new(Typeparam)
        }
        return t
 }
@@ -825,6 +831,8 @@ func (t *Type) copy() *Type {
        case TARRAY:
                x := *t.Extra.(*Array)
                nt.Extra = &x
+       case TTYPEPARAM:
+               base.Fatalf("typeparam types cannot be copied")
        case TTUPLE, TSSA, TRESULTS:
                base.Fatalf("ssa types cannot be copied")
        }
@@ -1766,14 +1774,34 @@ func NewInterface(pkg *Pkg, methods []*Field) *Type {
        return t
 }
 
-// NewTypeParam returns a new type param.
-func NewTypeParam(pkg *Pkg) *Type {
+// NewTypeParam returns a new type param with the specified sym (package and name)
+// and specified index within the typeparam list.
+func NewTypeParam(sym *Sym, index int) *Type {
        t := New(TTYPEPARAM)
-       t.Extra.(*Interface).pkg = pkg
+       t.sym = sym
+       t.Extra.(*Typeparam).index = index
        t.SetHasTParam(true)
        return t
 }
 
+// Index returns the index of the type param within its param list.
+func (t *Type) Index() int {
+       t.wantEtype(TTYPEPARAM)
+       return t.Extra.(*Typeparam).index
+}
+
+// SetBound sets the bound of a typeparam.
+func (t *Type) SetBound(bound *Type) {
+       t.wantEtype(TTYPEPARAM)
+       t.Extra.(*Typeparam).bound = bound
+}
+
+// Bound returns the bound of a typeparam.
+func (t *Type) Bound() *Type {
+       t.wantEtype(TTYPEPARAM)
+       return t.Extra.(*Typeparam).bound
+}
+
 const BOGUS_FUNARG_OFFSET = -1000000000
 
 func unzeroFieldOffsets(f []*Field) {
index 873390c1e9280d6b961ad02592e52e16f39096c3..e1020a12194b0278436475eb9d6e4e52087350c2 100644 (file)
@@ -349,7 +349,6 @@ func TestTypesInfo(t *testing.T) {
        }
 
        for _, test := range tests {
-               ResetId() // avoid renumbering of type parameter ids when adding tests
                info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
                var name string
                if strings.HasPrefix(test.src, brokenPkg) {
index 8d6cd1edab9d4c61cd1f1d5d7a99798def7fdcde..f80a918467e6cf81c8312c07f841e8346053b081 100644 (file)
@@ -83,6 +83,7 @@ type Checker struct {
        pkg  *Package
        *Info
        version version                     // accepted language version
+       nextID  uint64                      // unique Id for type parameters (first valid Id is 1)
        objMap  map[Object]*declInfo        // maps package-level objects and (non-interface) methods to declaration info
        impMap  map[importKey]*Package      // maps (import path, source directory) to (complete or fake) package
        posMap  map[*Interface][]syntax.Pos // maps interface types to lists of embedded interface positions
index e6c260ff6790c6663438ad62ce3e21b232712a1a..cf119a1b23bdb6feae9b9ecf3dd2c7e48d3ba693 100644 (file)
@@ -732,11 +732,11 @@ func (t *Named) AddMethod(m *Func) {
 // Note: This is a uint32 rather than a uint64 because the
 // respective 64 bit atomic instructions are not available
 // on all platforms.
-var lastId uint32
+var lastID uint32
 
-// nextId returns a value increasing monotonically by 1 with
+// nextID returns a value increasing monotonically by 1 with
 // each call, starting with 1. It may be called concurrently.
-func nextId() uint64 { return uint64(atomic.AddUint32(&lastId, 1)) }
+func nextID() uint64 { return uint64(atomic.AddUint32(&lastID, 1)) }
 
 // A TypeParam represents a type parameter type.
 type TypeParam struct {
@@ -753,13 +753,24 @@ func (t *TypeParam) Obj() *TypeName { return t.obj }
 // NewTypeParam returns a new TypeParam.
 func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
        assert(bound != nil)
-       typ := &TypeParam{check: check, id: nextId(), obj: obj, index: index, bound: bound}
+       // Always increment lastID, even if it is not used.
+       id := nextID()
+       if check != nil {
+               check.nextID++
+               id = check.nextID
+       }
+       typ := &TypeParam{check: check, id: id, obj: obj, index: index, bound: bound}
        if obj.typ == nil {
                obj.typ = typ
        }
        return typ
 }
 
+// Index returns the index of the type param within its param list.
+func (t *TypeParam) Index() int {
+       return t.index
+}
+
 func (t *TypeParam) Bound() *Interface {
        iface := asInterface(t.bound)
        // use the type bound position if we have one
index 096402148d38ad481815ad916e00664dfd0419c2..1525844f2dfcc2cbf07784b75afe6cfb9bbdd9ab 100644 (file)
@@ -4,14 +4,9 @@
 
 package types2
 
-import "sync/atomic"
-
 func init() {
        acceptMethodTypeParams = true
 }
 
-// Upon calling ResetId, nextId starts with 1 again.
-// It may be called concurrently. This is only needed
-// for tests where we may want to have a consistent
-// numbering for each individual test case.
-func ResetId() { atomic.StoreUint32(&lastId, 0) }
+// Debug is set if types2 is built with debug mode enabled.
+const Debug = debug
index 40016697b7c90f99c6319f0dae6c9079f3db0767..e85cc8ed3588fe273ee1f6121b843efd5e0dc2e6 100644 (file)
@@ -226,7 +226,7 @@ func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
                                empty = false
                        }
                }
-               if t.allMethods == nil || len(t.methods) > len(t.allMethods) {
+               if debug && (t.allMethods == nil || len(t.methods) > len(t.allMethods)) {
                        if !empty {
                                buf.WriteByte(' ')
                        }
index d98e9a5ade6e9bbe0a3c60b03d9dd472425c35a9..618fdc0757d74334dd065f56b700fb89b92820ad 100644 (file)
@@ -138,6 +138,10 @@ func TestTypeString(t *testing.T) {
 var nopos syntax.Pos
 
 func TestIncompleteInterfaces(t *testing.T) {
+       if !Debug {
+               t.Skip("requires type checker to be compiled with debug = true")
+       }
+
        sig := NewSignature(nil, nil, nil, false)
        m := NewFunc(nopos, nil, "m", sig)
        for _, test := range []struct {
diff --git a/src/go/constant/kind_string.go b/src/go/constant/kind_string.go
new file mode 100644 (file)
index 0000000..7003325
--- /dev/null
@@ -0,0 +1,28 @@
+// Code generated by "stringer -type Kind"; DO NOT EDIT.
+
+package constant
+
+import "strconv"
+
+func _() {
+       // An "invalid array index" compiler error signifies that the constant values have changed.
+       // Re-run the stringer command to generate them again.
+       var x [1]struct{}
+       _ = x[Unknown-0]
+       _ = x[Bool-1]
+       _ = x[String-2]
+       _ = x[Int-3]
+       _ = x[Float-4]
+       _ = x[Complex-5]
+}
+
+const _Kind_name = "UnknownBoolStringIntFloatComplex"
+
+var _Kind_index = [...]uint8{0, 7, 11, 17, 20, 25, 32}
+
+func (i Kind) String() string {
+       if i < 0 || i >= Kind(len(_Kind_index)-1) {
+               return "Kind(" + strconv.FormatInt(int64(i), 10) + ")"
+       }
+       return _Kind_name[_Kind_index[i]:_Kind_index[i+1]]
+}
index 78cb3f896f535cd7fddd64a2f2b34e03f1ec81dd..014e873100de6e02a426dec50f6aed921764c6db 100644 (file)
@@ -24,6 +24,8 @@ import (
        "unicode/utf8"
 )
 
+//go:generate stringer -type Kind
+
 // Kind specifies the kind of value represented by a Value.
 type Kind int
 
index fde6fbf1b144eb609559d4662d9bf054636405aa..53ba23b64cfa8dcbcd4710bffc708558a4b11e9c 100644 (file)
@@ -7,6 +7,8 @@
 
 package runtime
 
+import "internal/abi"
+
 //go:nosplit
 //go:nowritebarrierrec
 func setsig(i uint32, fn uintptr) {
@@ -14,7 +16,7 @@ func setsig(i uint32, fn uintptr) {
        sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
        sa.sa_mask = sigset_all
        if fn == funcPC(sighandler) {
-               fn = funcPC(sigtramp)
+               fn = abi.FuncPCABI0(sigtramp)
        }
        sa.sa_handler = fn
        sigaction(i, &sa, nil)
index dc0bb9ff96fd33ca40cb21ee59ee1a2ea6631010..7ae80c25060be1442b5c4d5ffe3ca46988e63935 100644 (file)
@@ -4,6 +4,8 @@
 
 package runtime
 
+import "internal/abi"
+
 func cgoSigtramp()
 
 //go:nosplit
@@ -14,9 +16,9 @@ func setsig(i uint32, fn uintptr) {
        sa.sa_mask = sigset_all
        if fn == funcPC(sighandler) {
                if iscgo {
-                       fn = funcPC(cgoSigtramp)
+                       fn = abi.FuncPCABI0(cgoSigtramp)
                } else {
-                       fn = funcPC(sigtramp)
+                       fn = abi.FuncPCABI0(sigtramp)
                }
        }
        sa.sa_handler = fn
diff --git a/test/typeparam/issue45817.go b/test/typeparam/issue45817.go
new file mode 100644 (file)
index 0000000..744698f
--- /dev/null
@@ -0,0 +1,25 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+       "fmt"
+)
+
+type s[T any] struct {
+       a T
+}
+func (x s[T]) f() T {
+       return x.a
+}
+func main() {
+       x := s[int]{a:7}
+       f := x.f
+       if got, want := f(), 7; got != want {
+               panic(fmt.Sprintf("got %d, want %d", got, want))
+       }
+}