Skip to content

Commit

Permalink
[dev.typeparams] cmd/compile: enable parsing of generic code with new…
Browse files Browse the repository at this point in the history
… -G flag

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>
  • Loading branch information
griesemer committed Oct 13, 2020
1 parent 7668f02 commit 48755e0
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 5 deletions.
10 changes: 9 additions & 1 deletion src/cmd/compile/internal/gc/main.go
Expand Up @@ -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'])
Expand Down Expand Up @@ -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()

Expand Down
13 changes: 10 additions & 3 deletions src/cmd/compile/internal/gc/noder.go
Expand Up @@ -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)
Expand All @@ -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)
}

Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion test/run.go
Expand Up @@ -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
Expand Down
57 changes: 57 additions & 0 deletions test/typeparam/smoketest.go
@@ -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]
}

0 comments on commit 48755e0

Please sign in to comment.