]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: enable parsing of generic code with new -G flag
authorRobert Griesemer <gri@golang.org>
Mon, 12 Oct 2020 23:19:49 +0000 (16:19 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 13 Oct 2020 04:48:43 +0000 (04:48 +0000)
Providing the -G flag instructs the compiler to accept type parameters.
For now, the compiler only parses such files and then exits.

Added a new test directory (test/typeparam) and initial test case.

Port from dev.go2go branch.

Change-Id: Ic11e33a9d5f012f8def0bdae205043659562ac73
Reviewed-on: https://go-review.googlesource.com/c/go/+/261660
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/noder.go
test/run.go
test/typeparam/smoketest.go [new file with mode: 0644]

index e4e4ce72fdb1693b08313e21fc68d9b4e88ec7b7..21e4757a92df8a3fd1305b5e1205e5f7795b57ed 100644 (file)
@@ -216,6 +216,7 @@ func Main(archInit func(*Arch)) {
        objabi.Flagcount("C", "disable printing of columns in error messages", &Debug['C']) // TODO(gri) remove eventually
        flag.StringVar(&localimport, "D", "", "set relative `path` for local imports")
        objabi.Flagcount("E", "debug symbol export", &Debug['E'])
+       objabi.Flagcount("G", "accept generic code", &Debug['G'])
        objabi.Flagfn1("I", "add `directory` to import search path", addidir)
        objabi.Flagcount("K", "debug missing line numbers", &Debug['K'])
        objabi.Flagcount("L", "show full file names in error messages", &Debug['L'])
@@ -571,9 +572,16 @@ func Main(archInit func(*Arch)) {
        loadsys()
 
        timings.Start("fe", "parse")
-       lines := parseFiles(flag.Args())
+       lines := parseFiles(flag.Args(), Debug['G'] != 0)
        timings.Stop()
        timings.AddEvent(int64(lines), "lines")
+       if Debug['G'] != 0 {
+               // can only parse generic code for now
+               if nerrors+nsavederrors != 0 {
+                       errorexit()
+               }
+               return
+       }
 
        finishUniverse()
 
index 8b1105598364fc5d429fd5e8f4a4d6206631e73b..e75c645a573f3f0d4c2d741b6ac94990531f8fc5 100644 (file)
@@ -24,7 +24,7 @@ import (
 // Each declaration in every *syntax.File is converted to a syntax tree
 // and its root represented by *Node is appended to xtop.
 // Returns the total count of parsed lines.
-func parseFiles(filenames []string) uint {
+func parseFiles(filenames []string, allowGenerics bool) uint {
        noders := make([]*noder, 0, len(filenames))
        // Limit the number of simultaneously open files.
        sem := make(chan struct{}, runtime.GOMAXPROCS(0)+10)
@@ -49,7 +49,11 @@ func parseFiles(filenames []string) uint {
                        }
                        defer f.Close()
 
-                       p.file, _ = syntax.Parse(base, f, p.error, p.pragma, syntax.CheckBranches) // errors are tracked via p.error
+                       mode := syntax.CheckBranches
+                       if allowGenerics {
+                               mode |= syntax.AllowGenerics
+                       }
+                       p.file, _ = syntax.Parse(base, f, p.error, p.pragma, mode) // errors are tracked via p.error
                }(filename)
        }
 
@@ -59,7 +63,10 @@ func parseFiles(filenames []string) uint {
                        p.yyerrorpos(e.Pos, "%s", e.Msg)
                }
 
-               p.node()
+               // noder cannot handle generic code yet
+               if !allowGenerics {
+                       p.node()
+               }
                lines += p.file.EOF.Line()
                p.file = nil // release memory
 
index 672861c8d78136364c3d8247e708c5e5a51b0288..7422e6922d63467356984a26ce54b52ec545a080 100644 (file)
@@ -58,7 +58,7 @@ var (
 
        // dirs are the directories to look for *.go files in.
        // TODO(bradfitz): just use all directories?
-       dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime"}
+       dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "typeparam"}
 
        // ratec controls the max number of tests running at a time.
        ratec chan bool
diff --git a/test/typeparam/smoketest.go b/test/typeparam/smoketest.go
new file mode 100644 (file)
index 0000000..d17809e
--- /dev/null
@@ -0,0 +1,57 @@
+// compile -G
+
+// Copyright 2020 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.
+
+// This file checks simple code using type parameters.
+
+package smoketest
+
+// type parameters for functions
+func f1[P any]()
+func f2[P1, P2 any, P3 any]()
+func f3[P interface{}](x P, y T1[int])
+
+// function instantiations
+var _ = f1[int]
+var _ = f2[int, string, struct{}]
+var _ = f3[bool]
+
+// type parameters for types
+type T1[P any] struct{}
+type T2[P1, P2 any, P3 any] struct{}
+type T3[P interface{}] interface{}
+
+// type instantiations
+type _ T1[int]
+type _ T2[int, string, struct{}]
+type _ T3[bool]
+
+// methods
+func (T1[P]) m1() {}
+func (x T2[P1, P2, P3]) m1() {}
+func (_ T3[_]) m1() {}
+
+// type lists
+type _ interface {
+       m1()
+       m2()
+       type int, float32, string
+       m3()
+       type bool
+}
+
+// embedded instantiated types
+type _ struct {
+       f1, f2 int
+       T1[int]
+       T2[int, string, struct{}]
+       T3[bool]
+}
+
+type _ interface {
+       m1()
+       m2()
+       T3[bool]
+}