]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: simplify function/interface/struct typechecking
authorMatthew Dempsky <mdempsky@google.com>
Wed, 23 Dec 2020 10:48:57 +0000 (02:48 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 23 Dec 2020 11:59:32 +0000 (11:59 +0000)
After the previous CL, the only callers to NewFuncType, tointerface,
or NewStructType are the functions for type-checking the type literal
ASTs. So just inline the code there.

While here, refactor the Field type-checking logic a little bit, to
reduce some duplication.

Passes toolstash -cmp.

Change-Id: Ie12d14b87ef8b6e528ac9dccd609604bd09b98ec
Reviewed-on: https://go-review.googlesource.com/c/go/+/279956
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/typecheck/dcl.go
src/cmd/compile/internal/typecheck/type.go

index bfdd76ba107c8dbeb06529a2cfb467c510bb2998..db18c17e13018a26eb1d84d2f26bee4df404df98 100644 (file)
@@ -281,72 +281,6 @@ func CheckFuncStack() {
        }
 }
 
-// turn a parsed function declaration into a type
-func NewFuncType(nrecv *ir.Field, nparams, nresults []*ir.Field) *types.Type {
-       funarg := func(n *ir.Field) *types.Field {
-               lno := base.Pos
-               base.Pos = n.Pos
-
-               if n.Ntype != nil {
-                       n.Type = typecheckNtype(n.Ntype).Type()
-                       n.Ntype = nil
-               }
-
-               f := types.NewField(n.Pos, n.Sym, n.Type)
-               f.SetIsDDD(n.IsDDD)
-               if n.Decl != nil {
-                       n.Decl.SetType(f.Type)
-                       f.Nname = n.Decl
-               }
-
-               base.Pos = lno
-               return f
-       }
-       funargs := func(nn []*ir.Field) []*types.Field {
-               res := make([]*types.Field, len(nn))
-               for i, n := range nn {
-                       res[i] = funarg(n)
-               }
-               return res
-       }
-
-       var recv *types.Field
-       if nrecv != nil {
-               recv = funarg(nrecv)
-       }
-
-       t := types.NewSignature(types.LocalPkg, recv, funargs(nparams), funargs(nresults))
-       checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
-       return t
-}
-
-// convert a parsed id/type list into
-// a type for struct/interface/arglist
-func NewStructType(l []*ir.Field) *types.Type {
-       lno := base.Pos
-
-       fields := make([]*types.Field, len(l))
-       for i, n := range l {
-               base.Pos = n.Pos
-
-               if n.Ntype != nil {
-                       n.Type = typecheckNtype(n.Ntype).Type()
-                       n.Ntype = nil
-               }
-               f := types.NewField(n.Pos, n.Sym, n.Type)
-               if n.Embedded {
-                       checkembeddedtype(n.Type)
-                       f.Embedded = 1
-               }
-               f.Note = n.Note
-               fields[i] = f
-       }
-       checkdupfields("field", fields)
-
-       base.Pos = lno
-       return types.NewStruct(types.LocalPkg, fields)
-}
-
 // Add a method, declared as a function.
 // - msym is the method symbol
 // - t is function type (with receiver)
@@ -604,27 +538,6 @@ func initname(s string) bool {
        return s == "init"
 }
 
-func tointerface(nmethods []*ir.Field) *types.Type {
-       if len(nmethods) == 0 {
-               return types.Types[types.TINTER]
-       }
-
-       lno := base.Pos
-
-       methods := make([]*types.Field, len(nmethods))
-       for i, n := range nmethods {
-               base.Pos = n.Pos
-               if n.Ntype != nil {
-                       n.Type = typecheckNtype(n.Ntype).Type()
-                       n.Ntype = nil
-               }
-               methods[i] = types.NewField(n.Pos, n.Sym, n.Type)
-       }
-
-       base.Pos = lno
-       return types.NewInterface(types.LocalPkg, methods)
-}
-
 var vargen int
 
 func Temp(t *types.Type) *ir.Name {
index 4782bb9c3180a2a5211c3dbeb2f9927388642266..0c2ebb8b26a0c24567b93d97982917d209372674 100644 (file)
@@ -73,13 +73,42 @@ func tcChanType(n *ir.ChanType) ir.Node {
 
 // tcFuncType typechecks an OTFUNC node.
 func tcFuncType(n *ir.FuncType) ir.Node {
-       n.SetOTYPE(NewFuncType(n.Recv, n.Params, n.Results))
+       misc := func(f *types.Field, nf *ir.Field) {
+               f.SetIsDDD(nf.IsDDD)
+               if nf.Decl != nil {
+                       nf.Decl.SetType(f.Type)
+                       f.Nname = nf.Decl
+               }
+       }
+
+       lno := base.Pos
+
+       var recv *types.Field
+       if n.Recv != nil {
+               recv = tcField(n.Recv, misc)
+       }
+
+       t := types.NewSignature(types.LocalPkg, recv, tcFields(n.Params, misc), tcFields(n.Results, misc))
+       checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
+
+       base.Pos = lno
+
+       n.SetOTYPE(t)
        return n
 }
 
 // tcInterfaceType typechecks an OTINTER node.
 func tcInterfaceType(n *ir.InterfaceType) ir.Node {
-       n.SetOTYPE(tointerface(n.Methods))
+       if len(n.Methods) == 0 {
+               n.SetOTYPE(types.Types[types.TINTER])
+               return n
+       }
+       
+       lno := base.Pos
+       methods := tcFields(n.Methods, nil)
+       base.Pos = lno
+
+       n.SetOTYPE(types.NewInterface(types.LocalPkg, methods))
        return n
 }
 
@@ -117,6 +146,43 @@ func tcSliceType(n *ir.SliceType) ir.Node {
 
 // tcStructType typechecks an OTSTRUCT node.
 func tcStructType(n *ir.StructType) ir.Node {
-       n.SetOTYPE(NewStructType(n.Fields))
+       lno := base.Pos
+
+       fields := tcFields(n.Fields, func(f *types.Field, nf *ir.Field) {
+               if nf.Embedded {
+                       checkembeddedtype(f.Type)
+                       f.Embedded = 1
+               }
+               f.Note = nf.Note
+       })
+       checkdupfields("field", fields)
+
+       base.Pos = lno
+       n.SetOTYPE(types.NewStruct(types.LocalPkg, fields))
        return n
 }
+
+// tcField typechecks a generic Field.
+// misc can be provided to handle specialized typechecking.
+func tcField(n *ir.Field, misc func(*types.Field, *ir.Field)) *types.Field {
+       base.Pos = n.Pos
+       if n.Ntype != nil {
+               n.Type = typecheckNtype(n.Ntype).Type()
+               n.Ntype = nil
+       }
+       f := types.NewField(n.Pos, n.Sym, n.Type)
+       if misc != nil {
+               misc(f, n)
+       }
+       return f
+}
+
+// tcFields typechecks a slice of generic Fields.
+// misc can be provided to handle specialized typechecking.
+func tcFields(l []*ir.Field, misc func(*types.Field, *ir.Field)) []*types.Field {
+       fields := make([]*types.Field, len(l))
+       for i, n := range l {
+               fields[i] = tcField(n, misc)
+       }
+       return fields
+}