}
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' {
// 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() {}
// 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"
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"
}
_ = 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
}
{
{
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
}
}
_() // 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"
}
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"
}
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).
)
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"
)
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"
const (
A int = 1
- B byte; // ERROR "type without expr|expected .=."
+ B byte; // ERROR "type without expr|expected .=.|missing init expr"
)
const LargeA = 1000000000000000000
// 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)
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)
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)
}
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)
}
} "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)
}
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)
}
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"
}
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)
}
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)
}
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)
}
} "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)
}
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)
}
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"
}
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"
}
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.")
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.