1
0
mirror of https://github.com/golang/go synced 2024-07-01 07:56:09 +00:00

[dev.typeparams] test: add scaffolding to run.go to check compiler with -G flag

Added a new flag -G to run. Setting -G (as in: go run run.go -G)
will run tests marked with "errorcheck" (and no other flags) also
with the compiler using the new typechecker.

Many tests don't pass yet (due to discrepancies in error messages).
The top-level tests in the test directory which don't pass yet have
been explicitly excluded, permitting to see the current status.
Future CLs will bring error messages in sync and eventually all
tests should pass.

Change-Id: I7caf5eff413e173f68d092af4bbe458434718d74
Reviewed-on: https://go-review.googlesource.com/c/go/+/274313
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>
This commit is contained in:
Robert Griesemer 2020-11-30 21:38:49 -08:00
parent 87bc85a846
commit 72ad2f44ea
11 changed files with 208 additions and 97 deletions

View File

@ -83,7 +83,8 @@ func parseFiles(filenames []string, allowGenerics bool) (lines uint) {
}
conf := types2.Config{
InferFromConstraints: true,
InferFromConstraints: true,
CompilerErrorMessages: true,
Error: func(err error) {
terr := err.(types2.Error)
if len(terr.Msg) > 0 && terr.Msg[0] == '\t' {

View File

@ -36,7 +36,7 @@ type (
// Methods can be declared on the original named type and the alias.
func (T0) m1() {} // GCCGO_ERROR "previous"
func (*T0) m1() {} // ERROR "method redeclared: T0\.m1|redefinition of .m1."
func (*T0) m1() {} // ERROR "method redeclared: T0\.m1|T0\.m1 redeclared in this block|redefinition of .m1."
func (A0) m1() {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
func (A0) m1() {} // ERROR "T0\.m1 redeclared in this block|redefinition of .m1."
func (A0) m2() {}
@ -90,7 +90,7 @@ func _() {
// Invalid type alias declarations.
type _ = reflect.ValueOf // ERROR "reflect.ValueOf is not a type|expected type"
type _ = reflect.ValueOf // ERROR "reflect.ValueOf .*is not a type|expected type"
func (A1) m() {} // ERROR "cannot define new methods on non-local type int|may not define methods on non-local type"
func (A2) m() {} // ERROR "invalid receiver type"

View File

@ -13,10 +13,10 @@ func main() {
s := make([]int, 8)
_ = append() // ERROR "missing arguments to append"
_ = append(s...) // ERROR "cannot use ... on first argument"
_ = append(s, 2, s...) // ERROR "too many arguments to append"
_ = append() // ERROR "missing arguments to append|not enough arguments for append"
_ = append(s...) // ERROR "cannot use ... on first argument|not enough arguments in call to append"
_ = append(s, 2, s...) // ERROR "too many arguments to append|too many arguments in call to append"
_ = append(s, make([]int, 0)) // ERROR "cannot use make.* as type int in append"
_ = append(s, make([]int, -1)...) // ERROR "negative len argument in make"
_ = append(s, make([]int, 0)) // ERROR "cannot use make.* as type int in append|cannot use make.* as int value"
_ = append(s, make([]int, -1)...) // ERROR "negative len argument in make|index -1.* must not be negative"
}

View File

@ -42,7 +42,7 @@ func main() {
_ = x
}
{
x := sync.Mutex{key: 0} // ERROR "(unknown|assignment).*Mutex"
x := sync.Mutex{key: 0} // ERROR "(unknown|assignment).*Mutex|unknown field.* in struct literal"
_ = x
}
{
@ -56,13 +56,13 @@ func main() {
{
var x = 1
{
x, x := 2, 3 // ERROR "x repeated on left side of :="
x, x := 2, 3 // ERROR "x repeated on left side of :=|x redeclared in this block"
_ = x
}
_ = x
}
{
a, a := 1, 2 // ERROR "a repeated on left side of :="
a, a := 1, 2 // ERROR "a repeated on left side of :=|a redeclared in this block"
_ = a
}
}

View File

@ -25,8 +25,8 @@ func main() {
_() // ERROR "cannot use .* as value"
x := _+1 // ERROR "cannot use .* as value"
_ = x
_ = t._ // ERROR "cannot refer to blank field|invalid use of"
_ = t._ // ERROR "cannot refer to blank field|invalid use of|t._ undefined"
var v1, v2 T
_ = v1 == v2 // ERROR "cannot be compared|non-comparable"
_ = v1 == v2 // ERROR "cannot be compared|non-comparable|cannot compare v1 == v2"
}

View File

@ -10,24 +10,24 @@ package main
func main() {
var s string = "hello"
s[1:2] = "a" // ERROR "cannot assign to .* \(strings are immutable\)"
s[3] = "b" // ERROR "cannot assign to .* \(strings are immutable\)"
s[1:2] = "a" // ERROR "cannot assign to .* (\(strings are immutable\))?"
s[3] = "b" // ERROR "cannot assign to .* (\(strings are immutable\))?"
const n int = 1
const cs string = "hello"
n = 2 // ERROR "cannot assign to .* \(declared const\)"
cs = "hi" // ERROR "cannot assign to .* \(declared const\)"
true = false // ERROR "cannot assign to .* \(declared const\)"
n = 2 // ERROR "cannot assign to .* (\(declared const\))?"
cs = "hi" // ERROR "cannot assign to .* (\(declared const\))?"
true = false // ERROR "cannot assign to .* (\(declared const\))?"
var m map[int]struct{ n int }
m[0].n = 7 // ERROR "cannot assign to struct field .* in map$"
1 = 7 // ERROR "cannot assign to 1$"
"hi" = 7 // ERROR `cannot assign to "hi"$`
nil = 7 // ERROR "cannot assign to nil$"
len("") = 7 // ERROR `cannot assign to len\(""\)$`
[]int{} = nil // ERROR "cannot assign to \[\]int\{\}$"
1 = 7 // ERROR "cannot assign to 1"
"hi" = 7 // ERROR `cannot assign to "hi"`
nil = 7 // ERROR "cannot assign to nil"
len("") = 7 // ERROR `cannot assign to len\(""\)`
[]int{} = nil // ERROR "cannot assign to \[\]int\{\}"
var x int = 7
x + 1 = 7 // ERROR "cannot assign to x \+ 1$"
x + 1 = 7 // ERROR "cannot assign to x \+ 1"
}

View File

@ -63,16 +63,16 @@ func main() {
use(a3 == a3) // ERROR "invalid operation|invalid comparison"
// Comparison of structs should have a good message
use(t3 == t3) // ERROR "struct|expected"
use(t4 == t4) // ERROR "cannot be compared|non-comparable"
use(t3 == t3) // ERROR "struct|expected|cannot compare"
use(t4 == t4) // ERROR "cannot be compared|non-comparable|cannot compare"
// Slices, functions, and maps too.
var x []int
var f func()
var m map[int]int
use(x == x) // ERROR "slice can only be compared to nil"
use(f == f) // ERROR "func can only be compared to nil"
use(m == m) // ERROR "map can only be compared to nil"
use(x == x) // ERROR "slice can only be compared to nil|cannot compare"
use(f == f) // ERROR "func can only be compared to nil|cannot compare"
use(m == m) // ERROR "map can only be compared to nil|cannot compare"
// Comparison with interface that cannot return true
// (would panic).

View File

@ -30,43 +30,43 @@ const (
)
var (
a1 = Int8 * 100 // ERROR "overflow"
a1 = Int8 * 100 // ERROR "overflow|cannot convert"
a2 = Int8 * -1 // OK
a3 = Int8 * 1000 // ERROR "overflow"
a4 = Int8 * int8(1000) // ERROR "overflow"
a5 = int8(Int8 * 1000) // ERROR "overflow"
a6 = int8(Int8 * int8(1000)) // ERROR "overflow"
a7 = Int8 - 2*Int8 - 2*Int8 // ERROR "overflow"
a8 = Int8 * Const / 100 // ERROR "overflow"
a3 = Int8 * 1000 // ERROR "overflow|cannot convert"
a4 = Int8 * int8(1000) // ERROR "overflow|cannot convert"
a5 = int8(Int8 * 1000) // ERROR "overflow|cannot convert"
a6 = int8(Int8 * int8(1000)) // ERROR "overflow|cannot convert"
a7 = Int8 - 2*Int8 - 2*Int8 // ERROR "overflow|cannot convert"
a8 = Int8 * Const / 100 // ERROR "overflow|cannot convert"
a9 = Int8 * (Const / 100) // OK
b1 = Uint8 * Uint8 // ERROR "overflow"
b2 = Uint8 * -1 // ERROR "overflow"
b1 = Uint8 * Uint8 // ERROR "overflow|cannot convert"
b2 = Uint8 * -1 // ERROR "overflow|cannot convert"
b3 = Uint8 - Uint8 // OK
b4 = Uint8 - Uint8 - Uint8 // ERROR "overflow"
b5 = uint8(^0) // ERROR "overflow"
b4 = Uint8 - Uint8 - Uint8 // ERROR "overflow|cannot convert"
b5 = uint8(^0) // ERROR "overflow|cannot convert"
b5a = int64(^0) // OK
b6 = ^uint8(0) // OK
b6a = ^int64(0) // OK
b7 = uint8(Minus1) // ERROR "overflow"
b8 = uint8(int8(-1)) // ERROR "overflow"
b8a = uint8(-1) // ERROR "overflow"
b7 = uint8(Minus1) // ERROR "overflow|cannot convert"
b8 = uint8(int8(-1)) // ERROR "overflow|cannot convert"
b8a = uint8(-1) // ERROR "overflow|cannot convert"
b9 byte = (1 << 10) >> 8 // OK
b10 byte = (1 << 10) // ERROR "overflow"
b11 byte = (byte(1) << 10) >> 8 // ERROR "overflow"
b12 byte = 1000 // ERROR "overflow"
b13 byte = byte(1000) // ERROR "overflow"
b14 byte = byte(100) * byte(100) // ERROR "overflow"
b15 byte = byte(100) * 100 // ERROR "overflow"
b16 byte = byte(0) * 1000 // ERROR "overflow"
b10 byte = (1 << 10) // ERROR "overflow|cannot convert"
b11 byte = (byte(1) << 10) >> 8 // ERROR "overflow|cannot convert"
b12 byte = 1000 // ERROR "overflow|cannot convert"
b13 byte = byte(1000) // ERROR "overflow|cannot convert"
b14 byte = byte(100) * byte(100) // ERROR "overflow|cannot convert"
b15 byte = byte(100) * 100 // ERROR "overflow|cannot convert"
b16 byte = byte(0) * 1000 // ERROR "overflow|cannot convert"
b16a byte = 0 * 1000 // OK
b17 byte = byte(0) * byte(1000) // ERROR "overflow"
b17 byte = byte(0) * byte(1000) // ERROR "overflow|cannot convert"
b18 byte = Uint8 / 0 // ERROR "division by zero"
c1 float64 = Big
c2 float64 = Big * Big // ERROR "overflow"
c3 float64 = float64(Big) * Big // ERROR "overflow"
c4 = Big * Big // ERROR "overflow"
c2 float64 = Big * Big // ERROR "overflow|cannot convert"
c3 float64 = float64(Big) * Big // ERROR "overflow|cannot convert"
c4 = Big * Big // ERROR "overflow|cannot convert"
c5 = Big / 0 // ERROR "division by zero"
c6 = 1000 % 1e3 // ERROR "invalid operation|expected integer type"
)
@ -87,8 +87,8 @@ func main() {
f(Bool) // ERROR "convert|wrong type|cannot|incompatible"
}
const ptr = nil // ERROR "const.*nil"
const ptr = nil // ERROR "const.*nil|not constant"
const _ = string([]byte(nil)) // ERROR "is not a? ?constant"
const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a? ?constant"
const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type|is not a constant"
const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type|is not a constant"
const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type|is not a constant|not constant"
const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type|is not a constant|not constant"

View File

@ -11,7 +11,7 @@ package main
const (
A int = 1
B byte; // ERROR "type without expr|expected .=."
B byte; // ERROR "type without expr|expected .=.|missing init expr"
)
const LargeA = 1000000000000000000
@ -23,7 +23,7 @@ const AlsoLargeA = LargeA << 400 << 400 >> 400 >> 400 // GC_ERROR "constant shif
// Issue #42732.
const a = 1e+500000000
const b = a * a // ERROR "constant multiplication overflow"
const b = a * a // ERROR "constant multiplication overflow|not representable"
const c = b * b
const MaxInt512 = (1<<256 - 1) * (1<<256 + 1)

View File

@ -22,7 +22,7 @@ func _() {
var t T
var u struct{}
s = s
s = t // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u
s = S(s)
s = S(t)
@ -42,12 +42,12 @@ func _() {
x int "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = S(s)
s = S(t)
s = S(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = T(u)
}
@ -63,12 +63,12 @@ func _() {
x E "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = S(s)
s = S(t)
s = S(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = T(u)
}
@ -91,12 +91,12 @@ func _() {
} "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = S(s)
s = S(t)
s = S(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = T(u)
}
@ -117,12 +117,12 @@ func _() {
x E2 "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = S(s)
s = S(t) // ERROR "cannot convert"
s = S(u) // ERROR "cannot convert"
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = T(u)
}
@ -142,12 +142,12 @@ func _() {
var t T
var u struct{ f func(E) }
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = S(s)
s = S(t)
s = S(u) // ERROR "cannot convert"
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = T(u) // ERROR "cannot convert"
}
@ -160,12 +160,12 @@ func _() {
var t *T
var u *struct{}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t)
s = (*S)(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u)
}
@ -180,12 +180,12 @@ func _() {
x int "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t)
s = (*S)(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u)
}
@ -201,12 +201,12 @@ func _() {
x E "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t)
s = (*S)(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u)
}
@ -229,12 +229,12 @@ func _() {
} "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t)
s = (*S)(u)
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u)
}
@ -255,12 +255,12 @@ func _() {
x E2 "bar"
}
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t) // ERROR "cannot convert"
s = (*S)(u) // ERROR "cannot convert"
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u)
}
@ -280,12 +280,12 @@ func _() {
var t *T
var u *struct{ f func(E) }
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t)
s = (*S)(u) // ERROR "cannot convert"
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u) // ERROR "cannot convert"
}
@ -305,11 +305,11 @@ func _() {
var t *T
var u *struct{ f func(E) }
s = s
s = t // ERROR "cannot use .* in assignment"
s = u // ERROR "cannot use .* in assignment"
s = t // ERROR "cannot use .* in assignment|incompatible type"
s = u // ERROR "cannot use .* in assignment|incompatible type"
s = (*S)(s)
s = (*S)(t)
s = (*S)(u) // ERROR "cannot convert"
t = u // ERROR "cannot use .* in assignment"
t = u // ERROR "cannot use .* in assignment|incompatible type"
t = (*T)(u) // ERROR "cannot convert"
}

View File

@ -39,6 +39,7 @@ var (
runSkips = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)")
linkshared = flag.Bool("linkshared", false, "")
updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output")
newTypechecker = flag.Bool("G", false, "generics typechecker. if set, run basic errorcheck tests also with new typechecker")
runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
shard = flag.Int("shard", 0, "shard index to run. Only applicable if -shards is non-zero.")
@ -740,7 +741,116 @@ func (t *test) run() {
t.updateErrors(string(out), long)
}
t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
return
if t.err != nil || !*newTypechecker {
return
}
// The following is temporary scaffolding to get types2 typechecker
// up and running against the existing test cases. The explicitly
// listed files don't pass yet, usually because the error messages
// are slightly different (this list is not complete). Any errorcheck
// tests that require output from analysis phases past intial type-
// checking are also excluded since these phases are not running yet.
// We can get rid of this code once types2 is fully plugged in.
// For now we're done when we can't handle the file or some of the flags.
// The first goal is to eliminate the file list; the second goal is to
// eliminate the flag list.
// Excluded files.
for _, file := range []string{
"complit1",
"const2",
"convlit.go",
"copy1.go",
"ddd1.go",
"devirt.go",
"directive.go",
"float_lit3.go",
"func1.go",
"funcdup.go",
"funcdup2.go",
"goto.go",
"import1.go",
"import5.go",
"import6.go",
"init.go",
"initializerr.go",
"initloop.go",
"label.go",
"label1.go",
"makechan.go",
"makemap.go",
"makenew.go",
"map1.go",
"method2.go",
"method6.go",
"named1.go",
"rename1.go",
"runtime.go",
"shift1.go",
"slice3err.go",
"switch3.go",
"switch5.go",
"switch6.go",
"switch7.go",
"typecheck.go",
"typecheckloop.go",
"typeswitch3.go",
"undef.go",
"varerr.go",
} {
if strings.Contains(long, file) {
return // cannot handle file
}
}
// Excluded flags.
for _, flag := range flags {
for _, pattern := range []string{
"-+",
"-m",
"-live",
"wb",
"append",
"slice",
"ssa/check_bce/debug",
"ssa/intrinsics/debug",
"ssa/prove/debug",
"ssa/likelyadjust/debug",
"ssa/insert_resched_checks/off",
"ssa/phiopt/debug",
"defer",
"nil",
} {
if strings.Contains(flag, pattern) {
return // cannot handle flag
}
}
}
// Run errorcheck again with -G option (new typechecker).
cmdline = []string{goTool(), "tool", "compile", "-G", "-C", "-e", "-o", "a.o"}
// No need to add -dynlink even if linkshared if we're just checking for errors...
cmdline = append(cmdline, flags...)
cmdline = append(cmdline, long)
out, err = runcmd(cmdline...)
if wantError {
if err == nil {
t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
return
}
} else {
if err != nil {
t.err = err
return
}
}
if *updateErrors {
t.updateErrors(string(out), long)
}
t.err = t.errorCheck(string(out), wantAuto, long, t.gofile)
case "compile":
// Compile Go file.