diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:23:18 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:23:18 +0000 |
commit | 43a123c1ae6613b3efeed291fa552ecd909d3acf (patch) | |
tree | fd92518b7024bc74031f78a1cf9e454b65e73665 /src/internal/types/testdata | |
parent | Initial commit. (diff) | |
download | golang-1.20-43a123c1ae6613b3efeed291fa552ecd909d3acf.tar.xz golang-1.20-43a123c1ae6613b3efeed291fa552ecd909d3acf.zip |
Adding upstream version 1.20.14.upstream/1.20.14upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/internal/types/testdata')
249 files changed, 17373 insertions, 0 deletions
diff --git a/src/internal/types/testdata/check/blank.go b/src/internal/types/testdata/check/blank.go new file mode 100644 index 0000000..6a2507f --- /dev/null +++ b/src/internal/types/testdata/check/blank.go @@ -0,0 +1,5 @@ +// Copyright 2014 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. + +package _ /* ERROR invalid package name */ diff --git a/src/internal/types/testdata/check/builtins0.go b/src/internal/types/testdata/check/builtins0.go new file mode 100644 index 0000000..308f70b --- /dev/null +++ b/src/internal/types/testdata/check/builtins0.go @@ -0,0 +1,967 @@ +// Copyright 2012 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. + +// builtin calls + +package builtins + +import "unsafe" + +func f0() {} + +func append1() { + var b byte + var x int + var s []byte + _ = append() // ERROR not enough arguments + _ = append("foo" /* ERROR must be a slice */ ) + _ = append(nil /* ERROR must be a slice */ , s) + _ = append(x /* ERROR must be a slice */ , s) + _ = append(s) + _ = append(s, nil...) + append /* ERROR not used */ (s) + + _ = append(s, b) + _ = append(s, x /* ERROR cannot use x */ ) + _ = append(s, s /* ERROR cannot use s */ ) + _ = append(s...) /* ERROR not enough arguments */ + _ = append(s, b, s /* ERROR too many arguments */ ...) + _ = append(s, 1, 2, 3) + _ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6) + _ = append(s, 1, 2 /* ERROR too many arguments */, s...) + _ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false) + + type S []byte + type T string + var t T + _ = append(s, "foo" /* ERROR cannot use .* in argument to append */ ) + _ = append(s, "foo"...) + _ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ ) + _ = append(S(s), "foo"...) + _ = append(s, t /* ERROR cannot use t */ ) + _ = append(s, t...) + _ = append(s, T("foo")...) + _ = append(S(s), t /* ERROR cannot use t */ ) + _ = append(S(s), t...) + _ = append(S(s), T("foo")...) + _ = append([]string{}, t /* ERROR cannot use t */ , "foo") + _ = append([]T{}, t, "foo") +} + +// from the spec +func append2() { + s0 := []int{0, 0} + s1 := append(s0, 2) // append a single element s1 == []int{0, 0, 2} + s2 := append(s1, 3, 5, 7) // append multiple elements s2 == []int{0, 0, 2, 3, 5, 7} + s3 := append(s2, s0...) // append a slice s3 == []int{0, 0, 2, 3, 5, 7, 0, 0} + s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0} + + var t []interface{} + t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"} + + var b []byte + b = append(b, "bar"...) // append string contents b == []byte{'b', 'a', 'r' } + + _ = s4 +} + +func append3() { + f1 := func() (s []int) { return } + f2 := func() (s []int, x int) { return } + f3 := func() (s []int, x, y int) { return } + f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return } + ff := func() (int, float32) { return 0, 0 } + _ = append(f0 /* ERROR used as value */ ()) + _ = append(f1()) + _ = append(f2()) + _ = append(f3()) + _ = append(f5()) + _ = append(ff /* ERROR must be a slice */ ()) // TODO(gri) better error message +} + +func cap1() { + var a [10]bool + var p *[20]int + var c chan string + _ = cap() // ERROR not enough arguments + _ = cap(1, 2) // ERROR too many arguments + _ = cap(42 /* ERROR invalid */) + const _3 = cap(a) + assert(_3 == 10) + const _4 = cap(p) + assert(_4 == 20) + _ = cap(c) + cap /* ERROR not used */ (c) + + // issue 4744 + type T struct{ a [10]int } + const _ = cap(((*T)(nil)).a) + + var s [][]byte + _ = cap(s) + _ = cap(s... /* ERROR invalid use of \.\.\. */ ) +} + +func cap2() { + f1a := func() (a [10]int) { return } + f1s := func() (s []int) { return } + f2 := func() (s []int, x int) { return } + _ = cap(f0 /* ERROR used as value */ ()) + _ = cap(f1a()) + _ = cap(f1s()) + _ = cap(f2()) // ERROR too many arguments +} + +// test cases for issue 7387 +func cap3() { + var f = func() int { return 0 } + var x = f() + const ( + _ = cap([4]int{}) + _ = cap([4]int{x}) + _ = cap /* ERROR not constant */ ([4]int{f()}) + _ = cap /* ERROR not constant */ ([4]int{cap([]int{})}) + _ = cap([4]int{cap([4]int{})}) + ) + var y float64 + var z complex128 + const ( + _ = cap([4]float64{}) + _ = cap([4]float64{y}) + _ = cap([4]float64{real(2i)}) + _ = cap /* ERROR not constant */ ([4]float64{real(z)}) + ) + var ch chan [10]int + const ( + _ = cap /* ERROR not constant */ (<-ch) + _ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]}) + ) +} + +func clear1() { + var a [10]int + var m map[float64]string + var s []byte + clear(a /* ERROR cannot clear a */) + clear(&a) + clear(m) + clear(s) + clear([]int{}) +} + +func close1() { + var c chan int + var r <-chan int + close() // ERROR not enough arguments + close(1, 2) // ERROR too many arguments + close(42 /* ERROR cannot close non-channel */) + close(r /* ERROR receive-only channel */) + close(c) + _ = close /* ERROR used as value */ (c) + + var s []chan int + close(s... /* ERROR invalid use of \.\.\. */ ) +} + +func close2() { + f1 := func() (ch chan int) { return } + f2 := func() (ch chan int, x int) { return } + close(f0 /* ERROR used as value */ ()) + close(f1()) + close(f2()) // ERROR too many arguments +} + +func complex1() { + var i32 int32 + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + _ = complex() // ERROR not enough arguments + _ = complex(1) // ERROR not enough arguments + _ = complex(true /* ERROR mismatched types */ , 0) + _ = complex(i32 /* ERROR expected floating-point */ , 0) + _ = complex("foo" /* ERROR mismatched types */ , 0) + _ = complex(c64 /* ERROR expected floating-point */ , 0) + _ = complex(0 /* ERROR mismatched types */ , true) + _ = complex(0 /* ERROR expected floating-point */ , i32) + _ = complex(0 /* ERROR mismatched types */ , "foo") + _ = complex(0 /* ERROR expected floating-point */ , c64) + _ = complex(f32, f32) + _ = complex(f32, 1) + _ = complex(f32, 1.0) + _ = complex(f32, 'a') + _ = complex(f64, f64) + _ = complex(f64, 1) + _ = complex(f64, 1.0) + _ = complex(f64, 'a') + _ = complex(f32 /* ERROR mismatched types */ , f64) + _ = complex(f64 /* ERROR mismatched types */ , f32) + _ = complex(1, 1) + _ = complex(1, 1.1) + _ = complex(1, 'a') + complex /* ERROR not used */ (1, 2) + + var _ complex64 = complex(f32, f32) + var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64) + + var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32) + var _ complex128 = complex(f64, f64) + + // untyped constants + const _ int = complex(1, 0) + const _ float32 = complex(1, 0) + const _ complex64 = complex(1, 0) + const _ complex128 = complex(1, 0) + const _ = complex(0i, 0i) + const _ = complex(0i, 0) + const _ int = 1.0 + complex(1, 0i) + + const _ int = complex /* ERROR int */ (1.1, 0) + const _ float32 = complex /* ERROR float32 */ (1, 2) + + // untyped values + var s uint + _ = complex(1 /* ERROR integer */ <<s, 0) + const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0) + var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0) + + // floating-point argument types must be identical + type F32 float32 + type F64 float64 + var x32 F32 + var x64 F64 + c64 = complex(x32, x32) + _ = complex(x32 /* ERROR mismatched types */ , f32) + _ = complex(f32 /* ERROR mismatched types */ , x32) + c128 = complex(x64, x64) + _ = c128 + _ = complex(x64 /* ERROR mismatched types */ , f64) + _ = complex(f64 /* ERROR mismatched types */ , x64) + + var t []float32 + _ = complex(t... /* ERROR invalid use of \.\.\. */ ) +} + +func complex2() { + f1 := func() (x float32) { return } + f2 := func() (x, y float32) { return } + f3 := func() (x, y, z float32) { return } + _ = complex(f0 /* ERROR used as value */ ()) + _ = complex(f1()) // ERROR not enough arguments + _ = complex(f2()) + _ = complex(f3()) // ERROR too many arguments +} + +func copy1() { + copy() // ERROR not enough arguments + copy("foo") // ERROR not enough arguments + copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{}) + copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{}) + copy([ /* ERROR different element types */ ]int8{}, "foo") + + // spec examples + var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7} + var s = make([]int, 6) + var b = make([]byte, 5) + n1 := copy(s, a[0:]) // n1 == 6, s == []int{0, 1, 2, 3, 4, 5} + n2 := copy(s, s[2:]) // n2 == 4, s == []int{2, 3, 4, 5, 4, 5} + n3 := copy(b, "Hello, World!") // n3 == 5, b == []byte("Hello") + _, _, _ = n1, n2, n3 + + var t [][]int + copy(t, t) + copy(t /* ERROR copy expects slice arguments */ , nil) + copy(nil /* ERROR copy expects slice arguments */ , t) + copy(nil /* ERROR copy expects slice arguments */ , nil) + copy(t... /* ERROR invalid use of \.\.\. */ ) +} + +func copy2() { + f1 := func() (a []int) { return } + f2 := func() (a, b []int) { return } + f3 := func() (a, b, c []int) { return } + copy(f0 /* ERROR used as value */ ()) + copy(f1()) // ERROR not enough arguments + copy(f2()) + copy(f3()) // ERROR too many arguments +} + +func delete1() { + var m map[string]int + var s string + delete() // ERROR not enough arguments + delete(1) // ERROR not enough arguments + delete(1, 2, 3) // ERROR too many arguments + delete(m, 0 /* ERROR cannot use */) + delete(m, s) + _ = delete /* ERROR used as value */ (m, s) + + var t []map[string]string + delete(t... /* ERROR invalid use of \.\.\. */ ) +} + +func delete2() { + f1 := func() (m map[string]int) { return } + f2 := func() (m map[string]int, k string) { return } + f3 := func() (m map[string]int, k string, x float32) { return } + delete(f0 /* ERROR used as value */ ()) + delete(f1()) // ERROR not enough arguments + delete(f2()) + delete(f3()) // ERROR too many arguments +} + +func imag1() { + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + _ = imag() // ERROR not enough arguments + _ = imag(1, 2) // ERROR too many arguments + _ = imag(10) + _ = imag(2.7182818) + _ = imag("foo" /* ERROR expected complex */) + _ = imag('a') + const _5 = imag(1 + 2i) + assert(_5 == 2) + f32 = _5 + f64 = _5 + const _6 = imag(0i) + assert(_6 == 0) + f32 = imag(c64) + f64 = imag(c128) + f32 = imag /* ERROR cannot use .* in assignment */ (c128) + f64 = imag /* ERROR cannot use .* in assignment */ (c64) + imag /* ERROR not used */ (c64) + _, _ = f32, f64 + + // complex type may not be predeclared + type C64 complex64 + type C128 complex128 + var x64 C64 + var x128 C128 + f32 = imag(x64) + f64 = imag(x128) + + var a []complex64 + _ = imag(a... /* ERROR invalid use of \.\.\. */ ) + + // if argument is untyped, result is untyped + const _ byte = imag(1.2 + 3i) + const _ complex128 = imag(1.2 + 3i) + + // lhs constant shift operands are typed as complex128 + var s uint + _ = imag(1 /* ERROR must be integer */ << s) +} + +func imag2() { + f1 := func() (x complex128) { return } + f2 := func() (x, y complex128) { return } + _ = imag(f0 /* ERROR used as value */ ()) + _ = imag(f1()) + _ = imag(f2()) // ERROR too many arguments +} + +func len1() { + const c = "foobar" + var a [10]bool + var p *[20]int + var m map[string]complex128 + _ = len() // ERROR not enough arguments + _ = len(1, 2) // ERROR too many arguments + _ = len(42 /* ERROR invalid */) + const _3 = len(c) + assert(_3 == 6) + const _4 = len(a) + assert(_4 == 10) + const _5 = len(p) + assert(_5 == 20) + _ = len(m) + len /* ERROR not used */ (c) + + // esoteric case + var t string + var hash map[interface{}][]*[10]int + const n = len /* ERROR not constant */ (hash[recover()][len(t)]) + assert(n == 10) // ok because n has unknown value and no error is reported + var ch <-chan int + const nn = len /* ERROR not constant */ (hash[<-ch][len(t)]) + + // issue 4744 + type T struct{ a [10]int } + const _ = len(((*T)(nil)).a) + + var s [][]byte + _ = len(s) + _ = len(s... /* ERROR invalid use of \.\.\. */ ) +} + +func len2() { + f1 := func() (x []int) { return } + f2 := func() (x, y []int) { return } + _ = len(f0 /* ERROR used as value */ ()) + _ = len(f1()) + _ = len(f2()) // ERROR too many arguments +} + +// test cases for issue 7387 +func len3() { + var f = func() int { return 0 } + var x = f() + const ( + _ = len([4]int{}) + _ = len([4]int{x}) + _ = len /* ERROR not constant */ ([4]int{f()}) + _ = len /* ERROR not constant */ ([4]int{len([]int{})}) + _ = len([4]int{len([4]int{})}) + ) + var y float64 + var z complex128 + const ( + _ = len([4]float64{}) + _ = len([4]float64{y}) + _ = len([4]float64{real(2i)}) + _ = len /* ERROR not constant */ ([4]float64{real(z)}) + ) + var ch chan [10]int + const ( + _ = len /* ERROR not constant */ (<-ch) + _ = len /* ERROR not constant */ ([4]int{(<-ch)[0]}) + ) +} + +func make1() { + var n int + var m float32 + var s uint + + _ = make() // ERROR not enough arguments + _ = make(1 /* ERROR not a type */) + _ = make(int /* ERROR cannot make */) + + // slices + _ = make/* ERROR arguments */ ([]int) + _ = make/* ERROR arguments */ ([]int, 2, 3, 4) + _ = make([]int, int /* ERROR not an expression */) + _ = make([]int, 10, float32 /* ERROR not an expression */) + _ = make([]int, "foo" /* ERROR cannot convert */) + _ = make([]int, 10, 2.3 /* ERROR truncated */) + _ = make([]int, 5, 10.0) + _ = make([]int, 0i) + _ = make([]int, 1.0) + _ = make([]int, 1.0<<s) + _ = make([]int, 1.1 /* ERROR int */ <<s) + _ = make([]int, - /* ERROR must not be negative */ 1, 10) + _ = make([]int, 0, - /* ERROR must not be negative */ 1) + _ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1) + _ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100) + _ = make([]int, 10 /* ERROR length and capacity swapped */ , 9) + _ = make([]int, 1 /* ERROR overflows */ <<100, 12345) + _ = make([]int, m /* ERROR must be integer */ ) + _ = &make /* ERROR cannot take address */ ([]int, 0) + + // maps + _ = make /* ERROR arguments */ (map[int]string, 10, 20) + _ = make(map[int]float32, int /* ERROR not an expression */) + _ = make(map[int]float32, "foo" /* ERROR cannot convert */) + _ = make(map[int]float32, 10) + _ = make(map[int]float32, n) + _ = make(map[int]float32, int64(n)) + _ = make(map[string]bool, 10.0) + _ = make(map[string]bool, 10.0<<s) + _ = &make /* ERROR cannot take address */ (map[string]bool) + + // channels + _ = make /* ERROR arguments */ (chan int, 10, 20) + _ = make(chan int, int /* ERROR not an expression */) + _ = make(chan<- int, "foo" /* ERROR cannot convert */) + _ = make(chan int, - /* ERROR must not be negative */ 10) + _ = make(<-chan float64, 10) + _ = make(chan chan int, n) + _ = make(chan string, int64(n)) + _ = make(chan bool, 10.0) + _ = make(chan bool, 10.0<<s) + _ = &make /* ERROR cannot take address */ (chan bool) + + make /* ERROR not used */ ([]int, 10) + + var t []int + _ = make([]int, t[0], t[1]) + _ = make([]int, t... /* ERROR invalid use of \.\.\. */ ) +} + +func make2() { + f1 := func() (x []int) { return } + _ = make(f0 /* ERROR not a type */ ()) + _ = make(f1 /* ERROR not a type */ ()) +} + +func new1() { + _ = new() // ERROR not enough arguments + _ = new(1, 2) // ERROR too many arguments + _ = new("foo" /* ERROR not a type */) + p := new(float64) + _ = new(struct{ x, y int }) + q := new(*float64) + _ = *p == **q + new /* ERROR not used */ (int) + _ = &new /* ERROR cannot take address */ (int) + + _ = new(int... /* ERROR invalid use of \.\.\. */ ) +} + +func new2() { + f1 := func() (x []int) { return } + _ = new(f0 /* ERROR not a type */ ()) + _ = new(f1 /* ERROR not a type */ ()) +} + +func panic1() { + panic() // ERROR not enough arguments + panic(1, 2) // ERROR too many arguments + panic(0) + panic("foo") + panic(false) + panic(1<<10) + panic(1 << /* ERROR constant shift overflow */ 1000) + _ = panic /* ERROR used as value */ (0) + + var s []byte + panic(s) + panic(s... /* ERROR invalid use of \.\.\. */ ) +} + +func panic2() { + f1 := func() (x int) { return } + f2 := func() (x, y int) { return } + panic(f0 /* ERROR used as value */ ()) + panic(f1()) + panic(f2()) // ERROR too many arguments +} + +func print1() { + print() + print(1) + print(1, 2) + print("foo") + print(2.718281828) + print(false) + print(1<<10) + print(1 << /* ERROR constant shift overflow */ 1000) + println(nil /* ERROR untyped nil */ ) + + var s []int + print(s... /* ERROR invalid use of \.\.\. */ ) + _ = print /* ERROR used as value */ () +} + +func print2() { + f1 := func() (x int) { return } + f2 := func() (x, y int) { return } + f3 := func() (x int, y float32, z string) { return } + print(f0 /* ERROR used as value */ ()) + print(f1()) + print(f2()) + print(f3()) +} + +func println1() { + println() + println(1) + println(1, 2) + println("foo") + println(2.718281828) + println(false) + println(1<<10) + println(1 << /* ERROR constant shift overflow */ 1000) + println(nil /* ERROR untyped nil */ ) + + var s []int + println(s... /* ERROR invalid use of \.\.\. */ ) + _ = println /* ERROR used as value */ () +} + +func println2() { + f1 := func() (x int) { return } + f2 := func() (x, y int) { return } + f3 := func() (x int, y float32, z string) { return } + println(f0 /* ERROR used as value */ ()) + println(f1()) + println(f2()) + println(f3()) +} + +func real1() { + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + _ = real() // ERROR not enough arguments + _ = real(1, 2) // ERROR too many arguments + _ = real(10) + _ = real(2.7182818) + _ = real("foo" /* ERROR expected complex */) + const _5 = real(1 + 2i) + assert(_5 == 1) + f32 = _5 + f64 = _5 + const _6 = real(0i) + assert(_6 == 0) + f32 = real(c64) + f64 = real(c128) + f32 = real /* ERROR cannot use .* in assignment */ (c128) + f64 = real /* ERROR cannot use .* in assignment */ (c64) + real /* ERROR not used */ (c64) + + // complex type may not be predeclared + type C64 complex64 + type C128 complex128 + var x64 C64 + var x128 C128 + f32 = imag(x64) + f64 = imag(x128) + _, _ = f32, f64 + + var a []complex64 + _ = real(a... /* ERROR invalid use of \.\.\. */ ) + + // if argument is untyped, result is untyped + const _ byte = real(1 + 2.3i) + const _ complex128 = real(1 + 2.3i) + + // lhs constant shift operands are typed as complex128 + var s uint + _ = real(1 /* ERROR must be integer */ << s) +} + +func real2() { + f1 := func() (x complex128) { return } + f2 := func() (x, y complex128) { return } + _ = real(f0 /* ERROR used as value */ ()) + _ = real(f1()) + _ = real(f2()) // ERROR too many arguments +} + +func recover1() { + _ = recover() + _ = recover(10) // ERROR too many arguments + recover() + + var s []int + recover(s... /* ERROR invalid use of \.\.\. */ ) +} + +func recover2() { + f1 := func() (x int) { return } + f2 := func() (x, y int) { return } + _ = recover(f0 /* ERROR used as value */ ()) + _ = recover(f1()) // ERROR too many arguments + _ = recover(f2()) // ERROR too many arguments +} + +// assuming types.DefaultPtrSize == 8 +type S0 struct{ // offset + a bool // 0 + b rune // 4 + c *int // 8 + d bool // 16 + e complex128 // 24 +} // 40 + +type S1 struct{ // offset + x float32 // 0 + y string // 8 + z *S1 // 24 + S0 // 32 +} // 72 + +type S2 struct{ // offset + *S1 // 0 +} // 8 + +type S3 struct { // offset + a int64 // 0 + b int32 // 8 +} // 12 + +type S4 struct { // offset + S3 // 0 + int32 // 12 +} // 16 + +type S5 struct { // offset + a [3]int32 // 0 + b int32 // 12 +} // 16 + +func (S2) m() {} + +func Alignof1() { + var x int + _ = unsafe.Alignof() // ERROR not enough arguments + _ = unsafe.Alignof(1, 2) // ERROR too many arguments + _ = unsafe.Alignof(int /* ERROR not an expression */) + _ = unsafe.Alignof(42) + _ = unsafe.Alignof(new(struct{})) + _ = unsafe.Alignof(1<<10) + _ = unsafe.Alignof(1 << /* ERROR constant shift overflow */ 1000) + _ = unsafe.Alignof(nil /* ERROR "untyped nil */ ) + unsafe /* ERROR not used */ .Alignof(x) + + var y S0 + assert(unsafe.Alignof(y.a) == 1) + assert(unsafe.Alignof(y.b) == 4) + assert(unsafe.Alignof(y.c) == 8) + assert(unsafe.Alignof(y.d) == 1) + assert(unsafe.Alignof(y.e) == 8) + + var s []byte + _ = unsafe.Alignof(s) + _ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ ) +} + +func Alignof2() { + f1 := func() (x int32) { return } + f2 := func() (x, y int32) { return } + _ = unsafe.Alignof(f0 /* ERROR used as value */ ()) + assert(unsafe.Alignof(f1()) == 4) + _ = unsafe.Alignof(f2()) // ERROR too many arguments +} + +func Offsetof1() { + var x struct{ f int } + _ = unsafe.Offsetof() // ERROR not enough arguments + _ = unsafe.Offsetof(1, 2) // ERROR too many arguments + _ = unsafe.Offsetof(int /* ERROR not a selector expression */ ) + _ = unsafe.Offsetof(x /* ERROR not a selector expression */ ) + _ = unsafe.Offsetof(nil /* ERROR not a selector expression */ ) + _ = unsafe.Offsetof(x.f) + _ = unsafe.Offsetof((x.f)) + _ = unsafe.Offsetof((((((((x))).f))))) + unsafe /* ERROR not used */ .Offsetof(x.f) + + var y0 S0 + assert(unsafe.Offsetof(y0.a) == 0) + assert(unsafe.Offsetof(y0.b) == 4) + assert(unsafe.Offsetof(y0.c) == 8) + assert(unsafe.Offsetof(y0.d) == 16) + assert(unsafe.Offsetof(y0.e) == 24) + + var y1 S1 + assert(unsafe.Offsetof(y1.x) == 0) + assert(unsafe.Offsetof(y1.y) == 8) + assert(unsafe.Offsetof(y1.z) == 24) + assert(unsafe.Offsetof(y1.S0) == 32) + + assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0 + assert(unsafe.Offsetof(y1.a) == 32) // relative to S1 + assert(unsafe.Offsetof(y1.b) == 36) // relative to S1 + assert(unsafe.Offsetof(y1.c) == 40) // relative to S1 + assert(unsafe.Offsetof(y1.d) == 48) // relative to S1 + assert(unsafe.Offsetof(y1.e) == 56) // relative to S1 + + var y1p *S1 + assert(unsafe.Offsetof(y1p.S0) == 32) + + type P *S1 + var p P = y1p + assert(unsafe.Offsetof(p.S0) == 32) + + var y2 S2 + assert(unsafe.Offsetof(y2.S1) == 0) + _ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x) + _ = unsafe.Offsetof(y2 /* ERROR method value */ .m) + + var s []byte + _ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ ) +} + +func Offsetof2() { + f1 := func() (x int32) { return } + f2 := func() (x, y int32) { return } + _ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ()) + _ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ()) + _ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ()) +} + +func Sizeof1() { + var x int + _ = unsafe.Sizeof() // ERROR not enough arguments + _ = unsafe.Sizeof(1, 2) // ERROR too many arguments + _ = unsafe.Sizeof(int /* ERROR not an expression */) + _ = unsafe.Sizeof(42) + _ = unsafe.Sizeof(new(complex128)) + _ = unsafe.Sizeof(1<<10) + _ = unsafe.Sizeof(1 << /* ERROR constant shift overflow */ 1000) + _ = unsafe.Sizeof(nil /* ERROR untyped nil */ ) + unsafe /* ERROR not used */ .Sizeof(x) + + // basic types have size guarantees + assert(unsafe.Sizeof(byte(0)) == 1) + assert(unsafe.Sizeof(uint8(0)) == 1) + assert(unsafe.Sizeof(int8(0)) == 1) + assert(unsafe.Sizeof(uint16(0)) == 2) + assert(unsafe.Sizeof(int16(0)) == 2) + assert(unsafe.Sizeof(uint32(0)) == 4) + assert(unsafe.Sizeof(int32(0)) == 4) + assert(unsafe.Sizeof(float32(0)) == 4) + assert(unsafe.Sizeof(uint64(0)) == 8) + assert(unsafe.Sizeof(int64(0)) == 8) + assert(unsafe.Sizeof(float64(0)) == 8) + assert(unsafe.Sizeof(complex64(0)) == 8) + assert(unsafe.Sizeof(complex128(0)) == 16) + + var y0 S0 + assert(unsafe.Sizeof(y0.a) == 1) + assert(unsafe.Sizeof(y0.b) == 4) + assert(unsafe.Sizeof(y0.c) == 8) + assert(unsafe.Sizeof(y0.d) == 1) + assert(unsafe.Sizeof(y0.e) == 16) + assert(unsafe.Sizeof(y0) == 40) + + var y1 S1 + assert(unsafe.Sizeof(y1) == 72) + + var y2 S2 + assert(unsafe.Sizeof(y2) == 8) + + var y3 S3 + assert(unsafe.Sizeof(y3) == 12) + + var y4 S4 + assert(unsafe.Sizeof(y4) == 16) + + var y5 S5 + assert(unsafe.Sizeof(y5) == 16) + + var a3 [10]S3 + assert(unsafe.Sizeof(a3) == 156) + + // test case for issue 5670 + type T struct { + a int32 + _ int32 + c int32 + } + assert(unsafe.Sizeof(T{}) == 12) + + var s []byte + _ = unsafe.Sizeof(s) + _ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ ) +} + +func Sizeof2() { + f1 := func() (x int64) { return } + f2 := func() (x, y int64) { return } + _ = unsafe.Sizeof(f0 /* ERROR used as value */ ()) + assert(unsafe.Sizeof(f1()) == 8) + _ = unsafe.Sizeof(f2()) // ERROR too many arguments +} + +func Slice1() { + var x int + unsafe.Slice() // ERROR not enough arguments + unsafe.Slice(1, 2, 3) // ERROR too many arguments + unsafe.Slice(1 /* ERROR is not a pointer */ , 2) + unsafe.Slice(nil /* ERROR nil is not a pointer */ , 0) + unsafe.Slice(&x, "foo" /* ERROR cannot convert .* to type int */ ) + unsafe.Slice(&x, 1.2 /* ERROR truncated to int */ ) + unsafe.Slice(&x, - /* ERROR must not be negative */ 1) + unsafe /* ERROR not used */ .Slice(&x, 0) + var _ []byte = unsafe /* ERROR value of type \[\]int */ .Slice(&x, 0) + + var _ []int = unsafe.Slice(&x, 0) + _ = unsafe.Slice(&x, 1.0) + _ = unsafe.Slice((*int)(nil), 0) +} + +func SliceData1() { + var s []int + unsafe.SliceData(0 /* ERROR not a slice */) + unsafe /* ERROR not used */ .SliceData(s) + + type S []int + _ = unsafe.SliceData(s) + _ = unsafe.SliceData(S{}) +} + +func String1() { + var b byte + unsafe.String() // ERROR not enough arguments + unsafe.String(1, 2, 3) // ERROR too many arguments + unsafe.String(1 /* ERROR cannot use 1 */ , 2) + unsafe.String(&b, "foo" /* ERROR cannot convert .* to type int */ ) + unsafe.String(&b, 1.2 /* ERROR truncated to int */ ) + unsafe.String(&b, - /* ERROR must not be negative */ 1) + unsafe /* ERROR not used */ .String(&b, 0) + var _ []byte = unsafe /* ERROR value of type string */ .String(&b, 0) + + var _ string = unsafe.String(&b, 0) + _ = unsafe.String(&b, 1.0) + _ = unsafe.String(nil, 0) // here we allow nil as ptr argument (in contrast to unsafe.Slice) +} + +func StringData1() { + var s string + type S string + unsafe.StringData(0 /* ERROR cannot use 0 */) + unsafe.StringData(S /* ERROR cannot use S */ ("foo")) + unsafe /* ERROR not used */ .StringData(s) + + _ = unsafe.StringData(s) + _ = unsafe.StringData("foo") +} + +// self-testing only +func assert1() { + var x int + assert() /* ERROR not enough arguments */ + assert(1, 2) /* ERROR too many arguments */ + assert("foo" /* ERROR boolean constant */ ) + assert(x /* ERROR boolean constant */) + assert(true) + assert /* ERROR failed */ (false) + _ = assert(true) + + var s []byte + assert(s... /* ERROR invalid use of \.\.\. */ ) +} + +func assert2() { + f1 := func() (x bool) { return } + f2 := func() (x bool) { return } + assert(f0 /* ERROR used as value */ ()) + assert(f1 /* ERROR boolean constant */ ()) + assert(f2 /* ERROR boolean constant */ ()) +} + +// self-testing only +func trace1() { + // Uncomment the code below to test trace - will produce console output + // _ = trace /* ERROR no value */ () + // _ = trace(1) + // _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar") + + var s []byte + trace(s... /* ERROR invalid use of \.\.\. */ ) +} + +func trace2() { + f1 := func() (x int) { return } + f2 := func() (x int, y string) { return } + f3 := func() (x int, y string, z []int) { return } + _ = f1 + _ = f2 + _ = f3 + // Uncomment the code below to test trace - will produce console output + // trace(f0()) + // trace(f1()) + // trace(f2()) + // trace(f3()) + // trace(f0(), 1) + // trace(f1(), 1, 2) + // trace(f2(), 1, 2, 3) + // trace(f3(), 1, 2, 3, 4) +} diff --git a/src/internal/types/testdata/check/builtins1.go b/src/internal/types/testdata/check/builtins1.go new file mode 100644 index 0000000..3348861 --- /dev/null +++ b/src/internal/types/testdata/check/builtins1.go @@ -0,0 +1,288 @@ +// 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 tests built-in calls on generic types. + +package builtins + +import "unsafe" + +// clear + +func _[T any](x T) { + clear(x /* ERROR cannot clear x */) +} + +func _[T ~map[int]string | ~[]byte | ~*[10]int](x T) { + clear(x) +} + +func _[T ~map[int]string | ~[]byte | ~*[10]int | string](x T) { + clear(x /* ERROR cannot clear x */) +} + +// close + +type C0 interface{ int } +type C1 interface{ chan int } +type C2 interface{ chan int | <-chan int } +type C3 interface{ chan int | chan float32 } +type C4 interface{ chan int | chan<- int } +type C5[T any] interface{ ~chan T | chan<- T } + +func _[T any](ch T) { + close(ch /* ERROR cannot close non-channel */) +} + +func _[T C0](ch T) { + close(ch /* ERROR cannot close non-channel */) +} + +func _[T C1](ch T) { + close(ch) +} + +func _[T C2](ch T) { + close(ch /* ERROR cannot close receive-only channel */) +} + +func _[T C3](ch T) { + close(ch) +} + +func _[T C4](ch T) { + close(ch) +} + +func _[T C5[X], X any](ch T) { + close(ch) +} + +// copy + +func _[T any](x, y T) { + copy(x /* ERROR copy expects slice arguments */ , y) +} + +func _[T ~[]byte](x, y T) { + copy(x, y) + copy(x, "foo") + copy("foo" /* ERROR expects slice arguments */ , y) + + var x2 []byte + copy(x2, y) // element types are identical + copy(y, x2) // element types are identical + + type myByte byte + var x3 []myByte + copy(x3 /* ERROR different element types */ , y) + copy(y /* ERROR different element types */ , x3) +} + +func _[T ~[]E, E any](x T, y []E) { + copy(x, y) + copy(x /* ERROR different element types */ , "foo") +} + +func _[T ~string](x []byte, y T) { + copy(x, y) + copy(y /* ERROR expects slice arguments */ , x) +} + +func _[T ~[]byte|~string](x T, y []byte) { + copy(x /* ERROR expects slice arguments */ , y) + copy(y, x) +} + +type L0 []int +type L1 []int + +func _[T L0 | L1](x, y T) { + copy(x, y) +} + +// delete + +type M0 interface{ int } +type M1 interface{ map[string]int } +type M2 interface { map[string]int | map[string]float64 } +type M3 interface{ map[string]int | map[rune]int } +type M4[K comparable, V any] interface{ map[K]V | map[rune]V } + +func _[T any](m T) { + delete(m /* ERROR not a map */, "foo") +} + +func _[T M0](m T) { + delete(m /* ERROR not a map */, "foo") +} + +func _[T M1](m T) { + delete(m, "foo") +} + +func _[T M2](m T) { + delete(m, "foo") + delete(m, 0 /* ERROR cannot use .* as string */) +} + +func _[T M3](m T) { + delete(m /* ERROR must have identical key types */, "foo") +} + +func _[T M4[rune, V], V any](m T) { + delete(m, 'k') +} + +func _[T M4[K, V], K comparable, V any](m T) { + delete(m /* ERROR must have identical key types */, "foo") +} + +// make + +type myChan chan int + +func _[ + S1 ~[]int, + S2 ~[]int | ~chan int, + + M1 ~map[string]int, + M2 ~map[string]int | ~chan int, + + C1 ~chan int, + C2 ~chan int | ~chan string, + C3 chan int | myChan, // single underlying type +]() { + type S0 []int + _ = make([]int, 10) + _ = make(S0, 10) + _ = make(S1, 10) + _ = make() /* ERROR not enough arguments */ + _ = make /* ERROR expects 2 or 3 arguments */ (S1) + _ = make(S1, 10, 20) + _ = make /* ERROR expects 2 or 3 arguments */ (S1, 10, 20, 30) + _ = make(S2 /* ERROR cannot make S2: no core type */ , 10) + + type M0 map[string]int + _ = make(map[string]int) + _ = make(M0) + _ = make(M1) + _ = make(M1, 10) + _ = make/* ERROR expects 1 or 2 arguments */(M1, 10, 20) + _ = make(M2 /* ERROR cannot make M2: no core type */ ) + + type C0 chan int + _ = make(chan int) + _ = make(C0) + _ = make(C1) + _ = make(C1, 10) + _ = make/* ERROR expects 1 or 2 arguments */(C1, 10, 20) + _ = make(C2 /* ERROR cannot make C2: no core type */ ) + _ = make(C3) +} + +// unsafe.Alignof + +func _[T comparable]() { + var ( + b int64 + a [10]T + s struct{ f T } + p *T + l []T + f func(T) + i interface{ m() T } + c chan T + m map[T]T + t T + ) + + const bb = unsafe.Alignof(b) + assert(bb == 8) + const _ = unsafe /* ERROR not constant */ .Alignof(a) + const _ = unsafe /* ERROR not constant */ .Alignof(s) + const pp = unsafe.Alignof(p) + assert(pp == 8) + const ll = unsafe.Alignof(l) + assert(ll == 8) + const ff = unsafe.Alignof(f) + assert(ff == 8) + const ii = unsafe.Alignof(i) + assert(ii == 8) + const cc = unsafe.Alignof(c) + assert(cc == 8) + const mm = unsafe.Alignof(m) + assert(mm == 8) + const _ = unsafe /* ERROR not constant */ .Alignof(t) +} + +// unsafe.Offsetof + +func _[T comparable]() { + var ( + b struct{ _, f int64 } + a struct{ _, f [10]T } + s struct{ _, f struct{ f T } } + p struct{ _, f *T } + l struct{ _, f []T } + f struct{ _, f func(T) } + i struct{ _, f interface{ m() T } } + c struct{ _, f chan T } + m struct{ _, f map[T]T } + t struct{ _, f T } + ) + + const bb = unsafe.Offsetof(b.f) + assert(bb == 8) + const _ = unsafe /* ERROR not constant */ .Alignof(a) + const _ = unsafe /* ERROR not constant */ .Alignof(s) + const pp = unsafe.Offsetof(p.f) + assert(pp == 8) + const ll = unsafe.Offsetof(l.f) + assert(ll == 24) + const ff = unsafe.Offsetof(f.f) + assert(ff == 8) + const ii = unsafe.Offsetof(i.f) + assert(ii == 16) + const cc = unsafe.Offsetof(c.f) + assert(cc == 8) + const mm = unsafe.Offsetof(m.f) + assert(mm == 8) + const _ = unsafe /* ERROR not constant */ .Alignof(t) +} + +// unsafe.Sizeof + +func _[T comparable]() { + var ( + b int64 + a [10]T + s struct{ f T } + p *T + l []T + f func(T) + i interface{ m() T } + c chan T + m map[T]T + t T + ) + + const bb = unsafe.Sizeof(b) + assert(bb == 8) + const _ = unsafe /* ERROR not constant */ .Alignof(a) + const _ = unsafe /* ERROR not constant */ .Alignof(s) + const pp = unsafe.Sizeof(p) + assert(pp == 8) + const ll = unsafe.Sizeof(l) + assert(ll == 24) + const ff = unsafe.Sizeof(f) + assert(ff == 8) + const ii = unsafe.Sizeof(i) + assert(ii == 16) + const cc = unsafe.Sizeof(c) + assert(cc == 8) + const mm = unsafe.Sizeof(m) + assert(mm == 8) + const _ = unsafe /* ERROR not constant */ .Alignof(t) +} diff --git a/src/internal/types/testdata/check/chans.go b/src/internal/types/testdata/check/chans.go new file mode 100644 index 0000000..fad2bce --- /dev/null +++ b/src/internal/types/testdata/check/chans.go @@ -0,0 +1,62 @@ +package chans + +import "runtime" + +// Ranger returns a Sender and a Receiver. The Receiver provides a +// Next method to retrieve values. The Sender provides a Send method +// to send values and a Close method to stop sending values. The Next +// method indicates when the Sender has been closed, and the Send +// method indicates when the Receiver has been freed. +// +// This is a convenient way to exit a goroutine sending values when +// the receiver stops reading them. +func Ranger[T any]() (*Sender[T], *Receiver[T]) { + c := make(chan T) + d := make(chan bool) + s := &Sender[T]{values: c, done: d} + r := &Receiver[T]{values: c, done: d} + runtime.SetFinalizer(r, r.finalize) + return s, r +} + +// A sender is used to send values to a Receiver. +type Sender[T any] struct { + values chan<- T + done <-chan bool +} + +// Send sends a value to the receiver. It returns whether any more +// values may be sent; if it returns false the value was not sent. +func (s *Sender[T]) Send(v T) bool { + select { + case s.values <- v: + return true + case <-s.done: + return false + } +} + +// Close tells the receiver that no more values will arrive. +// After Close is called, the Sender may no longer be used. +func (s *Sender[T]) Close() { + close(s.values) +} + +// A Receiver receives values from a Sender. +type Receiver[T any] struct { + values <-chan T + done chan<- bool +} + +// Next returns the next value from the channel. The bool result +// indicates whether the value is valid, or whether the Sender has +// been closed and no more values will be received. +func (r *Receiver[T]) Next() (T, bool) { + v, ok := <-r.values + return v, ok +} + +// finalize is a finalizer for the receiver. +func (r *Receiver[T]) finalize() { + close(r.done) +} diff --git a/src/internal/types/testdata/check/compliterals.go b/src/internal/types/testdata/check/compliterals.go new file mode 100644 index 0000000..60eac97 --- /dev/null +++ b/src/internal/types/testdata/check/compliterals.go @@ -0,0 +1,22 @@ +// Copyright 2012 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. + +// Composite literals with parameterized types + +package comp_literals + +type myStruct struct { + f int +} + +type slice[E any] []E + +func struct_literals[S struct{f int}|myStruct]() { + _ = S{} + _ = S{0} + _ = S{f: 0} + + _ = slice[int]{1, 2, 3} + _ = slice[S]{{}, {0}, {f:0}} +} diff --git a/src/internal/types/testdata/check/const0.go b/src/internal/types/testdata/check/const0.go new file mode 100644 index 0000000..402e6cf --- /dev/null +++ b/src/internal/types/testdata/check/const0.go @@ -0,0 +1,382 @@ +// Copyright 2012 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. + +// constant declarations + +package const0 + +import "unsafe" + +// constants declarations must be initialized by constants +var x = 0 +const c0 = x /* ERROR "not constant" */ + +// typed constants must have constant types +const _ interface /* ERROR invalid constant type */ {} = 0 + +func _ () { + const _ interface /* ERROR invalid constant type */ {} = 0 + for i := 0; i < 10; i++ {} // don't crash with non-nil iota here +} + +// untyped constants +const ( + // boolean values + ub0 = false + ub1 = true + ub2 = 2 < 1 + ub3 = ui1 == uf1 + ub4 = true == 0 /* ERROR "mismatched types untyped bool and untyped int" */ + + // integer values + ui0 = 0 + ui1 = 1 + ui2 = 42 + ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286 + ui4 = -10 + + ui5 = ui0 + ui1 + ui6 = ui1 - ui1 + ui7 = ui2 * ui1 + ui8 = ui3 / ui3 + ui9 = ui3 % ui3 + + ui10 = 1 / 0 /* ERROR "division by zero" */ + ui11 = ui1 / 0 /* ERROR "division by zero" */ + ui12 = ui3 / ui0 /* ERROR "division by zero" */ + ui13 = 1 % 0 /* ERROR "division by zero" */ + ui14 = ui1 % 0 /* ERROR "division by zero" */ + ui15 = ui3 % ui0 /* ERROR "division by zero" */ + + ui16 = ui2 & ui3 + ui17 = ui2 | ui3 + ui18 = ui2 ^ ui3 + ui19 = 1 /* ERROR "invalid operation" */ % 1.0 + + // floating point values + uf0 = 0. + uf1 = 1. + uf2 = 4.2e1 + uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286 + uf4 = 1e-1 + + uf5 = uf0 + uf1 + uf6 = uf1 - uf1 + uf7 = uf2 * uf1 + uf8 = uf3 / uf3 + uf9 = uf3 /* ERROR "not defined" */ % uf3 + + uf10 = 1 / 0 /* ERROR "division by zero" */ + uf11 = uf1 / 0 /* ERROR "division by zero" */ + uf12 = uf3 / uf0 /* ERROR "division by zero" */ + + uf16 = uf2 /* ERROR "not defined" */ & uf3 + uf17 = uf2 /* ERROR "not defined" */ | uf3 + uf18 = uf2 /* ERROR "not defined" */ ^ uf3 + + // complex values + uc0 = 0.i + uc1 = 1.i + uc2 = 4.2e1i + uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i + uc4 = 1e-1i + + uc5 = uc0 + uc1 + uc6 = uc1 - uc1 + uc7 = uc2 * uc1 + uc8 = uc3 / uc3 + uc9 = uc3 /* ERROR "not defined" */ % uc3 + + uc10 = 1 / 0 /* ERROR "division by zero" */ + uc11 = uc1 / 0 /* ERROR "division by zero" */ + uc12 = uc3 / uc0 /* ERROR "division by zero" */ + + uc16 = uc2 /* ERROR "not defined" */ & uc3 + uc17 = uc2 /* ERROR "not defined" */ | uc3 + uc18 = uc2 /* ERROR "not defined" */ ^ uc3 +) + +type ( + mybool bool + myint int + myfloat float64 + mycomplex complex128 +) + +// typed constants +const ( + // boolean values + tb0 bool = false + tb1 bool = true + tb2 mybool = 2 < 1 + tb3 mybool = ti1 == tf1 /* ERROR "mismatched types" */ + + // integer values + ti0 int8 = ui0 + ti1 int32 = ui1 + ti2 int64 = ui2 + ti3 myint = ui3 /* ERROR "overflows" */ + ti4 myint = ui4 + + ti5 = ti0 /* ERROR "mismatched types" */ + ti1 + ti6 = ti1 - ti1 + ti7 = ti2 /* ERROR "mismatched types" */ * ti1 + ti8 = ti3 / ti3 + ti9 = ti3 % ti3 + + ti10 = 1 / 0 /* ERROR "division by zero" */ + ti11 = ti1 / 0 /* ERROR "division by zero" */ + ti12 = ti3 /* ERROR "mismatched types" */ / ti0 + ti13 = 1 % 0 /* ERROR "division by zero" */ + ti14 = ti1 % 0 /* ERROR "division by zero" */ + ti15 = ti3 /* ERROR "mismatched types" */ % ti0 + + ti16 = ti2 /* ERROR "mismatched types" */ & ti3 + ti17 = ti2 /* ERROR "mismatched types" */ | ti4 + ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown + + // floating point values + tf0 float32 = 0. + tf1 float32 = 1. + tf2 float64 = 4.2e1 + tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286 + tf4 myfloat = 1e-1 + + tf5 = tf0 + tf1 + tf6 = tf1 - tf1 + tf7 = tf2 /* ERROR "mismatched types" */ * tf1 + tf8 = tf3 / tf3 + tf9 = tf3 /* ERROR "not defined" */ % tf3 + + tf10 = 1 / 0 /* ERROR "division by zero" */ + tf11 = tf1 / 0 /* ERROR "division by zero" */ + tf12 = tf3 /* ERROR "mismatched types" */ / tf0 + + tf16 = tf2 /* ERROR "mismatched types" */ & tf3 + tf17 = tf2 /* ERROR "mismatched types" */ | tf3 + tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3 + + // complex values + tc0 = 0.i + tc1 = 1.i + tc2 = 4.2e1i + tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i + tc4 = 1e-1i + + tc5 = tc0 + tc1 + tc6 = tc1 - tc1 + tc7 = tc2 * tc1 + tc8 = tc3 / tc3 + tc9 = tc3 /* ERROR "not defined" */ % tc3 + + tc10 = 1 / 0 /* ERROR "division by zero" */ + tc11 = tc1 / 0 /* ERROR "division by zero" */ + tc12 = tc3 / tc0 /* ERROR "division by zero" */ + + tc16 = tc2 /* ERROR "not defined" */ & tc3 + tc17 = tc2 /* ERROR "not defined" */ | tc3 + tc18 = tc2 /* ERROR "not defined" */ ^ tc3 +) + +// initialization cycles +const ( + a /* ERROR "initialization cycle" */ = a + b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error + f float64 = d +) + +// multiple initialization +const ( + a1, a2, a3 = 7, 3.1415926, "foo" + b1, b2, b3 = b3, b1, 42 + c1, c2, c3 /* ERROR "missing init expr for c3" */ = 1, 2 + d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */ + _p0 = assert(a1 == 7) + _p1 = assert(a2 == 3.1415926) + _p2 = assert(a3 == "foo") + _p3 = assert(b1 == 42) + _p4 = assert(b2 == 42) + _p5 = assert(b3 == 42) +) + +func _() { + const ( + a1, a2, a3 = 7, 3.1415926, "foo" + b1, b2, b3 = b3, b1, 42 + c1, c2, c3 /* ERROR "missing init expr for c3" */ = 1, 2 + d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */ + _p0 = assert(a1 == 7) + _p1 = assert(a2 == 3.1415926) + _p2 = assert(a3 == "foo") + _p3 = assert(b1 == 42) + _p4 = assert(b2 == 42) + _p5 = assert(b3 == 42) + ) +} + +// iota +const ( + iota0 = iota + iota1 = iota + iota2 = iota*2 + _a0 = assert(iota0 == 0) + _a1 = assert(iota1 == 1) + _a2 = assert(iota2 == 4) + iota6 = iota*3 + + iota7 + iota8 + _a3 = assert(iota7 == 21) + _a4 = assert(iota8 == 24) +) + +const ( + _b0 = iota + _b1 = assert(iota + iota2 == 5) + _b2 = len([iota]int{}) // iota may appear in a type! + _b3 = assert(_b2 == 2) + _b4 = len(A{}) +) + +type A [iota /* ERROR "cannot use iota" */ ]int + +// constant expressions with operands across different +// constant declarations must use the right iota values +const ( + _c0 = iota + _c1 + _c2 + _x = _c2 + _d1 + _e0 // 3 +) + +const ( + _d0 = iota + _d1 +) + +const ( + _e0 = iota +) + +var _ = assert(_x == 3) + +// special cases +const ( + _n0 = nil /* ERROR "not constant" */ + _n1 = [ /* ERROR "not constant" */ ]int{} +) + +// iotas must not be usable in expressions outside constant declarations +type _ [iota /* ERROR "iota outside constant decl" */ ]byte +var _ = iota /* ERROR "iota outside constant decl" */ +func _() { + _ = iota /* ERROR "iota outside constant decl" */ + const _ = iota + _ = iota /* ERROR "iota outside constant decl" */ +} + +func _() { + iota := 123 + const x = iota /* ERROR "is not constant" */ + var y = iota + _ = y +} + +// iotas are usable inside closures in constant declarations (#22345) +const ( + _ = iota + _ = len([iota]byte{}) + _ = unsafe.Sizeof(iota) + _ = unsafe.Sizeof(func() { _ = iota }) + _ = unsafe.Sizeof(func() { var _ = iota }) + _ = unsafe.Sizeof(func() { const _ = iota }) + _ = unsafe.Sizeof(func() { type _ [iota]byte }) + _ = unsafe.Sizeof(func() { func() int { return iota }() }) +) + +// verify inner and outer const declarations have distinct iotas +const ( + zero = iota + one = iota + _ = unsafe.Sizeof(func() { + var x [iota]int // [2]int + const ( + Zero = iota + One + Two + _ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal + _ = unsafe.Sizeof([Two]int{} == x) // assert types are equal + ) + var z [iota]int // [2]int + _ = unsafe.Sizeof([2]int{} == z) // assert types are equal + }) + three = iota // the sequence continues +) +var _ [three]int = [3]int{} // assert 'three' has correct value + +var ( + _ = iota /* ERROR "iota outside constant decl" */ + _ = unsafe.Sizeof(iota /* ERROR "iota outside constant decl" */ ) + _ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ }) + _ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ }) + _ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte }) + _ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() }) +) + +// constant arithmetic precision and rounding must lead to expected (integer) results +var _ = []int64{ + 0.0005 * 1e9, + 0.001 * 1e9, + 0.005 * 1e9, + 0.01 * 1e9, + 0.05 * 1e9, + 0.1 * 1e9, + 0.5 * 1e9, + 1 * 1e9, + 5 * 1e9, +} + +const _ = unsafe.Sizeof(func() { + const _ = 0 + _ = iota + + const ( + zero = iota + one + ) + assert(one == 1) + assert(iota == 0) +}) + +// issue #52438 +const i1 = iota +const i2 = iota +const i3 = iota + +func _() { + assert(i1 == 0) + assert(i2 == 0) + assert(i3 == 0) + + const i4 = iota + const i5 = iota + const i6 = iota + + assert(i4 == 0) + assert(i5 == 0) + assert(i6 == 0) +} + +// untyped constants must not get arbitrarily large +const prec = 512 // internal maximum precision for integers +const maxInt = (1<<(prec/2) - 1) * (1<<(prec/2) + 1) // == 1<<prec - 1 + +const _ = maxInt + /* ERROR constant addition overflow */ 1 +const _ = -maxInt - /* ERROR constant subtraction overflow */ 1 +const _ = maxInt ^ /* ERROR constant bitwise XOR overflow */ -1 +const _ = maxInt * /* ERROR constant multiplication overflow */ 2 +const _ = maxInt << /* ERROR constant shift overflow */ 2 +const _ = 1 << /* ERROR constant shift overflow */ prec + +const _ = ^ /* ERROR constant bitwise complement overflow */ maxInt diff --git a/src/internal/types/testdata/check/const1.go b/src/internal/types/testdata/check/const1.go new file mode 100644 index 0000000..c912801 --- /dev/null +++ b/src/internal/types/testdata/check/const1.go @@ -0,0 +1,334 @@ +// Copyright 2012 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. + +// constant conversions + +package const1 + +import "math" + +const( + mi = ^int(0) + mu = ^uint(0) + mp = ^uintptr(0) + + logSizeofInt = uint(mi>>8&1 + mi>>16&1 + mi>>32&1) + logSizeofUint = uint(mu>>8&1 + mu>>16&1 + mu>>32&1) + logSizeofUintptr = uint(mp>>8&1 + mp>>16&1 + mp>>32&1) +) + +const ( + minInt8 = -1<<(8<<iota - 1) + minInt16 + minInt32 + minInt64 + minInt = -1<<(8<<logSizeofInt - 1) +) + +const ( + maxInt8 = 1<<(8<<iota - 1) - 1 + maxInt16 + maxInt32 + maxInt64 + maxInt = 1<<(8<<logSizeofInt - 1) - 1 +) + +const ( + maxUint8 = 1<<(8<<iota) - 1 + maxUint16 + maxUint32 + maxUint64 + maxUint = 1<<(8<<logSizeofUint) - 1 + maxUintptr = 1<<(8<<logSizeofUintptr) - 1 +) + +const ( + smallestFloat32 = 1.0 / (1<<(127 - 1 + 23)) + // TODO(gri) The compiler limits integers to 512 bit and thus + // we cannot compute the value (1<<(1023 - 1 + 52)) + // without overflow. For now we match the compiler. + // See also issue #44057. + // smallestFloat64 = 1.0 / (1<<(1023 - 1 + 52)) + smallestFloat64 = math.SmallestNonzeroFloat64 +) + +const ( + _ = assert(smallestFloat32 > 0) + _ = assert(smallestFloat64 > 0) +) + +const ( + maxFloat32 = 1<<127 * (1<<24 - 1) / (1.0<<23) + // TODO(gri) The compiler limits integers to 512 bit and thus + // we cannot compute the value 1<<1023 + // without overflow. For now we match the compiler. + // See also issue #44057. + // maxFloat64 = 1<<1023 * (1<<53 - 1) / (1.0<<52) + maxFloat64 = math.MaxFloat64 +) + +const ( + _ int8 = minInt8 /* ERROR "overflows" */ - 1 + _ int8 = minInt8 + _ int8 = maxInt8 + _ int8 = maxInt8 /* ERROR "overflows" */ + 1 + _ int8 = smallestFloat64 /* ERROR "truncated" */ + + _ = int8(minInt8 /* ERROR "cannot convert" */ - 1) + _ = int8(minInt8) + _ = int8(maxInt8) + _ = int8(maxInt8 /* ERROR "cannot convert" */ + 1) + _ = int8(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ int16 = minInt16 /* ERROR "overflows" */ - 1 + _ int16 = minInt16 + _ int16 = maxInt16 + _ int16 = maxInt16 /* ERROR "overflows" */ + 1 + _ int16 = smallestFloat64 /* ERROR "truncated" */ + + _ = int16(minInt16 /* ERROR "cannot convert" */ - 1) + _ = int16(minInt16) + _ = int16(maxInt16) + _ = int16(maxInt16 /* ERROR "cannot convert" */ + 1) + _ = int16(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ int32 = minInt32 /* ERROR "overflows" */ - 1 + _ int32 = minInt32 + _ int32 = maxInt32 + _ int32 = maxInt32 /* ERROR "overflows" */ + 1 + _ int32 = smallestFloat64 /* ERROR "truncated" */ + + _ = int32(minInt32 /* ERROR "cannot convert" */ - 1) + _ = int32(minInt32) + _ = int32(maxInt32) + _ = int32(maxInt32 /* ERROR "cannot convert" */ + 1) + _ = int32(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ int64 = minInt64 /* ERROR "overflows" */ - 1 + _ int64 = minInt64 + _ int64 = maxInt64 + _ int64 = maxInt64 /* ERROR "overflows" */ + 1 + _ int64 = smallestFloat64 /* ERROR "truncated" */ + + _ = int64(minInt64 /* ERROR "cannot convert" */ - 1) + _ = int64(minInt64) + _ = int64(maxInt64) + _ = int64(maxInt64 /* ERROR "cannot convert" */ + 1) + _ = int64(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ int = minInt /* ERROR "overflows" */ - 1 + _ int = minInt + _ int = maxInt + _ int = maxInt /* ERROR "overflows" */ + 1 + _ int = smallestFloat64 /* ERROR "truncated" */ + + _ = int(minInt /* ERROR "cannot convert" */ - 1) + _ = int(minInt) + _ = int(maxInt) + _ = int(maxInt /* ERROR "cannot convert" */ + 1) + _ = int(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ uint8 = 0 /* ERROR "overflows" */ - 1 + _ uint8 = 0 + _ uint8 = maxUint8 + _ uint8 = maxUint8 /* ERROR "overflows" */ + 1 + _ uint8 = smallestFloat64 /* ERROR "truncated" */ + + _ = uint8(0 /* ERROR "cannot convert" */ - 1) + _ = uint8(0) + _ = uint8(maxUint8) + _ = uint8(maxUint8 /* ERROR "cannot convert" */ + 1) + _ = uint8(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ uint16 = 0 /* ERROR "overflows" */ - 1 + _ uint16 = 0 + _ uint16 = maxUint16 + _ uint16 = maxUint16 /* ERROR "overflows" */ + 1 + _ uint16 = smallestFloat64 /* ERROR "truncated" */ + + _ = uint16(0 /* ERROR "cannot convert" */ - 1) + _ = uint16(0) + _ = uint16(maxUint16) + _ = uint16(maxUint16 /* ERROR "cannot convert" */ + 1) + _ = uint16(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ uint32 = 0 /* ERROR "overflows" */ - 1 + _ uint32 = 0 + _ uint32 = maxUint32 + _ uint32 = maxUint32 /* ERROR "overflows" */ + 1 + _ uint32 = smallestFloat64 /* ERROR "truncated" */ + + _ = uint32(0 /* ERROR "cannot convert" */ - 1) + _ = uint32(0) + _ = uint32(maxUint32) + _ = uint32(maxUint32 /* ERROR "cannot convert" */ + 1) + _ = uint32(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ uint64 = 0 /* ERROR "overflows" */ - 1 + _ uint64 = 0 + _ uint64 = maxUint64 + _ uint64 = maxUint64 /* ERROR "overflows" */ + 1 + _ uint64 = smallestFloat64 /* ERROR "truncated" */ + + _ = uint64(0 /* ERROR "cannot convert" */ - 1) + _ = uint64(0) + _ = uint64(maxUint64) + _ = uint64(maxUint64 /* ERROR "cannot convert" */ + 1) + _ = uint64(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ uint = 0 /* ERROR "overflows" */ - 1 + _ uint = 0 + _ uint = maxUint + _ uint = maxUint /* ERROR "overflows" */ + 1 + _ uint = smallestFloat64 /* ERROR "truncated" */ + + _ = uint(0 /* ERROR "cannot convert" */ - 1) + _ = uint(0) + _ = uint(maxUint) + _ = uint(maxUint /* ERROR "cannot convert" */ + 1) + _ = uint(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ uintptr = 0 /* ERROR "overflows" */ - 1 + _ uintptr = 0 + _ uintptr = maxUintptr + _ uintptr = maxUintptr /* ERROR "overflows" */ + 1 + _ uintptr = smallestFloat64 /* ERROR "truncated" */ + + _ = uintptr(0 /* ERROR "cannot convert" */ - 1) + _ = uintptr(0) + _ = uintptr(maxUintptr) + _ = uintptr(maxUintptr /* ERROR "cannot convert" */ + 1) + _ = uintptr(smallestFloat64 /* ERROR "cannot convert" */) +) + +const ( + _ float32 = minInt64 + _ float64 = minInt64 + _ complex64 = minInt64 + _ complex128 = minInt64 + + _ = float32(minInt64) + _ = float64(minInt64) + _ = complex64(minInt64) + _ = complex128(minInt64) +) + +const ( + _ float32 = maxUint64 + _ float64 = maxUint64 + _ complex64 = maxUint64 + _ complex128 = maxUint64 + + _ = float32(maxUint64) + _ = float64(maxUint64) + _ = complex64(maxUint64) + _ = complex128(maxUint64) +) + +// TODO(gri) find smaller deltas below + +const delta32 = maxFloat32/(1 << 23) + +const ( + _ float32 = - /* ERROR "overflow" */ (maxFloat32 + delta32) + _ float32 = -maxFloat32 + _ float32 = maxFloat32 + _ float32 = maxFloat32 /* ERROR "overflow" */ + delta32 + + _ = float32(- /* ERROR "cannot convert" */ (maxFloat32 + delta32)) + _ = float32(-maxFloat32) + _ = float32(maxFloat32) + _ = float32(maxFloat32 /* ERROR "cannot convert" */ + delta32) + + _ = assert(float32(smallestFloat32) == smallestFloat32) + _ = assert(float32(smallestFloat32/2) == 0) + _ = assert(float32(smallestFloat64) == 0) + _ = assert(float32(smallestFloat64/2) == 0) +) + +const delta64 = maxFloat64/(1 << 52) + +const ( + _ float64 = - /* ERROR "overflow" */ (maxFloat64 + delta64) + _ float64 = -maxFloat64 + _ float64 = maxFloat64 + _ float64 = maxFloat64 /* ERROR "overflow" */ + delta64 + + _ = float64(- /* ERROR "cannot convert" */ (maxFloat64 + delta64)) + _ = float64(-maxFloat64) + _ = float64(maxFloat64) + _ = float64(maxFloat64 /* ERROR "cannot convert" */ + delta64) + + _ = assert(float64(smallestFloat32) == smallestFloat32) + _ = assert(float64(smallestFloat32/2) == smallestFloat32/2) + _ = assert(float64(smallestFloat64) == smallestFloat64) + _ = assert(float64(smallestFloat64/2) == 0) +) + +const ( + _ complex64 = - /* ERROR "overflow" */ (maxFloat32 + delta32) + _ complex64 = -maxFloat32 + _ complex64 = maxFloat32 + _ complex64 = maxFloat32 /* ERROR "overflow" */ + delta32 + + _ = complex64(- /* ERROR "cannot convert" */ (maxFloat32 + delta32)) + _ = complex64(-maxFloat32) + _ = complex64(maxFloat32) + _ = complex64(maxFloat32 /* ERROR "cannot convert" */ + delta32) +) + +const ( + _ complex128 = - /* ERROR "overflow" */ (maxFloat64 + delta64) + _ complex128 = -maxFloat64 + _ complex128 = maxFloat64 + _ complex128 = maxFloat64 /* ERROR "overflow" */ + delta64 + + _ = complex128(- /* ERROR "cannot convert" */ (maxFloat64 + delta64)) + _ = complex128(-maxFloat64) + _ = complex128(maxFloat64) + _ = complex128(maxFloat64 /* ERROR "cannot convert" */ + delta64) +) + +// Initialization of typed constant and conversion are the same: +const ( + f32 = 1 + smallestFloat32 + x32 float32 = f32 + y32 = float32(f32) + _ = assert(x32 - y32 == 0) +) + +const ( + f64 = 1 + smallestFloat64 + x64 float64 = f64 + y64 = float64(f64) + _ = assert(x64 - y64 == 0) +) + +const ( + _ = int8(-1) << 7 + _ = int8 /* ERROR "overflows" */ (-1) << 8 + + _ = uint32(1) << 31 + _ = uint32 /* ERROR "overflows" */ (1) << 32 +) diff --git a/src/internal/types/testdata/check/constdecl.go b/src/internal/types/testdata/check/constdecl.go new file mode 100644 index 0000000..faa9b9d --- /dev/null +++ b/src/internal/types/testdata/check/constdecl.go @@ -0,0 +1,160 @@ +// Copyright 2013 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. + +package constdecl + +import "math" +import "unsafe" + +var v int + +// Const decls must be initialized by constants. +const _ = v /* ERROR "not constant" */ +const _ = math /* ERROR "not constant" */ .Sin(0) +const _ = int /* ERROR "not an expression" */ + +func _() { + const _ = v /* ERROR "not constant" */ + const _ = math /* ERROR "not constant" */ .Sin(0) + const _ = int /* ERROR "not an expression" */ +} + +// Identifier and expression arity must match. +const _ /* ERROR "missing init expr for _" */ +const _ = 1, 2 /* ERROR "extra init expr 2" */ + +const _ /* ERROR "missing init expr for _" */ int +const _ int = 1, 2 /* ERROR "extra init expr 2" */ + +const ( + _ /* ERROR "missing init expr for _" */ + _ = 1, 2 /* ERROR "extra init expr 2" */ + + _ /* ERROR "missing init expr for _" */ int + _ int = 1, 2 /* ERROR "extra init expr 2" */ +) + +const ( + _ = 1 + _ + _, _ /* ERROR "missing init expr for _" */ + _ +) + +const ( + _, _ = 1, 2 + _, _ + _ /* ERROR "extra init expr at" */ + _, _ + _, _, _ /* ERROR "missing init expr for _" */ + _, _ +) + +func _() { + const _ /* ERROR "missing init expr for _" */ + const _ = 1, 2 /* ERROR "extra init expr 2" */ + + const _ /* ERROR "missing init expr for _" */ int + const _ int = 1, 2 /* ERROR "extra init expr 2" */ + + const ( + _ /* ERROR "missing init expr for _" */ + _ = 1, 2 /* ERROR "extra init expr 2" */ + + _ /* ERROR "missing init expr for _" */ int + _ int = 1, 2 /* ERROR "extra init expr 2" */ + ) + + const ( + _ = 1 + _ + _, _ /* ERROR "missing init expr for _" */ + _ + ) + + const ( + _, _ = 1, 2 + _, _ + _ /* ERROR "extra init expr at" */ + _, _ + _, _, _ /* ERROR "missing init expr for _" */ + _, _ + ) +} + +// Test case for constant with invalid initialization. +// Caused panic because the constant value was not set up (gri - 7/8/2014). +func _() { + const ( + x string = missing /* ERROR "undefined" */ + y = x + "" + ) +} + +// Test case for constants depending on function literals (see also #22992). +const A /* ERROR initialization cycle */ = unsafe.Sizeof(func() { _ = A }) + +func _() { + // The function literal below must not see a. + const a = unsafe.Sizeof(func() { _ = a /* ERROR "undefined" */ }) + const b = unsafe.Sizeof(func() { _ = a }) + + // The function literal below must not see x, y, or z. + const x, y, z = 0, 1, unsafe.Sizeof(func() { _ = x /* ERROR "undefined" */ + y /* ERROR "undefined" */ + z /* ERROR "undefined" */ }) +} + +// Test cases for errors in inherited constant initialization expressions. +// Errors related to inherited initialization expressions must appear at +// the constant identifier being declared, not at the original expression +// (issues #42991, #42992). +const ( + _ byte = 255 + iota + /* some gap */ + _ // ERROR overflows + /* some gap */ + /* some gap */ _ /* ERROR overflows */; _ /* ERROR overflows */ + /* some gap */ + _ = 255 + iota + _ = byte /* ERROR overflows */ (255) + iota + _ /* ERROR overflows */ +) + +// Test cases from issue. +const ( + ok = byte(iota + 253) + bad + barn + bard // ERROR cannot convert +) + +const ( + c = len([1 - iota]int{}) + d + e // ERROR invalid array length + f // ERROR invalid array length +) + +// Test that identifiers in implicit (omitted) RHS +// expressions of constant declarations are resolved +// in the correct context; see issues #49157, #53585. +const X = 2 + +func _() { + const ( + A = iota // 0 + iota = iota // 1 + B // 1 (iota is declared locally on prev. line) + C // 1 + ) + assert(A == 0 && B == 1 && C == 1) + + const ( + X = X + X + Y + Z = iota + ) + assert(X == 4 && Y == 8 && Z == 1) +} + +// TODO(gri) move extra tests from testdata/const0.src into here diff --git a/src/internal/types/testdata/check/conversions0.go b/src/internal/types/testdata/check/conversions0.go new file mode 100644 index 0000000..e1336c0 --- /dev/null +++ b/src/internal/types/testdata/check/conversions0.go @@ -0,0 +1,93 @@ +// Copyright 2012 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. + +// conversions + +package conversions + +import "unsafe" + +// argument count +var ( + _ = int() /* ERROR "missing argument" */ + _ = int(1, 2 /* ERROR "too many arguments" */ ) +) + +// numeric constant conversions are in const1.src. + +func string_conversions() { + const A = string(65) + assert(A == "A") + const E = string(-1) + assert(E == "\uFFFD") + assert(E == string(1234567890)) + + type myint int + assert(A == string(myint(65))) + + type mystring string + const _ mystring = mystring("foo") + + const _ = string(true /* ERROR "cannot convert" */ ) + const _ = string(1.2 /* ERROR "cannot convert" */ ) + const _ = string(nil /* ERROR "cannot convert" */ ) + + // issues 11357, 11353: argument must be of integer type + _ = string(0.0 /* ERROR "cannot convert" */ ) + _ = string(0i /* ERROR "cannot convert" */ ) + _ = string(1 /* ERROR "cannot convert" */ + 2i) +} + +func interface_conversions() { + type E interface{} + + type I1 interface{ + m1() + } + + type I2 interface{ + m1() + m2(x int) + } + + type I3 interface{ + m1() + m2() int + } + + var e E + var i1 I1 + var i2 I2 + var i3 I3 + + _ = E(0) + _ = E(nil) + _ = E(e) + _ = E(i1) + _ = E(i2) + + _ = I1(0 /* ERROR "cannot convert" */ ) + _ = I1(nil) + _ = I1(i1) + _ = I1(e /* ERROR "cannot convert" */ ) + _ = I1(i2) + + _ = I2(nil) + _ = I2(i1 /* ERROR "cannot convert" */ ) + _ = I2(i2) + _ = I2(i3 /* ERROR "cannot convert" */ ) + + _ = I3(nil) + _ = I3(i1 /* ERROR "cannot convert" */ ) + _ = I3(i2 /* ERROR "cannot convert" */ ) + _ = I3(i3) + + // TODO(gri) add more tests, improve error message +} + +func issue6326() { + type T unsafe.Pointer + var x T + _ = uintptr(x) // see issue 6326 +} diff --git a/src/internal/types/testdata/check/conversions1.go b/src/internal/types/testdata/check/conversions1.go new file mode 100644 index 0000000..93a5f18 --- /dev/null +++ b/src/internal/types/testdata/check/conversions1.go @@ -0,0 +1,313 @@ +// Copyright 2016 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. + +// Test various valid and invalid struct assignments and conversions. +// Does not compile. + +package conversions2 + +type I interface { + m() +} + +// conversions between structs + +func _() { + type S struct{} + type T struct{} + var s S + var t T + var u struct{} + s = s + s = t // ERROR "cannot use .* in assignment" + s = u + s = S(s) + s = S(t) + s = S(u) + t = u + t = T(u) +} + +func _() { + type S struct{ x int } + type T struct { + x int "foo" + } + var s S + var t T + var u struct { + x int "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = S(s) + s = S(t) + s = S(u) + t = u // ERROR "cannot use .* in assignment" + t = T(u) +} + +func _() { + type E struct{ x int } + type S struct{ x E } + type T struct { + x E "foo" + } + var s S + var t T + var u struct { + x E "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = S(s) + s = S(t) + s = S(u) + t = u // ERROR "cannot use .* in assignment" + t = T(u) +} + +func _() { + type S struct { + x struct { + x int "foo" + } + } + type T struct { + x struct { + x int "bar" + } "foo" + } + var s S + var t T + var u struct { + x struct { + x int "bar" + } "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = S(s) + s = S(t) + s = S(u) + t = u // ERROR "cannot use .* in assignment" + t = T(u) +} + +func _() { + type E1 struct { + x int "foo" + } + type E2 struct { + x int "bar" + } + type S struct{ x E1 } + type T struct { + x E2 "foo" + } + var s S + var t T + var u struct { + x E2 "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = S(s) + s = S(t /* ERROR "cannot convert" */ ) + s = S(u /* ERROR "cannot convert" */ ) + t = u // ERROR "cannot use .* in assignment" + t = T(u) +} + +func _() { + type E struct{ x int } + type S struct { + f func(struct { + x int "foo" + }) + } + type T struct { + f func(struct { + x int "bar" + }) + } + var s S + 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 = S(s) + s = S(t) + s = S(u /* ERROR "cannot convert" */ ) + t = u // ERROR "cannot use .* in assignment" + t = T(u /* ERROR "cannot convert" */ ) +} + +// conversions between pointers to structs + +func _() { + type S struct{} + type T struct{} + var s *S + var t *T + var u *struct{} + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = (*S)(s) + s = (*S)(t) + s = (*S)(u) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u) +} + +func _() { + type S struct{ x int } + type T struct { + x int "foo" + } + var s *S + var t *T + var u *struct { + x int "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = (*S)(s) + s = (*S)(t) + s = (*S)(u) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u) +} + +func _() { + type E struct{ x int } + type S struct{ x E } + type T struct { + x E "foo" + } + var s *S + var t *T + var u *struct { + x E "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = (*S)(s) + s = (*S)(t) + s = (*S)(u) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u) +} + +func _() { + type S struct { + x struct { + x int "foo" + } + } + type T struct { + x struct { + x int "bar" + } "foo" + } + var s *S + var t *T + var u *struct { + x struct { + x int "bar" + } "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = (*S)(s) + s = (*S)(t) + s = (*S)(u) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u) +} + +func _() { + type E1 struct { + x int "foo" + } + type E2 struct { + x int "bar" + } + type S struct{ x E1 } + type T struct { + x E2 "foo" + } + var s *S + var t *T + var u *struct { + x E2 "bar" + } + s = s + s = t // ERROR "cannot use .* in assignment" + s = u // ERROR "cannot use .* in assignment" + s = (*S)(s) + s = (*S)(t /* ERROR "cannot convert" */ ) + s = (*S)(u /* ERROR "cannot convert" */ ) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u) +} + +func _() { + type E struct{ x int } + type S struct { + f func(struct { + x int "foo" + }) + } + type T struct { + f func(struct { + x int "bar" + }) + } + var s *S + 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 = (*S)(s) + s = (*S)(t) + s = (*S)(u /* ERROR "cannot convert" */ ) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u /* ERROR "cannot convert" */ ) +} + +func _() { + type E struct{ x int } + type S struct { + f func(*struct { + x int "foo" + }) + } + type T struct { + f func(*struct { + x int "bar" + }) + } + var s *S + 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 = (*S)(s) + s = (*S)(t) + s = (*S)(u /* ERROR "cannot convert" */ ) + t = u // ERROR "cannot use .* in assignment" + t = (*T)(u /* ERROR "cannot convert" */ ) +} diff --git a/src/internal/types/testdata/check/cycles0.go b/src/internal/types/testdata/check/cycles0.go new file mode 100644 index 0000000..7c00c7d --- /dev/null +++ b/src/internal/types/testdata/check/cycles0.go @@ -0,0 +1,175 @@ +// Copyright 2013 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. + +package cycles + +import "unsafe" + +type ( + T0 int + T1 /* ERROR invalid recursive type: T1 refers to itself */ T1 + T2 *T2 + + T3 /* ERROR invalid recursive type */ T4 + T4 T5 + T5 T3 + + T6 T7 + T7 *T8 + T8 T6 + + // arrays + A0 /* ERROR invalid recursive type */ [10]A0 + A1 [10]*A1 + + A2 /* ERROR invalid recursive type */ [10]A3 + A3 [10]A4 + A4 A2 + + A5 [10]A6 + A6 *A5 + + // slices + L0 []L0 + + // structs + S0 /* ERROR invalid recursive type: S0 refers to itself */ struct{ _ S0 } + S1 /* ERROR invalid recursive type: S1 refers to itself */ struct{ S1 } + S2 struct{ _ *S2 } + S3 struct{ *S3 } + + S4 /* ERROR invalid recursive type */ struct{ S5 } + S5 struct{ S6 } + S6 S4 + + // pointers + P0 *P0 + PP *struct{ PP.f /* ERROR PP.f is not a type */ } + + // functions + F0 func(F0) + F1 func() F1 + F2 func(F2) F2 + + // interfaces + I0 /* ERROR invalid recursive type: I0 refers to itself */ interface{ I0 } + + I1 /* ERROR invalid recursive type */ interface{ I2 } + I2 interface{ I3 } + I3 interface{ I1 } + + I4 interface{ f(I4) } + + // testcase for issue 5090 + I5 interface{ f(I6) } + I6 interface{ I5 } + + // maps + M0 map[M0 /* ERROR invalid map key */ ]M0 + + // channels + C0 chan C0 +) + +// test case for issue #34771 +type ( + AA /* ERROR invalid recursive type */ B + B C + C [10]D + D E + E AA +) + +func _() { + type ( + t1 /* ERROR invalid recursive type: t1 refers to itself */ t1 + t2 *t2 + + t3 t4 /* ERROR undefined */ + t4 t5 /* ERROR undefined */ + t5 t3 + + // arrays + a0 /* ERROR invalid recursive type: a0 refers to itself */ [10]a0 + a1 [10]*a1 + + // slices + l0 []l0 + + // structs + s0 /* ERROR invalid recursive type: s0 refers to itself */ struct{ _ s0 } + s1 /* ERROR invalid recursive type: s1 refers to itself */ struct{ s1 } + s2 struct{ _ *s2 } + s3 struct{ *s3 } + + // pointers + p0 *p0 + + // functions + f0 func(f0) + f1 func() f1 + f2 func(f2) f2 + + // interfaces + i0 /* ERROR invalid recursive type: i0 refers to itself */ interface{ i0 } + + // maps + m0 map[m0 /* ERROR invalid map key */ ]m0 + + // channels + c0 chan c0 + ) +} + +// test cases for issue 6667 + +type A [10]map[A /* ERROR invalid map key */ ]bool + +type S struct { + m map[S /* ERROR invalid map key */ ]bool +} + +// test cases for issue 7236 +// (cycle detection must not be dependent on starting point of resolution) + +type ( + P1 *T9 + T9 /* ERROR invalid recursive type: T9 refers to itself */ T9 + + T10 /* ERROR invalid recursive type: T10 refers to itself */ T10 + P2 *T10 +) + +func (T11) m() {} + +type T11 /* ERROR invalid recursive type: T11 refers to itself */ struct{ T11 } + +type T12 /* ERROR invalid recursive type: T12 refers to itself */ struct{ T12 } + +func (*T12) m() {} + +type ( + P3 *T13 + T13 /* ERROR invalid recursive type */ T13 +) + +// test cases for issue 18643 +// (type cycle detection when non-type expressions are involved) +type ( + T14 [len(T14 /* ERROR invalid recursive type */ {})]int + T15 [][len(T15 /* ERROR invalid recursive type */ {})]int + T16 map[[len(T16 /* ERROR invalid recursive type */ {1:2})]int]int + T17 map[int][len(T17 /* ERROR invalid recursive type */ {1:2})]int +) + +// Test case for types depending on function literals (see also #22992). +type T20 chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte +type T22 = chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte + +func _() { + type T0 func(T0) + type T1 /* ERROR invalid recursive type */ = func(T1) + type T2 chan [unsafe.Sizeof(func(ch T2){ _ = <-ch })]byte + type T3 /* ERROR invalid recursive type */ = chan [unsafe.Sizeof(func(ch T3){ _ = <-ch })]byte +} diff --git a/src/internal/types/testdata/check/cycles1.go b/src/internal/types/testdata/check/cycles1.go new file mode 100644 index 0000000..ae2b38e --- /dev/null +++ b/src/internal/types/testdata/check/cycles1.go @@ -0,0 +1,77 @@ +// Copyright 2013 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. + +package p + +type ( + A interface { + a() interface { + ABC1 + } + } + B interface { + b() interface { + ABC2 + } + } + C interface { + c() interface { + ABC3 + } + } + + AB interface { + A + B + } + BC interface { + B + C + } + + ABC1 interface { + A + B + C + } + ABC2 interface { + AB + C + } + ABC3 interface { + A + BC + } +) + +var ( + x1 ABC1 + x2 ABC2 + x3 ABC3 +) + +func _() { + // all types have the same method set + x1 = x2 + x2 = x1 + + x1 = x3 + x3 = x1 + + x2 = x3 + x3 = x2 + + // all methods return the same type again + x1 = x1.a() + x1 = x1.b() + x1 = x1.c() + + x2 = x2.a() + x2 = x2.b() + x2 = x2.c() + + x3 = x3.a() + x3 = x3.b() + x3 = x3.c() +} diff --git a/src/internal/types/testdata/check/cycles2.go b/src/internal/types/testdata/check/cycles2.go new file mode 100644 index 0000000..8480b29 --- /dev/null +++ b/src/internal/types/testdata/check/cycles2.go @@ -0,0 +1,98 @@ +// Copyright 2013 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. + +package p + +import "unsafe" + +// Test case for issue 5090 + +type t interface { + f(u) +} + +type u interface { + t +} + +func _() { + var t t + var u u + + t.f(t) + t.f(u) + + u.f(t) + u.f(u) +} + + +// Test case for issues #6589, #33656. + +type A interface { + a() interface { + AB + } +} + +type B interface { + b() interface { + AB + } +} + +type AB interface { + a() interface { + A + B + } + b() interface { + A + B + } +} + +var x AB +var y interface { + A + B +} + +var _ = x == y + + +// Test case for issue 6638. + +type T interface { + m() [T(nil).m /* ERROR undefined */ ()[0]]int +} + +// Variations of this test case. + +type T1 /* ERROR invalid recursive type */ interface { + m() [x1.m()[0]]int +} + +var x1 T1 + +type T2 /* ERROR invalid recursive type */ interface { + m() [len(x2.m())]int +} + +var x2 T2 + +type T3 /* ERROR invalid recursive type */ interface { + m() [unsafe.Sizeof(x3.m)]int +} + +var x3 T3 + +type T4 /* ERROR invalid recursive type */ interface { + m() [unsafe.Sizeof(cast4(x4.m))]int // cast is invalid but we have a cycle, so all bets are off +} + +var x4 T4 +var _ = cast4(x4.m) + +type cast4 func() diff --git a/src/internal/types/testdata/check/cycles3.go b/src/internal/types/testdata/check/cycles3.go new file mode 100644 index 0000000..4330551 --- /dev/null +++ b/src/internal/types/testdata/check/cycles3.go @@ -0,0 +1,60 @@ +// Copyright 2013 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. + +package p + +import "unsafe" + +var ( + _ A = A(nil).a().b().c().d().e().f() + _ A = A(nil).b().c().d().e().f() + _ A = A(nil).c().d().e().f() + _ A = A(nil).d().e().f() + _ A = A(nil).e().f() + _ A = A(nil).f() + _ A = A(nil) +) + +type ( + A interface { + a() B + B + } + + B interface { + b() C + C + } + + C interface { + c() D + D + } + + D interface { + d() E + E + } + + E interface { + e() F + F + } + + F interface { + f() A + } +) + +type ( + U /* ERROR invalid recursive type */ interface { + V + } + + V interface { + v() [unsafe.Sizeof(u)]int + } +) + +var u U diff --git a/src/internal/types/testdata/check/cycles4.go b/src/internal/types/testdata/check/cycles4.go new file mode 100644 index 0000000..924aabf --- /dev/null +++ b/src/internal/types/testdata/check/cycles4.go @@ -0,0 +1,121 @@ +// Copyright 2013 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. + +package p + +import "unsafe" + +// Check that all methods of T are collected before +// determining the result type of m (which embeds +// all methods of T). + +type T interface { + m() interface {T} + E +} + +var _ int = T.m(nil).m().e() + +type E interface { + e() int +} + +// Check that unresolved forward chains are followed +// (see also comment in resolver.go, checker.typeDecl). + +var _ int = C.m(nil).m().e() + +type A B + +type B interface { + m() interface{C} + E +} + +type C A + +// Check that interface type comparison for identity +// does not recur endlessly. + +type T1 interface { + m() interface{T1} +} + +type T2 interface { + m() interface{T2} +} + +func _(x T1, y T2) { + // Checking for assignability of interfaces must check + // if all methods of x are present in y, and that they + // have identical signatures. The signatures recur via + // the result type, which is an interface that embeds + // a single method m that refers to the very interface + // that contains it. This requires cycle detection in + // identity checks for interface types. + x = y +} + +type T3 interface { + m() interface{T4} +} + +type T4 interface { + m() interface{T3} +} + +func _(x T1, y T3) { + x = y +} + +// Check that interfaces are type-checked in order of +// (embedded interface) dependencies (was issue 7158). + +var x1 T5 = T7(nil) + +type T5 interface { + T6 +} + +type T6 interface { + m() T7 +} +type T7 interface { + T5 +} + +// Actual test case from issue 7158. + +func wrapNode() Node { + return wrapElement() +} + +func wrapElement() Element { + return nil +} + +type EventTarget interface { + AddEventListener(Event) +} + +type Node interface { + EventTarget +} + +type Element interface { + Node +} + +type Event interface { + Target() Element +} + +// Check that accessing an interface method too early doesn't lead +// to follow-on errors due to an incorrectly computed type set. + +type T8 interface { + m() [unsafe.Sizeof(T8.m /* ERROR undefined */ )]int +} + +var _ = T8.m // no error expected here diff --git a/src/internal/types/testdata/check/cycles5.go b/src/internal/types/testdata/check/cycles5.go new file mode 100644 index 0000000..5e0d191 --- /dev/null +++ b/src/internal/types/testdata/check/cycles5.go @@ -0,0 +1,200 @@ +// Copyright 2017 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. + +package p + +import "unsafe" + +// test case from issue #18395 + +type ( + A interface { B } + B interface { C } + C interface { D; F() A } + D interface { G() B } +) + +var _ = A(nil).G // G must be found + + +// test case from issue #21804 + +type sourceBridge interface { + listVersions() ([]Version, error) +} + +type Constraint interface { + copyTo(*ConstraintMsg) +} + +type ConstraintMsg struct{} + +func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion { + return nil +} + +type Version interface { + Constraint +} + +type UnpairedVersion interface { + Version +} + +var _ Constraint = UnpairedVersion(nil) + + +// derived test case from issue #21804 + +type ( + _ interface{ m(B1) } + A1 interface{ a(D1) } + B1 interface{ A1 } + C1 interface{ B1 } + D1 interface{ C1 } +) + +var _ A1 = C1(nil) + + +// derived test case from issue #22701 + +func F(x I4) interface{} { + return x.Method() +} + +type Unused interface { + RefersToI1(a I1) +} + +type I1 interface { + I2 + I3 +} + +type I2 interface { + RefersToI4() I4 +} + +type I3 interface { + Method() interface{} +} + +type I4 interface { + I1 +} + + +// check embedding of error interface + +type Error interface{ error } + +var err Error +var _ = err.Error() + + +// more esoteric cases + +type ( + T1 interface { T2 } + T2 /* ERROR invalid recursive type */ T2 +) + +type ( + T3 interface { T4 } + T4 /* ERROR invalid recursive type */ T5 + T5 = T6 + T6 = T7 + T7 = T4 +) + + +// arbitrary code may appear inside an interface + +const n = unsafe.Sizeof(func(){}) + +type I interface { + m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte) +} + + +// test cases for varias alias cycles + +type T10 /* ERROR invalid recursive type */ = *T10 // issue #25141 +type T11 /* ERROR invalid recursive type */ = interface{ f(T11) } // issue #23139 + +// issue #18640 +type ( + aa = bb + bb struct { + *aa + } +) + +type ( + a struct{ *b } + b = c + c struct{ *b /* ERROR invalid use of type alias */ } +) + +// issue #24939 +type ( + _ interface { + M(P) + } + + M interface { + F() P // ERROR invalid use of type alias + } + + P = interface { + I() M + } +) + +// issue #8699 +type T12 /* ERROR invalid recursive type */ [len(a12)]int +var a12 = makeArray() +func makeArray() (res T12) { return } + +// issue #20770 +var r /* ERROR invalid cycle in declaration of r */ = newReader() +func newReader() r + +// variations of the theme of #8699 and #20770 +var arr /* ERROR cycle */ = f() +func f() [len(arr)]int + +// issue #25790 +func ff(ff /* ERROR not a type */ ) +func gg((gg /* ERROR not a type */ )) + +type T13 /* ERROR invalid recursive type T13 */ [len(b13)]int +var b13 T13 + +func g1() [unsafe.Sizeof(g1)]int +func g2() [unsafe.Sizeof(x2)]int +var x2 = g2 + +// verify that we get the correct sizes for the functions above +// (note: assert is statically evaluated in go/types test mode) +func init() { + assert(unsafe.Sizeof(g1) == 8) + assert(unsafe.Sizeof(x2) == 8) +} + +func h() [h /* ERROR no value */ ()[0]]int { panic(0) } + +var c14 /* ERROR cycle */ T14 +type T14 [uintptr(unsafe.Sizeof(&c14))]byte + +// issue #34333 +type T15 /* ERROR invalid recursive type T15 */ struct { + f func() T16 + b T16 +} + +type T16 struct { + T15 +}
\ No newline at end of file diff --git a/src/internal/types/testdata/check/decls0.go b/src/internal/types/testdata/check/decls0.go new file mode 100644 index 0000000..868b318 --- /dev/null +++ b/src/internal/types/testdata/check/decls0.go @@ -0,0 +1,210 @@ +// -lang=go1.17 + +// Copyright 2011 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. + +// type declarations + +package p // don't permit non-interface elements in interfaces + +import "unsafe" + +const pi = 3.1415 + +type ( + N undefined /* ERROR "undefined" */ + B bool + I int32 + A [10]P + T struct { + x, y P + } + P *T + R (*R) + F func(A) I + Y interface { + f(A) I + } + S [](((P))) + M map[I]F + C chan<- I + + // blank types must be typechecked + _ pi /* ERROR "not a type" */ + _ struct{} + _ struct{ pi /* ERROR "not a type" */ } +) + + +// declarations of init +const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2 +type init /* ERROR "cannot declare init" */ struct{} +var _, init /* ERROR "cannot declare init" */ int + +func init() {} +func init /* ERROR "missing function body" */ () + +func _() { const init = 0 } +func _() { type init int } +func _() { var init int; _ = init } + +// invalid array types +type ( + iA0 [... /* ERROR "invalid use of \[...\] array" */ ]byte + // The error message below could be better. At the moment + // we believe an integer that is too large is not an integer. + // But at least we get an error. + iA1 [1 /* ERROR "must be integer" */ <<100]int + iA2 [- /* ERROR "invalid array length" */ 1]complex128 + iA3 ["foo" /* ERROR "must be integer" */ ]string + iA4 [float64 /* ERROR "must be integer" */ (0)]int +) + + +type ( + p1 pi.foo /* ERROR "pi.foo is not a type" */ + p2 unsafe.Pointer +) + + +type ( + Pi pi /* ERROR "not a type" */ + + a /* ERROR "invalid recursive type" */ a + a /* ERROR "redeclared" */ int + + b /* ERROR "invalid recursive type" */ c + c d + d e + e b + + t *t + + U V + V *W + W U + + P1 *S2 + P2 P1 + + S0 struct { + } + S1 struct { + a, b, c int + u, v, a /* ERROR "redeclared" */ float32 + } + S2 struct { + S0 // embedded field + S0 /* ERROR "redeclared" */ int + } + S3 struct { + x S2 + } + S4/* ERROR "invalid recursive type" */ struct { + S4 + } + S5 /* ERROR "invalid recursive type" */ struct { + S6 + } + S6 struct { + field S7 + } + S7 struct { + S5 + } + + L1 []L1 + L2 []int + + A1 [10.0]int + A2 /* ERROR "invalid recursive type" */ [10]A2 + A3 /* ERROR "invalid recursive type" */ [10]struct { + x A4 + } + A4 [10]A3 + + F1 func() + F2 func(x, y, z float32) + F3 func(x, y, x /* ERROR "redeclared" */ float32) + F4 func() (x, y, x /* ERROR "redeclared" */ float32) + F5 func(x int) (x /* ERROR "redeclared" */ float32) + F6 func(x ...int) + + I1 interface{} + I2 interface { + m1() + } + I3 interface { + m1() + m1 /* ERROR "duplicate method" */ () + } + I4 interface { + m1(x, y, x /* ERROR "redeclared" */ float32) + m2() (x, y, x /* ERROR "redeclared" */ float32) + m3(x int) (x /* ERROR "redeclared" */ float32) + } + I5 interface { + m1(I5) + } + I6 interface { + S0 /* ERROR "non-interface type S0" */ + } + I7 interface { + I1 + I1 + } + I8 /* ERROR "invalid recursive type" */ interface { + I8 + } + I9 /* ERROR "invalid recursive type" */ interface { + I10 + } + I10 interface { + I11 + } + I11 interface { + I9 + } + + C1 chan int + C2 <-chan int + C3 chan<- C3 + C4 chan C5 + C5 chan C6 + C6 chan C4 + + M1 map[Last]string + M2 map[string]M2 + + Last int +) + +// cycles in function/method declarations +// (test cases for issues #5217, #25790 and variants) +func f1(x f1 /* ERROR "not a type" */ ) {} +func f2(x *f2 /* ERROR "not a type" */ ) {} +func f3() (x f3 /* ERROR "not a type" */ ) { return } +func f4() (x *f4 /* ERROR "not a type" */ ) { return } +// TODO(#43215) this should be detected as a cycle error +func f5([unsafe.Sizeof(f5)]int) {} + +func (S0) m1 (x S0.m1 /* ERROR S0.m1 is not a type */ ) {} +func (S0) m2 (x *S0.m2 /* ERROR S0.m2 is not a type */ ) {} +func (S0) m3 () (x S0.m3 /* ERROR S0.m3 is not a type */ ) { return } +func (S0) m4 () (x *S0.m4 /* ERROR S0.m4 is not a type */ ) { return } + +// interfaces may not have any blank methods +type BlankI interface { + _ /* ERROR "methods must have a unique non-blank name" */ () + _ /* ERROR "methods must have a unique non-blank name" */ (float32) int + m() +} + +// non-interface types may have multiple blank methods +type BlankT struct{} + +func (BlankT) _() {} +func (BlankT) _(int) {} +func (BlankT) _() int { return 0 } +func (BlankT) _(int) int { return 0} diff --git a/src/internal/types/testdata/check/decls1.go b/src/internal/types/testdata/check/decls1.go new file mode 100644 index 0000000..b232fc8 --- /dev/null +++ b/src/internal/types/testdata/check/decls1.go @@ -0,0 +1,146 @@ +// Copyright 2012 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. + +// variable declarations + +package decls1 + +import ( + "math" +) + +// Global variables without initialization +var ( + a, b bool + c byte + d uint8 + r rune + i int + j, k, l int + x, y float32 + xx, yy float64 + u, v complex64 + uu, vv complex128 + s, t string + array []byte + iface interface{} + + blank _ /* ERROR "cannot use _" */ +) + +// Global variables with initialization +var ( + s1 = i + j + s2 = i /* ERROR "mismatched types" */ + x + s3 = c + d + s4 = s + t + s5 = s /* ERROR "invalid operation" */ / t + s6 = array[t1] + s7 = array[x /* ERROR "integer" */] + s8 = &a + s10 = &42 /* ERROR "cannot take address" */ + s11 = &v + s12 = -(u + *t11) / *&v + s13 = a /* ERROR "shifted operand" */ << d + s14 = i << j + s18 = math.Pi * 10.0 + s19 = s1 /* ERROR "cannot call" */ () + s20 = f0 /* ERROR "no value" */ () + s21 = f6(1, s1, i) + s22 = f6(1, s1, uu /* ERROR "cannot use .* in argument" */ ) + + t1 int = i + j + t2 int = i /* ERROR "mismatched types" */ + x + t3 int = c /* ERROR "cannot use .* variable declaration" */ + d + t4 string = s + t + t5 string = s /* ERROR "invalid operation" */ / t + t6 byte = array[t1] + t7 byte = array[x /* ERROR "must be integer" */] + t8 *int = & /* ERROR "cannot use .* variable declaration" */ a + t10 *int = &42 /* ERROR "cannot take address" */ + t11 *complex64 = &v + t12 complex64 = -(u + *t11) / *&v + t13 int = a /* ERROR "shifted operand" */ << d + t14 int = i << j + t15 math /* ERROR "not in selector" */ + t16 math.xxx /* ERROR "undefined" */ + t17 math /* ERROR "not a type" */ .Pi + t18 float64 = math.Pi * 10.0 + t19 int = t1 /* ERROR "cannot call" */ () + t20 int = f0 /* ERROR "no value" */ () + t21 int = a /* ERROR "cannot use .* variable declaration" */ +) + +// Various more complex expressions +var ( + u1 = x /* ERROR "not an interface" */ .(int) + u2 = iface.([]int) + u3 = iface.(a /* ERROR "not a type" */ ) + u4, ok = iface.(int) + u5, ok2, ok3 = iface /* ERROR "assignment mismatch" */ .(int) +) + +// Constant expression initializations +var ( + v1 = 1 /* ERROR "mismatched types untyped int and untyped string" */ + "foo" + v2 = c + 255 + v3 = c + 256 /* ERROR "overflows" */ + v4 = r + 2147483647 + v5 = r + 2147483648 /* ERROR "overflows" */ + v6 = 42 + v7 = v6 + 9223372036854775807 + v8 = v6 + 9223372036854775808 /* ERROR "overflows" */ + v9 = i + 1 << 10 + v10 byte = 1024 /* ERROR "overflows" */ + v11 = xx/yy*yy - xx + v12 = true && false + v13 = nil /* ERROR "use of untyped nil" */ + v14 string = 257 // ERROR cannot use 257 .* as string value in variable declaration$ + v15 int8 = 257 // ERROR cannot use 257 .* as int8 value in variable declaration .*overflows +) + +// Multiple assignment expressions +var ( + m1a, m1b = 1, 2 + m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2 + m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */ +) + +func _() { + var ( + m1a, m1b = 1, 2 + m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2 + m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */ + ) + + _, _ = m1a, m1b + _, _, _ = m2a, m2b, m2c + _, _ = m3a, m3b +} + +// Declaration of parameters and results +func f0() {} +func f1(a /* ERROR "not a type" */) {} +func f2(a, b, c d /* ERROR "not a type" */) {} + +func f3() int { return 0 } +func f4() a /* ERROR "not a type" */ { return 0 } +func f5() (a, b, c d /* ERROR "not a type" */) { return } + +func f6(a, b, c int) complex128 { return 0 } + +// Declaration of receivers +type T struct{} + +func (T) m0() {} +func (*T) m1() {} +func (x T) m2() {} +func (x *T) m3() {} + +// Initialization functions +func init() {} +func init /* ERROR "no arguments and no return values" */ (int) {} +func init /* ERROR "no arguments and no return values" */ () int { return 0 } +func init /* ERROR "no arguments and no return values" */ (int) int { return 0 } +func (T) init(int) int { return 0 } diff --git a/src/internal/types/testdata/check/decls2/decls2a.go b/src/internal/types/testdata/check/decls2/decls2a.go new file mode 100644 index 0000000..731405b --- /dev/null +++ b/src/internal/types/testdata/check/decls2/decls2a.go @@ -0,0 +1,111 @@ +// Copyright 2012 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. + +// method declarations + +package decls2 + +import "time" +import "unsafe" + +// T1 declared before its methods. +type T1 struct{ + f int +} + +func (T1) m() {} +func (T1) m /* ERROR "already declared" */ () {} +func (x *T1) f /* ERROR "field and method" */ () {} + +// Conflict between embedded field and method name, +// with the embedded field being a basic type. +type T1b struct { + int +} + +func (T1b) int /* ERROR "field and method" */ () {} + +type T1c struct { + time.Time +} + +func (T1c) Time /* ERROR "field and method" */ () int { return 0 } + +// Disabled for now: LookupFieldOrMethod will find Pointer even though +// it's double-declared (it would cost extra in the common case to verify +// this). But the MethodSet computation will not find it due to the name +// collision caused by the double-declaration, leading to an internal +// inconsistency while we are verifying one computation against the other. +// var _ = T1c{}.Pointer + +// T2's method declared before the type. +func (*T2) f /* ERROR "field and method" */ () {} + +type T2 struct { + f int +} + +// Methods declared without a declared type. +func (undefined /* ERROR "undefined" */) m() {} +func (x *undefined /* ERROR "undefined" */) m() {} + +func (pi /* ERROR "not a type" */) m1() {} +func (x pi /* ERROR "not a type" */) m2() {} +func (x *pi /* ERROR "not a type" */ ) m3() {} + +// Blank types. +type _ struct { m int } +type _ struct { m int } + +func (_ /* ERROR "cannot use _" */) m() {} +func m(_ /* ERROR "cannot use _" */) {} + +// Methods with receiver base type declared in another file. +func (T3) m1() {} +func (*T3) m2() {} +func (x T3) m3() {} +func (x *T3) f /* ERROR "field and method" */ () {} + +// Methods of non-struct type. +type T4 func() + +func (self T4) m() func() { return self } + +// Methods associated with an interface. +type T5 interface { + m() int +} + +func (T5 /* ERROR "invalid receiver" */ ) m1() {} +func (T5 /* ERROR "invalid receiver" */ ) m2() {} + +// Methods associated with a named pointer type. +type ptr *int +func (ptr /* ERROR "invalid receiver" */ ) _() {} +func (* /* ERROR "invalid receiver" */ ptr) _() {} + +// Methods with zero or multiple receivers. +func ( /* ERROR "method has no receiver" */ ) _() {} +func (T3, * /* ERROR "method has multiple receivers" */ T3) _() {} +func (T3, T3, T3 /* ERROR "method has multiple receivers" */ ) _() {} +func (a, b /* ERROR "method has multiple receivers" */ T3) _() {} +func (a, b, c /* ERROR "method has multiple receivers" */ T3) _() {} + +// Methods associated with non-local or unnamed types. +func (int /* ERROR "cannot define new methods on non-local type int" */ ) m() {} +func ([ /* ERROR "invalid receiver" */ ]int) m() {} +func (time /* ERROR "cannot define new methods on non-local type time\.Time" */ .Time) m() {} +func (* /* ERROR "cannot define new methods on non-local type time\.Time" */ time.Time) m() {} +func (x /* ERROR "invalid receiver" */ interface{}) m() {} + +// Unsafe.Pointer is treated like a pointer when used as receiver type. +type UP unsafe.Pointer +func (UP /* ERROR "invalid" */ ) m1() {} +func (* /* ERROR "invalid" */ UP) m2() {} + +// Double declarations across package files +const c_double = 0 +type t_double int +var v_double int +func f_double() {} diff --git a/src/internal/types/testdata/check/decls2/decls2b.go b/src/internal/types/testdata/check/decls2/decls2b.go new file mode 100644 index 0000000..d4c5861 --- /dev/null +++ b/src/internal/types/testdata/check/decls2/decls2b.go @@ -0,0 +1,75 @@ +// Copyright 2012 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. + +// method declarations + +package decls2 + +import "io" + +const pi = 3.1415 + +func (T1) m /* ERROR "already declared" */ () {} +func (T2) m(io.Writer) {} + +type T3 struct { + f *T3 +} + +type T6 struct { + x int +} + +func (t *T6) m1() int { + return t.x +} + +func f() { + var t *T6 + t.m1() +} + +// Double declarations across package files +const c_double /* ERROR "redeclared" */ = 0 +type t_double /* ERROR "redeclared" */ int +var v_double /* ERROR "redeclared" */ int +func f_double /* ERROR "redeclared" */ () {} + +// Blank methods need to be type-checked. +// Verify by checking that errors are reported. +func (T /* ERROR "undefined" */ ) _() {} +func (T1) _(undefined /* ERROR "undefined" */ ) {} +func (T1) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ } + +// Methods with undefined receiver type can still be checked. +// Verify by checking that errors are reported. +func (Foo /* ERROR "undefined" */ ) m() {} +func (Foo /* ERROR "undefined" */ ) m(undefined /* ERROR "undefined" */ ) {} +func (Foo /* ERROR "undefined" */ ) m() int { return "foo" /* ERROR "cannot use .* in return statement" */ } + +func (Foo /* ERROR "undefined" */ ) _() {} +func (Foo /* ERROR "undefined" */ ) _(undefined /* ERROR "undefined" */ ) {} +func (Foo /* ERROR "undefined" */ ) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ } + +// Receiver declarations are regular parameter lists; +// receiver types may use parentheses, and the list +// may have a trailing comma. +type T7 struct {} + +func (T7) m1() {} +func ((T7)) m2() {} +func ((*T7)) m3() {} +func (x *(T7),) m4() {} +func (x (*(T7)),) m5() {} +func (x ((*((T7)))),) m6() {} + +// Check that methods with parenthesized receiver are actually present (issue #23130). +var ( + _ = T7.m1 + _ = T7.m2 + _ = (*T7).m3 + _ = (*T7).m4 + _ = (*T7).m5 + _ = (*T7).m6 +) diff --git a/src/internal/types/testdata/check/decls3.go b/src/internal/types/testdata/check/decls3.go new file mode 100644 index 0000000..01d4ffe --- /dev/null +++ b/src/internal/types/testdata/check/decls3.go @@ -0,0 +1,309 @@ +// Copyright 2012 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. + +// embedded types + +package decls3 + +import "unsafe" +import "fmt" + +// fields with the same name at the same level cancel each other out + +func _() { + type ( + T1 struct { X int } + T2 struct { X int } + T3 struct { T1; T2 } // X is embedded twice at the same level via T1->X, T2->X + ) + + var t T3 + _ = t.X /* ERROR "ambiguous selector t.X" */ +} + +func _() { + type ( + T1 struct { X int } + T2 struct { T1 } + T3 struct { T1 } + T4 struct { T2; T3 } // X is embedded twice at the same level via T2->T1->X, T3->T1->X + ) + + var t T4 + _ = t.X /* ERROR "ambiguous selector t.X" */ +} + +func issue4355() { + type ( + T1 struct {X int} + T2 struct {T1} + T3 struct {T2} + T4 struct {T2} + T5 struct {T3; T4} // X is embedded twice at the same level via T3->T2->T1->X, T4->T2->T1->X + ) + + var t T5 + _ = t.X /* ERROR "ambiguous selector t.X" */ +} + +func _() { + type State int + type A struct{ State } + type B struct{ fmt.State } + type T struct{ A; B } + + var t T + _ = t.State /* ERROR "ambiguous selector t.State" */ +} + +// Embedded fields can be predeclared types. + +func _() { + type T0 struct{ + int + float32 + f int + } + var x T0 + _ = x.int + _ = x.float32 + _ = x.f + + type T1 struct{ + T0 + } + var y T1 + _ = y.int + _ = y.float32 + _ = y.f +} + +// Restrictions on embedded field types. + +func _() { + type I1 interface{} + type I2 interface{} + type P1 *int + type P2 *int + type UP unsafe.Pointer + + type T1 struct { + I1 + * /* ERROR "cannot be a pointer to an interface" */ I2 + * /* ERROR "cannot be a pointer to an interface" */ error + P1 /* ERROR "cannot be a pointer" */ + * /* ERROR "cannot be a pointer" */ P2 + } + + // unsafe.Pointers are treated like regular pointers when embedded + type T2 struct { + unsafe /* ERROR "cannot be unsafe.Pointer" */ .Pointer + */* ERROR "cannot be unsafe.Pointer" */ /* ERROR "Pointer redeclared" */ unsafe.Pointer + UP /* ERROR "cannot be unsafe.Pointer" */ + * /* ERROR "cannot be unsafe.Pointer" */ /* ERROR "UP redeclared" */ UP + } +} + +// Named types that are pointers. + +type S struct{ x int } +func (*S) m() {} +type P *S + +func _() { + var s *S + _ = s.x + _ = s.m + + var p P + _ = p.x + _ = p.m /* ERROR "no field or method" */ + _ = P.m /* ERROR "no field or method" */ +} + +// Borrowed from the FieldByName test cases in reflect/all_test.go. + +type D1 struct { + d int +} +type D2 struct { + d int +} + +type S0 struct { + A, B, C int + D1 + D2 +} + +type S1 struct { + B int + S0 +} + +type S2 struct { + A int + *S1 +} + +type S1x struct { + S1 +} + +type S1y struct { + S1 +} + +type S3 struct { + S1x + S2 + D, E int + *S1y +} + +type S4 struct { + *S4 + A int +} + +// The X in S6 and S7 annihilate, but they also block the X in S8.S9. +type S5 struct { + S6 + S7 + S8 +} + +type S6 struct { + X int +} + +type S7 S6 + +type S8 struct { + S9 +} + +type S9 struct { + X int + Y int +} + +// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9. +type S10 struct { + S11 + S12 + S13 +} + +type S11 struct { + S6 +} + +type S12 struct { + S6 +} + +type S13 struct { + S8 +} + +func _() { + _ = struct{}{}.Foo /* ERROR "no field or method" */ + _ = S0{}.A + _ = S0{}.D /* ERROR "no field or method" */ + _ = S1{}.A + _ = S1{}.B + _ = S1{}.S0 + _ = S1{}.C + _ = S2{}.A + _ = S2{}.S1 + _ = S2{}.B + _ = S2{}.C + _ = S2{}.D /* ERROR "no field or method" */ + _ = S3{}.S1 /* ERROR "ambiguous selector S3{}.S1" */ + _ = S3{}.A + _ = S3{}.B /* ERROR "ambiguous selector" S3{}.B */ + _ = S3{}.D + _ = S3{}.E + _ = S4{}.A + _ = S4{}.B /* ERROR "no field or method" */ + _ = S5{}.X /* ERROR "ambiguous selector S5{}.X" */ + _ = S5{}.Y + _ = S10{}.X /* ERROR "ambiguous selector S10{}.X" */ + _ = S10{}.Y +} + +// Borrowed from the FieldByName benchmark in reflect/all_test.go. + +type R0 struct { + *R1 + *R2 + *R3 + *R4 +} + +type R1 struct { + *R5 + *R6 + *R7 + *R8 +} + +type R2 R1 +type R3 R1 +type R4 R1 + +type R5 struct { + *R9 + *R10 + *R11 + *R12 +} + +type R6 R5 +type R7 R5 +type R8 R5 + +type R9 struct { + *R13 + *R14 + *R15 + *R16 +} + +type R10 R9 +type R11 R9 +type R12 R9 + +type R13 struct { + *R17 + *R18 + *R19 + *R20 +} + +type R14 R13 +type R15 R13 +type R16 R13 + +type R17 struct { + *R21 + *R22 + *R23 + *R24 +} + +type R18 R17 +type R19 R17 +type R20 R17 + +type R21 struct { + X int +} + +type R22 R21 +type R23 R21 +type R24 R21 + +var _ = R0{}.X /* ERROR "ambiguous selector R0{}.X" */
\ No newline at end of file diff --git a/src/internal/types/testdata/check/decls4.go b/src/internal/types/testdata/check/decls4.go new file mode 100644 index 0000000..c1294ee --- /dev/null +++ b/src/internal/types/testdata/check/decls4.go @@ -0,0 +1,199 @@ +// Copyright 2016 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. + +// type aliases + +package decls4 + +type ( + T0 [10]int + T1 []byte + T2 struct { + x int + } + T3 interface{ + m() T2 + } + T4 func(int, T0) chan T2 +) + +type ( + Ai = int + A0 = T0 + A1 = T1 + A2 = T2 + A3 = T3 + A4 = T4 + + A10 = [10]int + A11 = []byte + A12 = struct { + x int + } + A13 = interface{ + m() A2 + } + A14 = func(int, A0) chan A2 +) + +// check assignment compatibility due to equality of types +var ( + xi_ int + ai Ai = xi_ + + x0 T0 + a0 A0 = x0 + + x1 T1 + a1 A1 = x1 + + x2 T2 + a2 A2 = x2 + + x3 T3 + a3 A3 = x3 + + x4 T4 + a4 A4 = x4 +) + +// alias receiver types +func (Ai /* ERROR "cannot define new methods on non-local type int" */) m1() {} +func (T0) m1() {} +func (A0) m1 /* ERROR already declared */ () {} +func (A0) m2 () {} +func (A3 /* ERROR invalid receiver */ ) m1 () {} +func (A10 /* ERROR invalid receiver */ ) m1() {} + +// x0 has methods m1, m2 declared via receiver type names T0 and A0 +var _ interface{ m1(); m2() } = x0 + +// alias receiver types (test case for issue #23042) +type T struct{} + +var ( + _ = T.m + _ = T{}.m + _ interface{m()} = T{} +) + +var ( + _ = T.n + _ = T{}.n + _ interface{m(); n()} = T{} +) + +type U = T +func (U) m() {} + +// alias receiver types (long type declaration chains) +type ( + V0 = V1 + V1 = (V2) + V2 = ((V3)) + V3 = T +) + +func (V0) m /* ERROR already declared */ () {} +func (V1) n() {} + +// alias receiver types (invalid due to cycles) +type ( + W0 /* ERROR invalid recursive type */ = W1 + W1 = (W2) + W2 = ((W0)) +) + +func (W0) m() {} // no error expected (due to above cycle error) +func (W1) n() {} + +// alias receiver types (invalid due to builtin underlying type) +type ( + B0 = B1 + B1 = B2 + B2 = int +) + +func (B0 /* ERROR cannot define new methods on non-local type int */ ) m() {} +func (B1 /* ERROR cannot define new methods on non-local type int */ ) n() {} + +// cycles +type ( + C2 /* ERROR invalid recursive type */ = C2 + C3 /* ERROR invalid recursive type */ = C4 + C4 = C3 + C5 struct { + f *C6 + } + C6 = C5 + C7 /* ERROR invalid recursive type */ struct { + f C8 + } + C8 = C7 +) + +// embedded fields +var ( + s0 struct { T0 } + s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different +) + +// embedding and lookup of fields and methods +func _(s struct{A0}) { s.A0 = x0 } + +type eX struct{xf int} + +func (eX) xm() + +type eY = struct{eX} // field/method set of eY includes xf, xm + +type eZ = *struct{eX} // field/method set of eZ includes xf, xm + +type eA struct { + eX // eX contributes xf, xm to eA +} + +type eA2 struct { + *eX // *eX contributes xf, xm to eA +} + +type eB struct { + eY // eY contributes xf, xm to eB +} + +type eB2 struct { + *eY // *eY contributes xf, xm to eB +} + +type eC struct { + eZ // eZ contributes xf, xm to eC +} + +var ( + _ = eA{}.xf + _ = eA{}.xm + _ = eA2{}.xf + _ = eA2{}.xm + _ = eB{}.xf + _ = eB{}.xm + _ = eB2{}.xf + _ = eB2{}.xm + _ = eC{}.xf + _ = eC{}.xm +) + +// ambiguous selectors due to embedding via type aliases +type eD struct { + eY + eZ +} + +var ( + _ = eD{}.xf /* ERROR ambiguous selector eD{}.xf */ + _ = eD{}.xm /* ERROR ambiguous selector eD{}.xm */ +) + +var ( + _ interface{ xm() } = eD /* ERROR missing method xm */ {} +)
\ No newline at end of file diff --git a/src/internal/types/testdata/check/decls5.go b/src/internal/types/testdata/check/decls5.go new file mode 100644 index 0000000..88d3194 --- /dev/null +++ b/src/internal/types/testdata/check/decls5.go @@ -0,0 +1,10 @@ +// Copyright 2017 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. + +package main + +// declarations of main +const _, main /* ERROR "cannot declare main" */ , _ = 0, 1, 2 +type main /* ERROR "cannot declare main" */ struct{} +var _, main /* ERROR "cannot declare main" */ int diff --git a/src/internal/types/testdata/check/errors.go b/src/internal/types/testdata/check/errors.go new file mode 100644 index 0000000..b3ab8af --- /dev/null +++ b/src/internal/types/testdata/check/errors.go @@ -0,0 +1,66 @@ +// Copyright 2013 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. + +package errors + +// Testing precise operand formatting in error messages +// (matching messages are regular expressions, hence the \'s). +func f(x int, m map[string]int) { + // no values + _ = f /* ERROR f\(0, m\) \(no value\) used as value */ (0, m) + + // built-ins + _ = println // ERROR println \(built-in\) must be called + + // types + _ = complex128 // ERROR complex128 \(type\) is not an expression + + // constants + const c1 = 991 + const c2 float32 = 0.5 + const c3 = "foo" + 0 // ERROR 0 \(untyped int constant\) is not used + 0.5 // ERROR 0.5 \(untyped float constant\) is not used + "foo" // ERROR "foo" \(untyped string constant\) is not used + c1 // ERROR c1 \(untyped int constant 991\) is not used + c2 // ERROR c2 \(constant 0.5 of type float32\) is not used + c1 /* ERROR c1 \+ c2 \(constant 991.5 of type float32\) is not used */ + c2 + c3 // ERROR c3 \(untyped string constant "foo"\) is not used + + // variables + x // ERROR x \(variable of type int\) is not used + + // values + nil // ERROR nil is not used + ( /* ERROR \(\*int\)\(nil\) \(value of type \*int\) is not used */ *int)(nil) + x /* ERROR x != x \(untyped bool value\) is not used */ != x + x /* ERROR x \+ x \(value of type int\) is not used */ + x + + // value, ok's + const s = "foo" + m /* ERROR m\[s\] \(map index expression of type int\) is not used */ [s] +} + +// Valid ERROR comments can have a variety of forms. +func _() { + 0 /* ERROR "0 .* is not used" */ + 0 /* ERROR 0 .* is not used */ + 0 // ERROR "0 .* is not used" + 0 // ERROR 0 .* is not used +} + +// Don't report spurious errors as a consequence of earlier errors. +// Add more tests as needed. +func _() { + if err := foo /* ERROR undefined */ (); err != nil /* no error here */ {} +} + +// Use unqualified names for package-local objects. +type T struct{} +var _ int = T /* ERROR value of type T */ {} // use T in error message rather then errors.T + +// Don't report errors containing "invalid type" (issue #24182). +func _(x *missing /* ERROR undefined: missing */ ) { + x.m() // there shouldn't be an error here referring to *invalid type +} diff --git a/src/internal/types/testdata/check/expr0.go b/src/internal/types/testdata/check/expr0.go new file mode 100644 index 0000000..dd86eca --- /dev/null +++ b/src/internal/types/testdata/check/expr0.go @@ -0,0 +1,187 @@ +// Copyright 2012 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. + +// unary expressions + +package expr0 + +type mybool bool + +var ( + // bool + b0 = true + b1 bool = b0 + b2 = !true + b3 = !b1 + b4 bool = !true + b5 bool = !b4 + b6 = +b0 /* ERROR "not defined" */ + b7 = -b0 /* ERROR "not defined" */ + b8 = ^b0 /* ERROR "not defined" */ + b9 = *b0 /* ERROR "cannot indirect" */ + b10 = &true /* ERROR "cannot take address" */ + b11 = &b0 + b12 = <-b0 /* ERROR "cannot receive" */ + b13 = & & /* ERROR "cannot take address" */ b0 + + // byte + _ = byte(0) + _ = byte(- /* ERROR "cannot convert" */ 1) + _ = - /* ERROR "-byte\(1\) \(constant -1 of type byte\) overflows byte" */ byte(1) // test for issue 11367 + _ = byte /* ERROR "overflows byte" */ (0) - byte(1) + + // int + i0 = 1 + i1 int = i0 + i2 = +1 + i3 = +i0 + i4 int = +1 + i5 int = +i4 + i6 = -1 + i7 = -i0 + i8 int = -1 + i9 int = -i4 + i10 = !i0 /* ERROR "not defined" */ + i11 = ^1 + i12 = ^i0 + i13 int = ^1 + i14 int = ^i4 + i15 = *i0 /* ERROR "cannot indirect" */ + i16 = &i0 + i17 = *i16 + i18 = <-i16 /* ERROR "cannot receive" */ + + // uint + u0 = uint(1) + u1 uint = u0 + u2 = +1 + u3 = +u0 + u4 uint = +1 + u5 uint = +u4 + u6 = -1 + u7 = -u0 + u8 uint = - /* ERROR "overflows" */ 1 + u9 uint = -u4 + u10 = !u0 /* ERROR "not defined" */ + u11 = ^1 + u12 = ^i0 + u13 uint = ^ /* ERROR "overflows" */ 1 + u14 uint = ^u4 + u15 = *u0 /* ERROR "cannot indirect" */ + u16 = &u0 + u17 = *u16 + u18 = <-u16 /* ERROR "cannot receive" */ + u19 = ^uint(0) + + // float64 + f0 = float64(1) + f1 float64 = f0 + f2 = +1 + f3 = +f0 + f4 float64 = +1 + f5 float64 = +f4 + f6 = -1 + f7 = -f0 + f8 float64 = -1 + f9 float64 = -f4 + f10 = !f0 /* ERROR "not defined" */ + f11 = ^1 + f12 = ^i0 + f13 float64 = ^1 + f14 float64 = ^f4 /* ERROR "not defined" */ + f15 = *f0 /* ERROR "cannot indirect" */ + f16 = &f0 + f17 = *u16 + f18 = <-u16 /* ERROR "cannot receive" */ + + // complex128 + c0 = complex128(1) + c1 complex128 = c0 + c2 = +1 + c3 = +c0 + c4 complex128 = +1 + c5 complex128 = +c4 + c6 = -1 + c7 = -c0 + c8 complex128 = -1 + c9 complex128 = -c4 + c10 = !c0 /* ERROR "not defined" */ + c11 = ^1 + c12 = ^i0 + c13 complex128 = ^1 + c14 complex128 = ^c4 /* ERROR "not defined" */ + c15 = *c0 /* ERROR "cannot indirect" */ + c16 = &c0 + c17 = *u16 + c18 = <-u16 /* ERROR "cannot receive" */ + + // string + s0 = "foo" + s1 = +"foo" /* ERROR "not defined" */ + s2 = -s0 /* ERROR "not defined" */ + s3 = !s0 /* ERROR "not defined" */ + s4 = ^s0 /* ERROR "not defined" */ + s5 = *s4 + s6 = &s4 + s7 = *s6 + s8 = <-s7 + + // channel + ch chan int + rc <-chan float64 + sc chan <- string + ch0 = +ch /* ERROR "not defined" */ + ch1 = -ch /* ERROR "not defined" */ + ch2 = !ch /* ERROR "not defined" */ + ch3 = ^ch /* ERROR "not defined" */ + ch4 = *ch /* ERROR "cannot indirect" */ + ch5 = &ch + ch6 = *ch5 + ch7 = <-ch + ch8 = <-rc + ch9 = <-sc /* ERROR "cannot receive" */ + ch10, ok = <-ch + // ok is of type bool + ch11, myok = <-ch + _ mybool = myok /* ERROR "cannot use .* in variable declaration" */ +) + +// address of composite literals +type T struct{x, y int} + +func f() T { return T{} } + +var ( + _ = &T{1, 2} + _ = &[...]int{} + _ = &[]int{} + _ = &[]int{} + _ = &map[string]T{} + _ = &(T{1, 2}) + _ = &((((T{1, 2})))) + _ = &f /* ERROR "cannot take address" */ () +) + +// recursive pointer types +type P *P + +var ( + p1 P = new(P) + p2 P = *p1 + p3 P = &p2 +) + +func g() (a, b int) { return } + +func _() { + _ = -g /* ERROR multiple-value g */ () + _ = <-g /* ERROR multiple-value g */ () +} + +// ~ is accepted as unary operator only permitted in interface type elements +var ( + _ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ 0 + _ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ "foo" + _ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ i0 +) diff --git a/src/internal/types/testdata/check/expr1.go b/src/internal/types/testdata/check/expr1.go new file mode 100644 index 0000000..49e8bae --- /dev/null +++ b/src/internal/types/testdata/check/expr1.go @@ -0,0 +1,127 @@ +// Copyright 2012 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. + +// binary expressions + +package expr1 + +type mybool bool + +func _(x, y bool, z mybool) { + x = x || y + x = x || true + x = x || false + x = x && y + x = x && true + x = x && false + + z = z /* ERROR mismatched types */ || y + z = z || true + z = z || false + z = z /* ERROR mismatched types */ && y + z = z && true + z = z && false +} + +type myint int + +func _(x, y int, z myint) { + x = x + 1 + x = x + 1.0 + x = x + 1.1 // ERROR truncated to int + x = x + y + x = x - y + x = x * y + x = x / y + x = x % y + x = x << y + x = x >> y + + z = z + 1 + z = z + 1.0 + z = z + 1.1 // ERROR truncated to int + z = z /* ERROR mismatched types */ + y + z = z /* ERROR mismatched types */ - y + z = z /* ERROR mismatched types */ * y + z = z /* ERROR mismatched types */ / y + z = z /* ERROR mismatched types */ % y + z = z << y + z = z >> y +} + +type myuint uint + +func _(x, y uint, z myuint) { + x = x + 1 + x = x + - /* ERROR overflows uint */ 1 + x = x + 1.0 + x = x + 1.1 // ERROR truncated to uint + x = x + y + x = x - y + x = x * y + x = x / y + x = x % y + x = x << y + x = x >> y + + z = z + 1 + z = x + - /* ERROR overflows uint */ 1 + z = z + 1.0 + z = z + 1.1 // ERROR truncated to uint + z = z /* ERROR mismatched types */ + y + z = z /* ERROR mismatched types */ - y + z = z /* ERROR mismatched types */ * y + z = z /* ERROR mismatched types */ / y + z = z /* ERROR mismatched types */ % y + z = z << y + z = z >> y +} + +type myfloat64 float64 + +func _(x, y float64, z myfloat64) { + x = x + 1 + x = x + -1 + x = x + 1.0 + x = x + 1.1 + x = x + y + x = x - y + x = x * y + x = x / y + x = x /* ERROR not defined */ % y + x = x /* ERROR operand x .* must be integer */ << y + x = x /* ERROR operand x .* must be integer */ >> y + + z = z + 1 + z = z + -1 + z = z + 1.0 + z = z + 1.1 + z = z /* ERROR mismatched types */ + y + z = z /* ERROR mismatched types */ - y + z = z /* ERROR mismatched types */ * y + z = z /* ERROR mismatched types */ / y + z = z /* ERROR mismatched types */ % y + z = z /* ERROR operand z .* must be integer */ << y + z = z /* ERROR operand z .* must be integer */ >> y +} + +type mystring string + +func _(x, y string, z mystring) { + x = x + "foo" + x = x /* ERROR not defined */ - "foo" + x = x /* ERROR mismatched types string and untyped int */ + 1 + x = x + y + x = x /* ERROR not defined */ - y + x = x /* ERROR mismatched types string and untyped int */* 10 +} + +func f() (a, b int) { return } + +func _(x int) { + _ = f /* ERROR multiple-value f */ () + 1 + _ = x + f /* ERROR multiple-value f */ () + _ = f /* ERROR multiple-value f */ () + f + _ = f /* ERROR multiple-value f */ () + f /* ERROR multiple-value f */ () +} diff --git a/src/internal/types/testdata/check/expr2.go b/src/internal/types/testdata/check/expr2.go new file mode 100644 index 0000000..1929664 --- /dev/null +++ b/src/internal/types/testdata/check/expr2.go @@ -0,0 +1,260 @@ +// Copyright 2012 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. + +// comparisons + +package expr2 + +func _bool() { + const t = true == true + const f = true == false + _ = t /* ERROR operator .* not defined */ < f + _ = 0 == t /* ERROR mismatched types untyped int and untyped bool */ + var b bool + var x, y float32 + b = x < y + _ = b + _ = struct{b bool}{x < y} +} + +// corner cases +var ( + v0 = nil == nil // ERROR operator == not defined on untyped nil +) + +func arrays() { + // basics + var a, b [10]int + _ = a == b + _ = a != b + _ = a /* ERROR < not defined */ < b + _ = a == nil /* ERROR mismatched types */ + + type C [10]int + var c C + _ = a == c + + type D [10]int + var d D + _ = c == d /* ERROR mismatched types */ + + var e [10]func() int + _ = e /* ERROR \[10\]func\(\) int cannot be compared */ == e +} + +func structs() { + // basics + var s, t struct { + x int + a [10]float32 + _ bool + } + _ = s == t + _ = s != t + _ = s /* ERROR < not defined */ < t + _ = s == nil /* ERROR mismatched types */ + + type S struct { + x int + a [10]float32 + _ bool + } + type T struct { + x int + a [10]float32 + _ bool + } + var ss S + var tt T + _ = s == ss + _ = ss == tt /* ERROR mismatched types */ + + var u struct { + x int + a [10]map[string]int + } + _ = u /* ERROR cannot be compared */ == u +} + +func pointers() { + // nil + _ = nil == nil // ERROR operator == not defined on untyped nil + _ = nil != nil // ERROR operator != not defined on untyped nil + _ = nil /* ERROR < not defined */ < nil + _ = nil /* ERROR <= not defined */ <= nil + _ = nil /* ERROR > not defined */ > nil + _ = nil /* ERROR >= not defined */ >= nil + + // basics + var p, q *int + _ = p == q + _ = p != q + + _ = p == nil + _ = p != nil + _ = nil == q + _ = nil != q + + _ = p /* ERROR < not defined */ < q + _ = p /* ERROR <= not defined */ <= q + _ = p /* ERROR > not defined */ > q + _ = p /* ERROR >= not defined */ >= q + + // various element types + type ( + S1 struct{} + S2 struct{} + P1 *S1 + P2 *S2 + ) + var ( + ps1 *S1 + ps2 *S2 + p1 P1 + p2 P2 + ) + _ = ps1 == ps1 + _ = ps1 == ps2 /* ERROR mismatched types */ + _ = ps2 == ps1 /* ERROR mismatched types */ + + _ = p1 == p1 + _ = p1 == p2 /* ERROR mismatched types */ + + _ = p1 == ps1 +} + +func channels() { + // basics + var c, d chan int + _ = c == d + _ = c != d + _ = c == nil + _ = c /* ERROR < not defined */ < d + + // various element types (named types) + type ( + C1 chan int + C1r <-chan int + C1s chan<- int + C2 chan float32 + ) + var ( + c1 C1 + c1r C1r + c1s C1s + c1a chan int + c2 C2 + ) + _ = c1 == c1 + _ = c1 == c1r /* ERROR mismatched types */ + _ = c1 == c1s /* ERROR mismatched types */ + _ = c1r == c1s /* ERROR mismatched types */ + _ = c1 == c1a + _ = c1a == c1 + _ = c1 == c2 /* ERROR mismatched types */ + _ = c1a == c2 /* ERROR mismatched types */ + + // various element types (unnamed types) + var ( + d1 chan int + d1r <-chan int + d1s chan<- int + d1a chan<- int + d2 chan float32 + ) + _ = d1 == d1 + _ = d1 == d1r + _ = d1 == d1s + _ = d1r == d1s /* ERROR mismatched types */ + _ = d1 == d1a + _ = d1a == d1 + _ = d1 == d2 /* ERROR mismatched types */ + _ = d1a == d2 /* ERROR mismatched types */ +} + +// for interfaces test +type S1 struct{} +type S11 struct{} +type S2 struct{} +func (*S1) m() int +func (*S11) m() int +func (*S11) n() +func (*S2) m() float32 + +func interfaces() { + // basics + var i, j interface{ m() int } + _ = i == j + _ = i != j + _ = i == nil + _ = i /* ERROR < not defined */ < j + + // various interfaces + var ii interface { m() int; n() } + var k interface { m() float32 } + _ = i == ii + _ = i == k /* ERROR mismatched types */ + + // interfaces vs values + var s1 S1 + var s11 S11 + var s2 S2 + + _ = i == 0 /* ERROR cannot convert */ + _ = i == s1 /* ERROR mismatched types */ + _ = i == &s1 + _ = i == &s11 + + _ = i == s2 /* ERROR mismatched types */ + _ = i == & /* ERROR mismatched types */ s2 + + // issue #28164 + // testcase from issue + _ = interface{}(nil) == [ /* ERROR slice can only be compared to nil */ ]int(nil) + + // related cases + var e interface{} + var s []int + var x int + _ = e == s // ERROR slice can only be compared to nil + _ = s /* ERROR slice can only be compared to nil */ == e + _ = e /* ERROR operator < not defined on interface */ < x + _ = x < e // ERROR operator < not defined on interface +} + +func slices() { + // basics + var s []int + _ = s == nil + _ = s != nil + _ = s /* ERROR < not defined */ < nil + + // slices are not otherwise comparable + _ = s /* ERROR slice can only be compared to nil */ == s + _ = s /* ERROR < not defined */ < s +} + +func maps() { + // basics + var m map[string]int + _ = m == nil + _ = m != nil + _ = m /* ERROR < not defined */ < nil + + // maps are not otherwise comparable + _ = m /* ERROR map can only be compared to nil */ == m + _ = m /* ERROR < not defined */ < m +} + +func funcs() { + // basics + var f func(int) float32 + _ = f == nil + _ = f != nil + _ = f /* ERROR < not defined */ < nil + + // funcs are not otherwise comparable + _ = f /* ERROR func can only be compared to nil */ == f + _ = f /* ERROR < not defined */ < f +} diff --git a/src/internal/types/testdata/check/expr3.go b/src/internal/types/testdata/check/expr3.go new file mode 100644 index 0000000..2da5984 --- /dev/null +++ b/src/internal/types/testdata/check/expr3.go @@ -0,0 +1,564 @@ +// Copyright 2012 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. + +package expr3 + +import "time" + +func indexes() { + _ = 1 /* ERROR "cannot index" */ [0] + _ = indexes /* ERROR "cannot index" */ [0] + _ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2] + + var a [10]int + _ = a[true /* ERROR "cannot convert" */ ] + _ = a["foo" /* ERROR "cannot convert" */ ] + _ = a[1.1 /* ERROR "truncated" */ ] + _ = a[1.0] + _ = a[- /* ERROR "negative" */ 1] + _ = a[- /* ERROR "negative" */ 1 :] + _ = a[: - /* ERROR "negative" */ 1] + _ = a[: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ] + _ = a[0: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ] + _ = a[0: /* ERROR "middle index required" */ :10] + _ = a[:10:10] + + var a0 int + a0 = a[0] + _ = a0 + var a1 int32 + a1 = a /* ERROR "cannot use .* in assignment" */ [1] + _ = a1 + + _ = a[9] + _ = a[10 /* ERROR "index .* out of bounds" */ ] + _ = a[1 /* ERROR "overflows" */ <<100] + _ = a[1<< /* ERROR "constant shift overflow" */ 1000] // no out-of-bounds follow-on error + _ = a[10:] + _ = a[:10] + _ = a[10:10] + _ = a[11 /* ERROR "index .* out of bounds" */ :] + _ = a[: 11 /* ERROR "index .* out of bounds" */ ] + _ = a[: 1 /* ERROR "overflows" */ <<100] + _ = a[:10:10] + _ = a[:11 /* ERROR "index .* out of bounds" */ :10] + _ = a[:10:11 /* ERROR "index .* out of bounds" */ ] + _ = a[10:0 /* ERROR "invalid slice indices" */ :10] + _ = a[0:10:0 /* ERROR "invalid slice indices" */ ] + _ = a[10:0 /* ERROR "invalid slice indices" */:0] + _ = &a /* ERROR "cannot take address" */ [:10] + + pa := &a + _ = pa[9] + _ = pa[10 /* ERROR "index .* out of bounds" */ ] + _ = pa[1 /* ERROR "overflows" */ <<100] + _ = pa[10:] + _ = pa[:10] + _ = pa[10:10] + _ = pa[11 /* ERROR "index .* out of bounds" */ :] + _ = pa[: 11 /* ERROR "index .* out of bounds" */ ] + _ = pa[: 1 /* ERROR "overflows" */ <<100] + _ = pa[:10:10] + _ = pa[:11 /* ERROR "index .* out of bounds" */ :10] + _ = pa[:10:11 /* ERROR "index .* out of bounds" */ ] + _ = pa[10:0 /* ERROR "invalid slice indices" */ :10] + _ = pa[0:10:0 /* ERROR "invalid slice indices" */ ] + _ = pa[10:0 /* ERROR "invalid slice indices" */ :0] + _ = &pa /* ERROR "cannot take address" */ [:10] + + var b [0]int + _ = b[0 /* ERROR "index .* out of bounds" */ ] + _ = b[:] + _ = b[0:] + _ = b[:0] + _ = b[0:0] + _ = b[0:0:0] + _ = b[1 /* ERROR "index .* out of bounds" */ :0:0] + + var s []int + _ = s[- /* ERROR "negative" */ 1] + _ = s[- /* ERROR "negative" */ 1 :] + _ = s[: - /* ERROR "negative" */ 1] + _ = s[0] + _ = s[1:2] + _ = s[2:1 /* ERROR "invalid slice indices" */ ] + _ = s[2:] + _ = s[: 1 /* ERROR "overflows" */ <<100] + _ = s[1 /* ERROR "overflows" */ <<100 :] + _ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100] + _ = s[: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ] + _ = s[:10:10] + _ = s[10:0 /* ERROR "invalid slice indices" */ :10] + _ = s[0:10:0 /* ERROR "invalid slice indices" */ ] + _ = s[10:0 /* ERROR "invalid slice indices" */ :0] + _ = &s /* ERROR "cannot take address" */ [:10] + + var m map[string]int + _ = m[0 /* ERROR "cannot use .* in map index" */ ] + _ = m /* ERROR "cannot slice" */ ["foo" : "bar"] + _ = m["foo"] + // ok is of type bool + type mybool bool + var ok mybool + _, ok = m["bar"] + _ = ok + _ = m/* ERROR "mismatched types int and untyped string" */[0 /* ERROR "cannot use 0" */ ] + "foo" + + var t string + _ = t[- /* ERROR "negative" */ 1] + _ = t[- /* ERROR "negative" */ 1 :] + _ = t[: - /* ERROR "negative" */ 1] + _ = t[1:2:3 /* ERROR "3-index slice of string" */ ] + _ = "foo"[1:2:3 /* ERROR "3-index slice of string" */ ] + var t0 byte + t0 = t[0] + _ = t0 + var t1 rune + t1 = t /* ERROR "cannot use .* in assignment" */ [2] + _ = t1 + _ = ("foo" + "bar")[5] + _ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ] + + const c = "foo" + _ = c[- /* ERROR "negative" */ 1] + _ = c[- /* ERROR "negative" */ 1 :] + _ = c[: - /* ERROR "negative" */ 1] + var c0 byte + c0 = c[0] + _ = c0 + var c2 float32 + c2 = c /* ERROR "cannot use .* in assignment" */ [2] + _ = c[3 /* ERROR "index .* out of bounds" */ ] + _ = ""[0 /* ERROR "index .* out of bounds" */ ] + _ = c2 + + _ = s[1<<30] // no compile-time error here + + // issue 4913 + type mystring string + var ss string + var ms mystring + var i, j int + ss = "foo"[1:2] + ss = "foo"[i:j] + ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2] + ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j] + _, _ = ss, ms +} + +type T struct { + x int + y func() +} + +func (*T) m() {} + +func method_expressions() { + _ = T.a /* ERROR "no field or method" */ + _ = T.x /* ERROR "has no method" */ + _ = T.m /* ERROR "invalid method expression T\.m \(needs pointer receiver \(\*T\)\.m\)" */ + _ = (*T).m + + var f func(*T) = T.m /* ERROR "invalid method expression T\.m \(needs pointer receiver \(\*T\)\.m\)" */ + var g func(*T) = (*T).m + _, _ = f, g + + _ = T.y /* ERROR "has no method" */ + _ = (*T).y /* ERROR "has no method" */ +} + +func struct_literals() { + type T0 struct { + a, b, c int + } + + type T1 struct { + T0 + a, b int + u float64 + s string + } + + // keyed elements + _ = T1{} + _ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ } + _ = T1{aa /* ERROR "unknown field" */ : 0} + _ = T1{1 /* ERROR "invalid field name" */ : 0} + _ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10} + _ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ } + _ = T1{c /* ERROR "unknown field" */ : 0} + _ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided + _ = T1{T0: T0{}} + _ = T1{T0 /* ERROR "invalid field name" */ .a: 0} + + // unkeyed elements + _ = T0{1, 2, 3} + _ = T0{1, b /* ERROR "mixture" */ : 2, 3} + _ = T0{1, 2} /* ERROR "too few values" */ + _ = T0{1, 2, 3, 4 /* ERROR "too many values" */ } + _ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4 /* ERROR "cannot use .*\(truncated\)" */} + + // invalid type + type P *struct{ + x int + } + _ = P /* ERROR "invalid composite literal type" */ {} + + // unexported fields + _ = time.Time{} + _ = time.Time{sec /* ERROR "unknown field" */ : 0} + _ = time.Time{ + 0 /* ERROR implicit assignment to unexported field wall in struct literal */, + 0 /* ERROR implicit assignment */ , + nil /* ERROR implicit assignment */ , + } +} + +func array_literals() { + type A0 [0]int + _ = A0{} + _ = A0{0 /* ERROR "index .* out of bounds" */} + _ = A0{0 /* ERROR "index .* out of bounds" */ : 0} + + type A1 [10]int + _ = A1{} + _ = A1{0, 1, 2} + _ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + _ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ } + _ = A1{- /* ERROR "negative" */ 1: 0} + _ = A1{8: 8, 9} + _ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ } + _ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4} + _ = A1{5: 5, 6, 7, 3: 3, 4} + _ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ } + _ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10} + _ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ } + _ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4} + _ = A1{2.0} + _ = A1{2.1 /* ERROR "truncated" */ } + _ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ } + + // indices must be integer constants + i := 1 + const f = 2.1 + const s = "foo" + _ = A1{i /* ERROR "index i must be integer constant" */ : 0} + _ = A1{f /* ERROR "truncated" */ : 0} + _ = A1{s /* ERROR "cannot convert" */ : 0} + + a0 := [...]int{} + assert(len(a0) == 0) + + a1 := [...]int{0, 1, 2} + assert(len(a1) == 3) + var a13 [3]int + var a14 [4]int + a13 = a1 + a14 = a1 /* ERROR "cannot use .* in assignment" */ + _, _ = a13, a14 + + a2 := [...]int{- /* ERROR "negative" */ 1: 0} + _ = a2 + + a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4} + assert(len(a3) == 5) // somewhat arbitrary + + a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14} + assert(len(a4) == 1024) + + // composite literal element types may be elided + type T []int + _ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}} + a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}} + assert(len(a6) == 8) + + // recursively so + _ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}} + + // from the spec + type Point struct { x, y float32 } + _ = [...]Point{Point{1.5, -3.5}, Point{0, 0}} + _ = [...]Point{{1.5, -3.5}, {0, 0}} + _ = [][]int{[]int{1, 2, 3}, []int{4, 5}} + _ = [][]int{{1, 2, 3}, {4, 5}} + _ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}} + _ = [...]*Point{{1.5, -3.5}, {0, 0}} +} + +func slice_literals() { + type S0 []int + _ = S0{} + _ = S0{0, 1, 2} + _ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + _ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + _ = S0{- /* ERROR "negative" */ 1: 0} + _ = S0{8: 8, 9} + _ = S0{8: 8, 9, 10} + _ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4} + _ = S0{5: 5, 6, 7, 3: 3, 4} + _ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ } + _ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10} + _ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ } + _ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4} + _ = S0{2.0} + _ = S0{2.1 /* ERROR "truncated" */ } + _ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ } + + // indices must be resolved correctly + const index1 = 1 + _ = S0{index1: 1} + _ = S0{index2: 2} + _ = S0{index3 /* ERROR "undefined" */ : 3} + + // indices must be integer constants + i := 1 + const f = 2.1 + const s = "foo" + _ = S0{i /* ERROR "index i must be integer constant" */ : 0} + _ = S0{f /* ERROR "truncated" */ : 0} + _ = S0{s /* ERROR "cannot convert" */ : 0} + + // composite literal element types may be elided + type T []int + _ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}} + _ = [][]int{{1, 2, 3}, {4, 5}} + + // recursively so + _ = [][]T{{}, []T{{}}, {{1, 2, 3}}} + + // issue 17954 + type T0 *struct { s string } + _ = []T0{{}} + _ = []T0{{"foo"}} + + type T1 *struct{ int } + _ = []T1{} + _ = []T1{{0}, {1}, {2}} + + type T2 T1 + _ = []T2{} + _ = []T2{{0}, {1}, {2}} + + _ = map[T0]T2{} + _ = map[T0]T2{{}: {}} +} + +const index2 int = 2 + +type N int +func (N) f() {} + +func map_literals() { + type M0 map[string]int + type M1 map[bool]int + type M2 map[*int]int + + _ = M0{} + _ = M0{1 /* ERROR "missing key" */ } + _ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2} + _ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ } + _ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 } + + _ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1} + _ = map[interface{}]int{int(2): 1, int16(2): 1} + _ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1} + + type S string + + _ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1} + _ = map[interface{}]int{"a": 1, S("a"): 1} + _ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1} + _ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1} + _ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1} + _ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1} + _ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1} + + type I interface { + f() + } + + _ = map[I]int{N(0): 1, N(2): 1} + _ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1} + + // map keys must be resolved correctly + key1 := "foo" + _ = M0{key1: 1} + _ = M0{key2: 2} + _ = M0{key3 /* ERROR "undefined" */ : 2} + + var value int + _ = M1{true: 1, false: 0} + _ = M2{nil: 0, &value: 1} + + // composite literal element types may be elided + type T [2]int + _ = map[int]T{0: T{3, 4}, 1: {5, 6}} + + // recursively so + _ = map[int][]T{0: {}, 1: {{}, T{1, 2}}} + + // composite literal key types may be elided + _ = map[T]int{T{3, 4}: 0, {5, 6}: 1} + + // recursively so + _ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3} + + // composite literal element and key types may be elided + _ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}} + _ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}} + + // recursively so + _ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}} + + // from the spec + type Point struct { x, y float32 } + _ = map[string]Point{"orig": {0, 0}} + _ = map[*Point]string{{0, 0}: "orig"} + + // issue 17954 + type T0 *struct{ s string } + type T1 *struct{ int } + type T2 T1 + + _ = map[T0]T2{} + _ = map[T0]T2{{}: {}} +} + +var key2 string = "bar" + +type I interface { + m() +} + +type I2 interface { + m(int) +} + +type T1 struct{} +type T2 struct{} + +func (T2) m(int) {} + +type mybool bool + +func type_asserts() { + var x int + _ = x /* ERROR "not an interface" */ .(int) + + var e interface{} + var ok bool + x, ok = e.(int) + _ = ok + + // ok value is of type bool + var myok mybool + _, myok = e.(int) + _ = myok + + var t I + _ = t /* ERROR "use of .* outside type switch" */ .(type) + _ = t /* ERROR "m has pointer receiver" */ .(T) + _ = t.(*T) + _ = t /* ERROR "missing method m" */ .(T1) + _ = t /* ERROR "wrong type for method m" */ .(T2) + _ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561) + + // e doesn't statically have an m, but may have one dynamically. + _ = e.(I2) +} + +func f0() {} +func f1(x int) {} +func f2(u float32, s string) {} +func fs(s []byte) {} +func fv(x ...int) {} +func fi(x ... interface{}) {} +func (T) fm(x ...int) + +func g0() {} +func g1() int { return 0} +func g2() (u float32, s string) { return } +func gs() []byte { return nil } + +func _calls() { + var x int + var y float32 + var s []int + + f0() + _ = f0 /* ERROR "used as value" */ () + f0(g0 /* ERROR "too many arguments" */ ) + + f1(0) + f1(x) + f1(10.0) + f1() /* ERROR "not enough arguments in call to f1\n\thave \(\)\n\twant \(int\)" */ + f1(x, y /* ERROR "too many arguments in call to f1\n\thave \(int, float32\)\n\twant \(int\)" */ ) + f1(s /* ERROR "cannot use .* in argument" */ ) + f1(x ... /* ERROR "cannot use ..." */ ) + f1(g0 /* ERROR "used as value" */ ()) + f1(g1()) + f1(g2 /* ERROR "too many arguments in call to f1\n\thave \(float32, string\)\n\twant \(int\)" */ ()) + + f2() /* ERROR "not enough arguments in call to f2\n\thave \(\)\n\twant \(float32, string\)" */ + f2(3.14) /* ERROR "not enough arguments in call to f2\n\thave \(number\)\n\twant \(float32, string\)" */ + f2(3.14, "foo") + f2(x /* ERROR "cannot use .* in argument" */ , "foo") + f2(g0 /* ERROR "used as value" */ ()) + f2(g1()) /* ERROR "not enough arguments in call to f2\n\thave \(int\)\n\twant \(float32, string\)" */ + f2(g2()) + + fs() /* ERROR "not enough arguments" */ + fs(g0 /* ERROR "used as value" */ ()) + fs(g1 /* ERROR "cannot use .* in argument" */ ()) + fs(g2 /* ERROR "too many arguments" */ ()) + fs(gs()) + + fv() + fv(1, 2.0, x) + fv(s /* ERROR "cannot use .* in argument" */ ) + fv(s...) + fv(x /* ERROR "cannot use" */ ...) + fv(1, s /* ERROR "too many arguments" */ ...) + fv(gs /* ERROR "cannot use .* in argument" */ ()) + fv(gs /* ERROR "cannot use .* in argument" */ ()...) + + var t T + t.fm() + t.fm(1, 2.0, x) + t.fm(s /* ERROR "cannot use .* in argument" */ ) + t.fm(g1()) + t.fm(1, s /* ERROR "too many arguments" */ ...) + t.fm(gs /* ERROR "cannot use .* in argument" */ ()) + t.fm(gs /* ERROR "cannot use .* in argument" */ ()...) + + T.fm(t, ) + T.fm(t, 1, 2.0, x) + T.fm(t, s /* ERROR "cannot use .* in argument" */ ) + T.fm(t, g1()) + T.fm(t, 1, s /* ERROR "too many arguments" */ ...) + T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()) + T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...) + + var i interface{ fm(x ...int) } = t + i.fm() + i.fm(1, 2.0, x) + i.fm(s /* ERROR "cannot use .* in argument" */ ) + i.fm(g1()) + i.fm(1, s /* ERROR "too many arguments" */ ...) + i.fm(gs /* ERROR "cannot use .* in argument" */ ()) + i.fm(gs /* ERROR "cannot use .* in argument" */ ()...) + + fi() + fi(1, 2.0, x, 3.14, "foo") + fi(g2()) + fi(0, g2) + fi(0, g2 /* ERROR "multiple-value g2" */ ()) +} + +func issue6344() { + type T []interface{} + var x T + fi(x...) // ... applies also to named slices +} diff --git a/src/internal/types/testdata/check/funcinference.go b/src/internal/types/testdata/check/funcinference.go new file mode 100644 index 0000000..fedf199 --- /dev/null +++ b/src/internal/types/testdata/check/funcinference.go @@ -0,0 +1,104 @@ +// 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. + +package funcInference + +import "strconv" + +type any interface{} + +func f0[A any, B interface{*C}, C interface{*D}, D interface{*A}](A, B, C, D) {} +func _() { + f := f0[string] + f("a", nil, nil, nil) + f0("a", nil, nil, nil) +} + +func f1[A any, B interface{*A}](A, B) {} +func _() { + f := f1[int] + f(int(0), new(int)) + f1(int(0), new(int)) +} + +func f2[A any, B interface{[]A}](A, B) {} +func _() { + f := f2[byte] + f(byte(0), []byte{}) + f2(byte(0), []byte{}) +} + +// Embedding stand-alone type parameters is not permitted for now. Disabled. +// func f3[A any, B interface{~C}, C interface{~*A}](A, B, C) +// func _() { +// f := f3[int] +// var x int +// f(x, &x, &x) +// f3(x, &x, &x) +// } + +func f4[A any, B interface{[]C}, C interface{*A}](A, B, C) {} +func _() { + f := f4[int] + var x int + f(x, []*int{}, &x) + f4(x, []*int{}, &x) +} + +func f5[A interface{struct{b B; c C}}, B any, C interface{*B}](x B) A { panic(0) } +func _() { + x := f5(1.2) + var _ float64 = x.b + var _ float64 = *x.c +} + +func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) } +func _() { + x := f6(struct{f []string}{}) + var _ string = x +} + +func f7[A interface{*B}, B interface{~*A}]() {} + +// More realistic examples + +func Double[S interface{ ~[]E }, E interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }](s S) S { + r := make(S, len(s)) + for i, v := range s { + r[i] = v + v + } + return r +} + +type MySlice []int + +var _ = Double(MySlice{1}) + +// From the draft design. + +type Setter[B any] interface { + Set(string) + *B +} + +func FromStrings[T interface{}, PT Setter[T]](s []string) []T { + result := make([]T, len(s)) + for i, v := range s { + // The type of &result[i] is *T which is in the type set + // of Setter, so we can convert it to PT. + p := PT(&result[i]) + // PT has a Set method. + p.Set(v) + } + return result +} + +type Settable int + +func (p *Settable) Set(s string) { + i, _ := strconv.Atoi(s) // real code should not ignore the error + *p = Settable(i) +} + +var _ = FromStrings[Settable]([]string{"1", "2"}) diff --git a/src/internal/types/testdata/check/go1_12.go b/src/internal/types/testdata/check/go1_12.go new file mode 100644 index 0000000..56c6d5a --- /dev/null +++ b/src/internal/types/testdata/check/go1_12.go @@ -0,0 +1,36 @@ +// -lang=go1.12 + +// Copyright 2021 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. + +// Check Go language version-specific errors. + +package p + +// numeric literals +const ( + _ = 1_000 // ERROR "underscores in numeric literals requires go1.13 or later" + _ = 0b111 // ERROR "binary literals requires go1.13 or later" + _ = 0o567 // ERROR "0o/0O-style octal literals requires go1.13 or later" + _ = 0xabc // ok + _ = 0x0p1 // ERROR "hexadecimal floating-point literals requires go1.13 or later" + + _ = 0B111 // ERROR "binary" + _ = 0O567 // ERROR "octal" + _ = 0Xabc // ok + _ = 0X0P1 // ERROR "hexadecimal floating-point" + + _ = 1_000i // ERROR "underscores" + _ = 0b111i // ERROR "binary" + _ = 0o567i // ERROR "octal" + _ = 0xabci // ERROR "hexadecimal floating-point" + _ = 0x0p1i // ERROR "hexadecimal floating-point" +) + +// signed shift counts +var ( + s int + _ = 1 << s // ERROR "invalid operation: signed shift count s \(variable of type int\) requires go1.13 or later" + _ = 1 >> s // ERROR "signed shift count" +) diff --git a/src/internal/types/testdata/check/go1_13.go b/src/internal/types/testdata/check/go1_13.go new file mode 100644 index 0000000..cc7861d --- /dev/null +++ b/src/internal/types/testdata/check/go1_13.go @@ -0,0 +1,23 @@ +// -lang=go1.13 + +// Copyright 2021 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. + +// Check Go language version-specific errors. + +package p + +// interface embedding + +type I interface { m() } + +type _ interface { + m() + I // ERROR "duplicate method m" +} + +type _ interface { + I + I // ERROR "duplicate method m" +} diff --git a/src/internal/types/testdata/check/go1_16.go b/src/internal/types/testdata/check/go1_16.go new file mode 100644 index 0000000..81b5290 --- /dev/null +++ b/src/internal/types/testdata/check/go1_16.go @@ -0,0 +1,15 @@ +// -lang=go1.16 + +// Copyright 2021 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. + +// Check Go language version-specific errors. + +package p + +type Slice []byte +type Array [8]byte + +var s Slice +var p = (*Array)(s /* ERROR requires go1.17 or later */ ) diff --git a/src/internal/types/testdata/check/go1_19.go b/src/internal/types/testdata/check/go1_19.go new file mode 100644 index 0000000..f899d93 --- /dev/null +++ b/src/internal/types/testdata/check/go1_19.go @@ -0,0 +1,15 @@ +// -lang=go1.19 + +// Copyright 2022 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. + +// Check Go language version-specific errors. + +package p + +type Slice []byte +type Array [8]byte + +var s Slice +var p = (Array)(s /* ERROR requires go1.20 or later */) diff --git a/src/internal/types/testdata/check/go1_8.go b/src/internal/types/testdata/check/go1_8.go new file mode 100644 index 0000000..99f2fd4 --- /dev/null +++ b/src/internal/types/testdata/check/go1_8.go @@ -0,0 +1,12 @@ +// -lang=go1.8 + +// Copyright 2021 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. + +// Check Go language version-specific errors. + +package p + +// type alias declarations +type any = /* ERROR type aliases requires go1.9 or later */ interface{} diff --git a/src/internal/types/testdata/check/gotos.go b/src/internal/types/testdata/check/gotos.go new file mode 100644 index 0000000..069a94b --- /dev/null +++ b/src/internal/types/testdata/check/gotos.go @@ -0,0 +1,560 @@ +// Copyright 2011 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 is a modified copy of $GOROOT/test/goto.go. + +package gotos + +var ( + i, n int + x []int + c chan int + m map[int]int + s string +) + +// goto after declaration okay +func _() { + x := 1 + goto L +L: + _ = x +} + +// goto before declaration okay +func _() { + goto L +L: + x := 1 + _ = x +} + +// goto across declaration not okay +func _() { + goto L /* ERROR "goto L jumps over variable declaration at line 36" */ + x := 1 + _ = x +L: +} + +// goto across declaration in inner scope okay +func _() { + goto L + { + x := 1 + _ = x + } +L: +} + +// goto across declaration after inner scope not okay +func _() { + goto L /* ERROR "goto L jumps over variable declaration at line 58" */ + { + x := 1 + _ = x + } + x := 1 + _ = x +L: +} + +// goto across declaration in reverse okay +func _() { +L: + x := 1 + _ = x + goto L +} + +func _() { +L: L1: + x := 1 + _ = x + goto L + goto L1 +} + +// error shows first offending variable +func _() { + goto L /* ERROR "goto L jumps over variable declaration at line 84" */ + x := 1 + _ = x + y := 1 + _ = y +L: +} + +// goto not okay even if code path is dead +func _() { + goto L /* ERROR "goto L jumps over variable declaration" */ + x := 1 + _ = x + y := 1 + _ = y + return +L: +} + +// goto into outer block okay +func _() { + { + goto L + } +L: +} + +func _() { + { + goto L + goto L1 + } +L: L1: +} + +// goto backward into outer block okay +func _() { +L: + { + goto L + } +} + +func _() { +L: L1: + { + goto L + goto L1 + } +} + +// goto into inner block not okay +func _() { + goto L /* ERROR "goto L jumps into block" */ + { + L: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + goto L1 /* ERROR "goto L1 jumps into block" */ + { + L: L1: + } +} + +// goto backward into inner block still not okay +func _() { + { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + { + L: L1: + } + goto L /* ERROR "goto L jumps into block" */ + goto L1 /* ERROR "goto L1 jumps into block" */ +} + +// error shows first (outermost) offending block +func _() { + goto L /* ERROR "goto L jumps into block" */ + { + { + { + L: + } + } + } +} + +// error prefers block diagnostic over declaration diagnostic +func _() { + goto L /* ERROR "goto L jumps into block" */ + x := 1 + _ = x + { + L: + } +} + +// many kinds of blocks, all invalid to jump into or among, +// but valid to jump out of + +// if + +func _() { +L: + if true { + goto L + } +} + +func _() { +L: + if true { + goto L + } else { + } +} + +func _() { +L: + if false { + } else { + goto L + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + if true { + L: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + if true { + L: + } else { + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + if true { + } else { + L: + } +} + +func _() { + if false { + L: + } else { + goto L /* ERROR "goto L jumps into block" */ + } +} + +func _() { + if true { + goto L /* ERROR "goto L jumps into block" */ + } else { + L: + } +} + +func _() { + if true { + goto L /* ERROR "goto L jumps into block" */ + } else if false { + L: + } +} + +func _() { + if true { + goto L /* ERROR "goto L jumps into block" */ + } else if false { + L: + } else { + } +} + +func _() { + if true { + goto L /* ERROR "goto L jumps into block" */ + } else if false { + } else { + L: + } +} + +func _() { + if true { + goto L /* ERROR "goto L jumps into block" */ + } else { + L: + } +} + +func _() { + if true { + L: + } else { + goto L /* ERROR "goto L jumps into block" */ + } +} + +// for + +func _() { + for { + goto L + } +L: +} + +func _() { + for { + goto L + L: + } +} + +func _() { + for { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + for { + goto L + L1: + } +L: + goto L1 /* ERROR "goto L1 jumps into block" */ +} + +func _() { + for i < n { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + for i = 0; i < n; i++ { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + for i = range x { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + for i = range c { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + for i = range m { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +func _() { + for i = range s { + L: + } + goto L /* ERROR "goto L jumps into block" */ +} + +// switch + +func _() { +L: + switch i { + case 0: + goto L + } +} + +func _() { +L: + switch i { + case 0: + + default: + goto L + } +} + +func _() { + switch i { + case 0: + + default: + L: + goto L + } +} + +func _() { + switch i { + case 0: + + default: + goto L + L: + } +} + +func _() { + switch i { + case 0: + goto L + L: + ; + default: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + switch i { + case 0: + L: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + switch i { + case 0: + L: + ; + default: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + switch i { + case 0: + default: + L: + } +} + +func _() { + switch i { + default: + goto L /* ERROR "goto L jumps into block" */ + case 0: + L: + } +} + +func _() { + switch i { + case 0: + L: + ; + default: + goto L /* ERROR "goto L jumps into block" */ + } +} + +// select +// different from switch. the statement has no implicit block around it. + +func _() { +L: + select { + case <-c: + goto L + } +} + +func _() { +L: + select { + case c <- 1: + + default: + goto L + } +} + +func _() { + select { + case <-c: + + default: + L: + goto L + } +} + +func _() { + select { + case c <- 1: + + default: + goto L + L: + } +} + +func _() { + select { + case <-c: + goto L + L: + ; + default: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + select { + case c <- 1: + L: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + select { + case c <- 1: + L: + ; + default: + } +} + +func _() { + goto L /* ERROR "goto L jumps into block" */ + select { + case <-c: + default: + L: + } +} + +func _() { + select { + default: + goto L /* ERROR "goto L jumps into block" */ + case <-c: + L: + } +} + +func _() { + select { + case <-c: + L: + ; + default: + goto L /* ERROR "goto L jumps into block" */ + } +} diff --git a/src/internal/types/testdata/check/importC.go b/src/internal/types/testdata/check/importC.go new file mode 100644 index 0000000..8078021 --- /dev/null +++ b/src/internal/types/testdata/check/importC.go @@ -0,0 +1,56 @@ +// -fakeImportC + +// Copyright 2015 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. + +package importC + +import "C" +import _ /* ERROR cannot rename import "C" */ "C" +import foo /* ERROR cannot rename import "C" */ "C" +import . /* ERROR cannot rename import "C" */ "C" + +// Test cases extracted from issue #22090. + +import "unsafe" + +const _ C.int = 0xff // no error due to invalid constant type + +type T struct { + Name string + Ordinal int +} + +func _(args []T) { + var s string + for i, v := range args { + cname := C.CString(v.Name) + args[i].Ordinal = int(C.sqlite3_bind_parameter_index(s, cname)) // no error due to i not being "used" + C.free(unsafe.Pointer(cname)) + } +} + +type CType C.Type + +const _ CType = C.X // no error due to invalid constant type +const _ = C.X + +// Test cases extracted from issue #23712. + +func _() { + var a [C.ArrayLength]byte + _ = a[0] // no index out of bounds error here +} + +// Additional tests to verify fix for #23712. + +func _() { + var a [C.ArrayLength1]byte + _ = 1 / len(a) // no division by zero error here and below + _ = 1 / cap(a) + _ = uint(unsafe.Sizeof(a)) // must not be negative + + var b [C.ArrayLength2]byte + a = b // should be valid +} diff --git a/src/internal/types/testdata/check/importdecl0/importdecl0a.go b/src/internal/types/testdata/check/importdecl0/importdecl0a.go new file mode 100644 index 0000000..d514ae4 --- /dev/null +++ b/src/internal/types/testdata/check/importdecl0/importdecl0a.go @@ -0,0 +1,53 @@ +// Copyright 2013 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. + +package importdecl0 + +import () + +import ( + // we can have multiple blank imports (was bug) + _ "math" + _ "net/rpc" + init /* ERROR "cannot import package as init" */ "fmt" + // reflect defines a type "flag" which shows up in the gc export data + "reflect" + . /* ERROR "imported and not used" */ "reflect" +) + +import "math" /* ERROR "imported and not used" */ +import m /* ERROR "imported as m and not used" */ "math" +import _ "math" + +import ( + "math/big" /* ERROR "imported and not used" */ + b /* ERROR "imported as b and not used" */ "math/big" + _ "math/big" +) + +import "fmt" +import f1 "fmt" +import f2 "fmt" + +// reflect.flag must not be visible in this package +type flag int +type _ reflect.flag /* ERROR "not exported" */ + +// imported package name may conflict with local objects +type reflect /* ERROR "reflect already declared" */ int + +// dot-imported exported objects may conflict with local objects +type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{} + +var _ = fmt.Println // use "fmt" + +func _() { + f1.Println() // use "fmt" +} + +func _() { + _ = func() { + f2.Println() // use "fmt" + } +} diff --git a/src/internal/types/testdata/check/importdecl0/importdecl0b.go b/src/internal/types/testdata/check/importdecl0/importdecl0b.go new file mode 100644 index 0000000..904faff --- /dev/null +++ b/src/internal/types/testdata/check/importdecl0/importdecl0b.go @@ -0,0 +1,30 @@ +// Copyright 2013 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. + +package importdecl0 + +import "math" +import m "math" + +import . "testing" // declares T in file scope +import . /* ERROR .unsafe. imported and not used */ "unsafe" +import . "fmt" // declares Println in file scope + +import ( + "" /* ERROR invalid import path */ + "a!b" /* ERROR invalid import path */ + "abc\xffdef" /* ERROR invalid import path */ +) + +// using "math" in this file doesn't affect its use in other files +const Pi0 = math.Pi +const Pi1 = m.Pi + +type _ T // use "testing" + +func _() func() interface{} { + return func() interface{} { + return Println // use "fmt" + } +} diff --git a/src/internal/types/testdata/check/importdecl1/importdecl1a.go b/src/internal/types/testdata/check/importdecl1/importdecl1a.go new file mode 100644 index 0000000..d377c01 --- /dev/null +++ b/src/internal/types/testdata/check/importdecl1/importdecl1a.go @@ -0,0 +1,22 @@ +// Copyright 2014 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. + +// Test case for issue 8969. + +package importdecl1 + +import "go/ast" +import . "unsafe" + +var _ Pointer // use dot-imported package unsafe + +// Test cases for issue 23914. + +type A interface { + // Methods m1, m2 must be type-checked in this file scope + // even when embedded in an interface in a different + // file of the same package. + m1() ast.Node + m2() Pointer +} diff --git a/src/internal/types/testdata/check/importdecl1/importdecl1b.go b/src/internal/types/testdata/check/importdecl1/importdecl1b.go new file mode 100644 index 0000000..ce8b983 --- /dev/null +++ b/src/internal/types/testdata/check/importdecl1/importdecl1b.go @@ -0,0 +1,11 @@ +// Copyright 2014 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. + +package importdecl1 + +import . /* ERROR .unsafe. imported and not used */ "unsafe" + +type B interface { + A +} diff --git a/src/internal/types/testdata/check/init0.go b/src/internal/types/testdata/check/init0.go new file mode 100644 index 0000000..5159a17 --- /dev/null +++ b/src/internal/types/testdata/check/init0.go @@ -0,0 +1,106 @@ +// Copyright 2013 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. + +// initialization cycles + +package init0 + +// initialization cycles (we don't know the types) +const ( + s0 /* ERROR initialization cycle: s0 refers to itself */ = s0 + + x0 /* ERROR initialization cycle for x0 */ = y0 + y0 = x0 + + a0 = b0 + b0 /* ERROR initialization cycle for b0 */ = c0 + c0 = d0 + d0 = b0 +) + +var ( + s1 /* ERROR initialization cycle: s1 refers to itself */ = s1 + + x1 /* ERROR initialization cycle for x1 */ = y1 + y1 = x1 + + a1 = b1 + b1 /* ERROR initialization cycle for b1 */ = c1 + c1 = d1 + d1 = b1 +) + +// initialization cycles (we know the types) +const ( + s2 /* ERROR initialization cycle: s2 refers to itself */ int = s2 + + x2 /* ERROR initialization cycle for x2 */ int = y2 + y2 = x2 + + a2 = b2 + b2 /* ERROR initialization cycle for b2 */ int = c2 + c2 = d2 + d2 = b2 +) + +var ( + s3 /* ERROR initialization cycle: s3 refers to itself */ int = s3 + + x3 /* ERROR initialization cycle for x3 */ int = y3 + y3 = x3 + + a3 = b3 + b3 /* ERROR initialization cycle for b3 */ int = c3 + c3 = d3 + d3 = b3 +) + +// cycles via struct fields + +type S1 struct { + f int +} +const cx3 S1 /* ERROR invalid constant type */ = S1{cx3.f} +var vx3 /* ERROR initialization cycle: vx3 refers to itself */ S1 = S1{vx3.f} + +// cycles via functions + +var x4 = x5 +var x5 /* ERROR initialization cycle for x5 */ = f1() +func f1() int { return x5*10 } + +var x6, x7 /* ERROR initialization cycle */ = f2() +var x8 = x7 +func f2() (int, int) { return f3() + f3(), 0 } +func f3() int { return x8 } + +// cycles via function literals + +var x9 /* ERROR initialization cycle: x9 refers to itself */ = func() int { return x9 }() + +var x10 /* ERROR initialization cycle for x10 */ = f4() + +func f4() int { + _ = func() { + _ = x10 + } + return 0 +} + +// cycles via method expressions + +type T1 struct{} + +func (T1) m() bool { _ = x11; return false } + +var x11 /* ERROR initialization cycle for x11 */ = T1.m(T1{}) + +// cycles via method values + +type T2 struct{} + +func (T2) m() bool { _ = x12; return false } + +var t1 T2 +var x12 /* ERROR initialization cycle for x12 */ = t1.m diff --git a/src/internal/types/testdata/check/init1.go b/src/internal/types/testdata/check/init1.go new file mode 100644 index 0000000..39ca314 --- /dev/null +++ b/src/internal/types/testdata/check/init1.go @@ -0,0 +1,97 @@ +// Copyright 2013 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. + +// initialization cycles + +package init1 + +// issue 6683 (marked as WorkingAsIntended) + +type T0 struct{} + +func (T0) m() int { return y0 } + +var x0 = T0{} + +var y0 /* ERROR initialization cycle */ = x0.m() + +type T1 struct{} + +func (T1) m() int { return y1 } + +var x1 interface { + m() int +} = T1{} + +var y1 = x1.m() // no cycle reported, x1 is of interface type + +// issue 6703 (modified) + +var x2 /* ERROR initialization cycle */ = T2.m + +var y2 = x2 + +type T2 struct{} + +func (T2) m() int { + _ = y2 + return 0 +} + +var x3 /* ERROR initialization cycle */ = T3.m(T3{}) // <<<< added (T3{}) + +var y3 = x3 + +type T3 struct{} + +func (T3) m() int { + _ = y3 + return 0 +} + +var x4 /* ERROR initialization cycle */ = T4{}.m // <<<< added {} + +var y4 = x4 + +type T4 struct{} + +func (T4) m() int { + _ = y4 + return 0 +} + +var x5 /* ERROR initialization cycle */ = T5{}.m() // <<<< added () + +var y5 = x5 + +type T5 struct{} + +func (T5) m() int { + _ = y5 + return 0 +} + +// issue 4847 +// simplified test case + +var x6 = f6 +var y6 /* ERROR initialization cycle */ = f6 +func f6() { _ = y6 } + +// full test case + +type ( + E int + S int +) + +type matcher func(s *S) E + +func matchList(s *S) E { return matcher(matchAnyFn)(s) } + +var foo = matcher(matchList) + +var matchAny /* ERROR initialization cycle */ = matcher(matchList) + +func matchAnyFn(s *S) (err E) { return matchAny(s) }
\ No newline at end of file diff --git a/src/internal/types/testdata/check/init2.go b/src/internal/types/testdata/check/init2.go new file mode 100644 index 0000000..614db6c --- /dev/null +++ b/src/internal/types/testdata/check/init2.go @@ -0,0 +1,139 @@ +// Copyright 2014 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. + +// initialization cycles + +package init2 + +// cycles through functions + +func f1() int { _ = x1; return 0 } +var x1 /* ERROR initialization cycle */ = f1 + +func f2() int { _ = x2; return 0 } +var x2 /* ERROR initialization cycle */ = f2() + +// cycles through method expressions + +type T3 int +func (T3) m() int { _ = x3; return 0 } +var x3 /* ERROR initialization cycle */ = T3.m + +type T4 int +func (T4) m() int { _ = x4; return 0 } +var x4 /* ERROR initialization cycle */ = T4.m(0) + +type T3p int +func (*T3p) m() int { _ = x3p; return 0 } +var x3p /* ERROR initialization cycle */ = (*T3p).m + +type T4p int +func (*T4p) m() int { _ = x4p; return 0 } +var x4p /* ERROR initialization cycle */ = (*T4p).m(nil) + +// cycles through method expressions of embedded methods + +type T5 struct { E5 } +type E5 int +func (E5) m() int { _ = x5; return 0 } +var x5 /* ERROR initialization cycle */ = T5.m + +type T6 struct { E6 } +type E6 int +func (E6) m() int { _ = x6; return 0 } +var x6 /* ERROR initialization cycle */ = T6.m(T6{0}) + +type T5p struct { E5p } +type E5p int +func (*E5p) m() int { _ = x5p; return 0 } +var x5p /* ERROR initialization cycle */ = (*T5p).m + +type T6p struct { E6p } +type E6p int +func (*E6p) m() int { _ = x6p; return 0 } +var x6p /* ERROR initialization cycle */ = (*T6p).m(nil) + +// cycles through method values + +type T7 int +func (T7) m() int { _ = x7; return 0 } +var x7 /* ERROR initialization cycle */ = T7(0).m + +type T8 int +func (T8) m() int { _ = x8; return 0 } +var x8 /* ERROR initialization cycle */ = T8(0).m() + +type T7p int +func (*T7p) m() int { _ = x7p; return 0 } +var x7p /* ERROR initialization cycle */ = new(T7p).m + +type T8p int +func (*T8p) m() int { _ = x8p; return 0 } +var x8p /* ERROR initialization cycle */ = new(T8p).m() + +type T7v int +func (T7v) m() int { _ = x7v; return 0 } +var x7var T7v +var x7v /* ERROR initialization cycle */ = x7var.m + +type T8v int +func (T8v) m() int { _ = x8v; return 0 } +var x8var T8v +var x8v /* ERROR initialization cycle */ = x8var.m() + +type T7pv int +func (*T7pv) m() int { _ = x7pv; return 0 } +var x7pvar *T7pv +var x7pv /* ERROR initialization cycle */ = x7pvar.m + +type T8pv int +func (*T8pv) m() int { _ = x8pv; return 0 } +var x8pvar *T8pv +var x8pv /* ERROR initialization cycle */ = x8pvar.m() + +// cycles through method values of embedded methods + +type T9 struct { E9 } +type E9 int +func (E9) m() int { _ = x9; return 0 } +var x9 /* ERROR initialization cycle */ = T9{0}.m + +type T10 struct { E10 } +type E10 int +func (E10) m() int { _ = x10; return 0 } +var x10 /* ERROR initialization cycle */ = T10{0}.m() + +type T9p struct { E9p } +type E9p int +func (*E9p) m() int { _ = x9p; return 0 } +var x9p /* ERROR initialization cycle */ = new(T9p).m + +type T10p struct { E10p } +type E10p int +func (*E10p) m() int { _ = x10p; return 0 } +var x10p /* ERROR initialization cycle */ = new(T10p).m() + +type T9v struct { E9v } +type E9v int +func (E9v) m() int { _ = x9v; return 0 } +var x9var T9v +var x9v /* ERROR initialization cycle */ = x9var.m + +type T10v struct { E10v } +type E10v int +func (E10v) m() int { _ = x10v; return 0 } +var x10var T10v +var x10v /* ERROR initialization cycle */ = x10var.m() + +type T9pv struct { E9pv } +type E9pv int +func (*E9pv) m() int { _ = x9pv; return 0 } +var x9pvar *T9pv +var x9pv /* ERROR initialization cycle */ = x9pvar.m + +type T10pv struct { E10pv } +type E10pv int +func (*E10pv) m() int { _ = x10pv; return 0 } +var x10pvar *T10pv +var x10pv /* ERROR initialization cycle */ = x10pvar.m() diff --git a/src/internal/types/testdata/check/issue25008/issue25008a.go b/src/internal/types/testdata/check/issue25008/issue25008a.go new file mode 100644 index 0000000..cf71ca1 --- /dev/null +++ b/src/internal/types/testdata/check/issue25008/issue25008a.go @@ -0,0 +1,15 @@ +// Copyright 2018 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. + +package p + +import "io" + +type A interface { + io.Reader +} + +func f(a A) { + a.Read(nil) +} diff --git a/src/internal/types/testdata/check/issue25008/issue25008b.go b/src/internal/types/testdata/check/issue25008/issue25008b.go new file mode 100644 index 0000000..f132b7f --- /dev/null +++ b/src/internal/types/testdata/check/issue25008/issue25008b.go @@ -0,0 +1,9 @@ +// Copyright 2018 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. + +package p + +type B interface { + A +} diff --git a/src/internal/types/testdata/check/issues0.go b/src/internal/types/testdata/check/issues0.go new file mode 100644 index 0000000..4a66641 --- /dev/null +++ b/src/internal/types/testdata/check/issues0.go @@ -0,0 +1,373 @@ +// -lang=go1.17 + +// Copyright 2014 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. + +package p // don't permit non-interface elements in interfaces + +import ( + "fmt" + syn "regexp/syntax" + t1 "text/template" + t2 "html/template" +) + +func issue7035() { + type T struct{ X int } + _ = func() { + fmt.Println() // must refer to imported fmt rather than the fmt below + } + fmt := new(T) + _ = fmt.X +} + +func issue8066() { + const ( + _ = float32(340282356779733661637539395458142568447) + _ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ ) + ) +} + +// Check that a missing identifier doesn't lead to a spurious error cascade. +func issue8799a() { + x, ok := missing /* ERROR undefined */ () + _ = !ok + _ = x +} + +func issue8799b(x int, ok bool) { + x, ok = missing /* ERROR undefined */ () + _ = !ok + _ = x +} + +func issue9182() { + type Point C /* ERROR undefined */ .Point + // no error for composite literal based on unknown type + _ = Point{x: 1, y: 2} +} + +func f0() (a []int) { return } +func f1() (a []int, b int) { return } +func f2() (a, b []int) { return } + +func append_([]int, ...int) {} + +func issue9473(a []int, b ...int) { + // variadic builtin function + _ = append(f0()) + _ = append(f0(), f0()...) + _ = append(f1()) + _ = append(f2 /* ERROR cannot use .* in argument */ ()) + _ = append(f2()... /* ERROR cannot use ... */ ) + _ = append(f0(), f1 /* ERROR multiple-value f1 */ ()) + _ = append(f0(), f2 /* ERROR multiple-value f2 */ ()) + _ = append(f0(), f1 /* ERROR multiple-value f1 */ ()...) + _ = append(f0(), f2 /* ERROR multiple-value f2 */ ()...) + + // variadic user-defined function + append_(f0()) + append_(f0(), f0()...) + append_(f1()) + append_(f2 /* ERROR cannot use .* in argument */ ()) + append_(f2()... /* ERROR cannot use ... */ ) + append_(f0(), f1 /* ERROR multiple-value f1 */ ()) + append_(f0(), f2 /* ERROR multiple-value f2 */ ()) + append_(f0(), f1 /* ERROR multiple-value f1 */ ()...) + append_(f0(), f2 /* ERROR multiple-value f2 */ ()...) +} + +// Check that embedding a non-interface type in an interface results in a good error message. +func issue10979() { + type _ interface { + int /* ERROR non-interface type int */ + } + type T struct{} + type _ interface { + T /* ERROR non-interface type T */ + } + type _ interface { + nosuchtype /* ERROR undefined: nosuchtype */ + } + type _ interface { + fmt.Nosuchtype /* ERROR undefined: fmt\.Nosuchtype */ + } + type _ interface { + nosuchpkg /* ERROR undefined: nosuchpkg */ .Nosuchtype + } + type I interface { + I.m /* ERROR I.m is not a type */ + m() + } +} + +// issue11347 +// These should not crash. +var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1 +var a2, b2 /* ERROR cycle */ = 0 /* ERROR assignment mismatch */ /* ERROR assignment mismatch */ > 0<<""[b2] +var a3, b3 /* ERROR cycle */ = int /* ERROR assignment mismatch */ /* ERROR assignment mismatch */ (1<<""[b3]) + +// issue10260 +// Check that error messages explain reason for interface assignment failures. +type ( + I0 interface{} + I1 interface{ foo() } + I2 interface{ foo(x int) } + T0 struct{} + T1 struct{} + T2 struct{} +) + +func (*T1) foo() {} +func (*T2) foo(x int) {} + +func issue10260() { + var ( + i0 I0 + i1 I1 + i2 I2 + t0 *T0 + t1 *T1 + t2 *T2 + ) + + var x I1 + x = T1 /* ERROR cannot use T1{} .* as I1 value in assignment: T1 does not implement I1 \(method foo has pointer receiver\) */ {} + _ = x /* ERROR impossible type assertion: x\.\(T1\)\n\tT1 does not implement I1 \(method foo has pointer receiver\) */ .(T1) + + T1{}.foo /* ERROR cannot call pointer method foo on T1 */ () + x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ () + + _ = i2 /* ERROR impossible type assertion: i2\.\(\*T1\)\n\t\*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ .(*T1) + + i1 = i0 /* ERROR cannot use i0 .* as I1 value in assignment: I0 does not implement I1 \(missing method foo\) */ + i1 = t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ + i1 = i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ + i1 = t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ + i2 = i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ + i2 = t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ + + _ = func() I1 { return i0 /* ERROR cannot use i0 .* as I1 value in return statement: I0 does not implement I1 \(missing method foo\) */ } + _ = func() I1 { return t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ } + _ = func() I1 { return i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ } + _ = func() I1 { return t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ } + _ = func() I2 { return i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ } + _ = func() I2 { return t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ } + + // a few more - less exhaustive now + + f := func(I1, I2){} + f(i0 /* ERROR missing method foo */ , i1 /* ERROR wrong type for method foo */ ) + + _ = [...]I1{i0 /* ERROR cannot use i0 .* as I1 value in array or slice literal: I0 does not implement I1 \(missing method foo\) */ } + _ = [...]I1{i2 /* ERROR cannot use i2 .* as I1 value in array or slice literal: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ } + _ = []I1{i0 /* ERROR missing method foo */ } + _ = []I1{i2 /* ERROR wrong type for method foo */ } + _ = map[int]I1{0: i0 /* ERROR missing method foo */ } + _ = map[int]I1{0: i2 /* ERROR wrong type for method foo */ } + + make(chan I1) <- i0 /* ERROR missing method foo */ + make(chan I1) <- i2 /* ERROR wrong type for method foo */ +} + +// Check that constants representable as integers are in integer form +// before being used in operations that are only defined on integers. +func issue14229() { + // from the issue + const _ = int64(-1<<63) % 1e6 + + // related + const ( + a int = 3 + b = 4.0 + _ = a / b + _ = a % b + _ = b / a + _ = b % a + ) +} + +// Check that in a n:1 variable declaration with type and initialization +// expression the type is distributed to all variables of the lhs before +// the initialization expression assignment is checked. +func issue15755() { + // from issue + var i interface{} + type b bool + var x, y b = i.(b) + _ = x == y + + // related: we should see an error since the result of f1 is ([]int, int) + var u, v []int = f1 /* ERROR cannot use f1 */ () + _ = u + _ = v +} + +// Test that we don't get "declared and not used" +// errors in the context of invalid/C objects. +func issue20358() { + var F C /* ERROR "undefined" */ .F + var A C /* ERROR "undefined" */ .A + var S C /* ERROR "undefined" */ .S + type T C /* ERROR "undefined" */ .T + type P C /* ERROR "undefined" */ .P + + // these variables must be "used" even though + // the LHS expressions/types below in which + // context they are used are unknown/invalid + var f, a, s1, s2, s3, t, p int + + _ = F(f) + _ = A[a] + _ = S[s1:s2:s3] + _ = T{t} + _ = P{f: p} +} + +// Test that we don't declare lhs variables in short variable +// declarations before we type-check function literals on the +// rhs. +func issue24026() { + f := func() int { f(0) /* must refer to outer f */; return 0 } + _ = f + + _ = func() { + f := func() { _ = f() /* must refer to outer f */ } + _ = f + } + + // b and c must not be visible inside function literal + a := 0 + a, b, c := func() (int, int, int) { + return a, b /* ERROR undefined */ , c /* ERROR undefined */ + }() + _, _ = b, c +} + +func f(int) {} // for issue24026 + +// Test that we don't report a "missing return statement" error +// (due to incorrect context when type-checking interfaces). +func issue24140(x interface{}) int { + switch x.(type) { + case interface{}: + return 0 + default: + panic(0) + } +} + +// Test that we don't crash when the 'if' condition is missing. +func issue25438() { + if { /* ERROR missing condition */ } + if x := 0; /* ERROR missing condition */ { _ = x } + if + { /* ERROR missing condition */ } +} + +// Test that we can embed alias type names in interfaces. +type issue25301 interface { + E +} + +type E = interface { + m() +} + +// Test case from issue. +// cmd/compile reports a cycle as well. +type issue25301b /* ERROR invalid recursive type */ = interface { + m() interface{ issue25301b } +} + +type issue25301c interface { + notE // ERROR non-interface type struct\{\} +} + +type notE = struct{} + +// Test that method declarations don't introduce artificial cycles +// (issue #26124). +const CC TT = 1 +type TT int +func (TT) MM() [CC]TT + +// Reduced test case from issue #26124. +const preloadLimit LNumber = 128 +type LNumber float64 +func (LNumber) assertFunction() *LFunction +type LFunction struct { + GFunction LGFunction +} +type LGFunction func(*LState) +type LState struct { + reg *registry +} +type registry struct { + alloc *allocator +} +type allocator struct { + _ [int(preloadLimit)]int +} + +// Test that we don't crash when type-checking composite literals +// containing errors in the type. +var issue27346 = [][n /* ERROR undefined */ ]int{ + 0: {}, +} + +var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}} + +// Test that invalid use of ... in parameter lists is recognized +// (issue #28281). +func issue28281a(int, int, ...int) +func issue28281b(a, b int, c ...int) +func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int) +func issue28281d(... /* ERROR can only use ... with final parameter */ int, int) +func issue28281e(a, b, c ... /* ERROR can only use ... with final parameter */ int, d int) +func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int) +func (... /* ERROR can only use ... with final parameter */ TT) f() +func issue28281g() (... /* ERROR can only use ... with final parameter */ TT) + +// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output +func issue26234a(f *syn.Prog) { + // The error message below should refer to the actual package name (syntax) + // not the local package name (syn). + f.foo /* ERROR f\.foo undefined \(type \*syntax\.Prog has no field or method foo\) */ +} + +type T struct { + x int + E1 + E2 +} + +type E1 struct{ f int } +type E2 struct{ f int } + +func issue26234b(x T) { + _ = x.f /* ERROR ambiguous selector x.f */ +} + +func issue26234c() { + T.x /* ERROR T.x undefined \(type T has no method x\) */ () +} + +func issue35895() { + // T is defined in this package, don't qualify its name with the package name. + var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T + + // There is only one package with name syntax imported, only use the (global) package name in error messages. + var _ *syn.Prog = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.Prog + + // Because both t1 and t2 have the same global package name (template), + // qualify packages with full path name in this case. + var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{} +} + +func issue42989(s uint) { + var m map[int]string + delete(m, 1<<s) + delete(m, 1.<<s) +} diff --git a/src/internal/types/testdata/check/issues1.go b/src/internal/types/testdata/check/issues1.go new file mode 100644 index 0000000..2f3414d --- /dev/null +++ b/src/internal/types/testdata/check/issues1.go @@ -0,0 +1,252 @@ +// -oldComparableSemantics + +// 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 contains regression tests for bugs found. + +package p + +import "io" +import "context" + +func eql[T comparable](x, y T) bool { + return x == y +} + +func _[X comparable, Y interface{comparable; m()}]() { + var x X + var y Y + eql(x, y /* ERROR does not match */ ) // interfaces of different types + eql(x, x) + eql(y, y) + eql(y, nil /* ERROR cannot use nil as Y value in argument to eql */ ) + eql[io /* ERROR does not satisfy comparable */ .Reader](nil, nil) +} + +// If we have a receiver of pointer to type parameter type (below: *T) +// we don't have any methods, like for interfaces. +type C[T any] interface { + m() +} + +// using type bound C +func _[T C[T]](x *T) { + x.m /* ERROR x\.m undefined */ () +} + +// using an interface literal as bound +func _[T interface{ m() }](x *T) { + x.m /* ERROR x\.m undefined */ () +} + +func f2[_ interface{ m1(); m2() }]() {} + +type T struct{} +func (T) m1() +func (*T) m2() + +func _() { + f2[T /* ERROR m2 has pointer receiver */ ]() + f2[*T]() +} + +// When a type parameter is used as an argument to instantiate a parameterized +// type, the type argument's type set must be a subset of the instantiated type +// parameter's type set. +type T1[P interface{~uint}] struct{} + +func _[P any]() { + _ = T1[P /* ERROR P does not satisfy interface{~uint} */ ]{} +} + +// This is the original (simplified) program causing the same issue. +type Unsigned interface { + ~uint +} + +type T2[U Unsigned] struct { + s U +} + +func (u T2[U]) Add1() U { + return u.s + 1 +} + +func NewT2[U any]() T2[U /* ERROR U does not satisfy Unsigned */ ] { + return T2[U /* ERROR U does not satisfy Unsigned */ ]{} +} + +func _() { + u := NewT2[string]() + _ = u.Add1() +} + +// When we encounter an instantiated type such as Elem[T] we must +// not "expand" the instantiation when the type to be instantiated +// (Elem in this case) is not yet fully set up. +type Elem[T any] struct { + next *Elem[T] + list *List[T] +} + +type List[T any] struct { + root Elem[T] +} + +func (l *List[T]) Init() { + l.root.next = &l.root +} + +// This is the original program causing the same issue. +type Element2[TElem any] struct { + next, prev *Element2[TElem] + list *List2[TElem] + Value TElem +} + +type List2[TElem any] struct { + root Element2[TElem] + len int +} + +func (l *List2[TElem]) Init() *List2[TElem] { + l.root.next = &l.root + l.root.prev = &l.root + l.len = 0 + return l +} + +// Self-recursive instantiations must work correctly. +type A[P any] struct { _ *A[P] } + +type AB[P any] struct { _ *BA[P] } +type BA[P any] struct { _ *AB[P] } + +// And a variation that also caused a problem with an +// unresolved underlying type. +type Element3[TElem any] struct { + next, prev *Element3[TElem] + list *List3[TElem] + Value TElem +} + +func (e *Element3[TElem]) Next() *Element3[TElem] { + if p := e.next; e.list != nil && p != &e.list.root { + return p + } + return nil +} + +type List3[TElem any] struct { + root Element3[TElem] + len int +} + +// Infinite generic type declarations must lead to an error. +type inf1[T any] struct{ _ inf1 /* ERROR invalid recursive type */ [T] } +type inf2[T any] struct{ inf2 /* ERROR invalid recursive type */ [T] } + +// The implementation of conversions T(x) between integers and floating-point +// numbers checks that both T and x have either integer or floating-point +// type. When the type of T or x is a type parameter, the respective simple +// predicate disjunction in the implementation was wrong because if a type set +// contains both an integer and a floating-point type, the type parameter is +// neither an integer or a floating-point number. +func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 { + return T2(v) +} + +func _() { + convert[int, uint](5) +} + +// When testing binary operators, for +, the operand types must either be +// both numeric, or both strings. The implementation had the same problem +// with this check as the conversion issue above (issue #39623). + +func issue39623[T interface{~int | ~string}](x, y T) T { + return x + y +} + +// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI: +func Sum[T interface{~int | ~string}](s []T) (sum T) { + for _, v := range s { + sum += v + } + return +} + +// Assignability of an unnamed pointer type to a type parameter that +// has a matching underlying type. +func _[T interface{}, PT interface{~*T}] (x T) PT { + return &x +} + +// Indexing of type parameters containing type parameters in their constraint terms: +func at[T interface{ ~[]E }, E interface{}](x T, i int) E { + return x[i] +} + +// Conversion of a local type to a type parameter. +func _[T interface{~int}](x T) { + type myint int + var _ int = int(x) + var _ T = 42 + var _ T = T(myint(42)) +} + +// Indexing a type parameter with an array type bound checks length. +// (Example by mdempsky@.) +func _[T interface { ~[10]int }](x T) { + _ = x[9] // ok + _ = x[20 /* ERROR out of bounds */ ] +} + +// Pointer indirection of a type parameter. +func _[T interface{ ~*int }](p T) int { + return *p +} + +// Channel sends and receives on type parameters. +func _[T interface{ ~chan int }](ch T) int { + ch <- 0 + return <- ch +} + +// Calling of a generic variable. +func _[T interface{ ~func() }](f T) { + f() + go f() +} + +type F1 func() +type F2 func() +func _[T interface{ func()|F1|F2 }](f T) { + f() + go f() +} + +// We must compare against the (possibly underlying) types of term list +// elements when checking if a constraint is satisfied by a type. +// The underlying type of each term must be computed after the +// interface has been instantiated as its constraint may contain +// a type parameter that was substituted with a defined type. +// Test case from an (originally) failing example. + +type sliceOf[E any] interface{ ~[]E } + +func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) } + +var f func() +var cancelSlice []context.CancelFunc +var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f) + +// A generic function must be instantiated with a type, not a value. + +func g[T any](T) T { panic(0) } + +var _ = g[int] +var _ = g[nil /* ERROR is not a type */ ] +var _ = g(0) diff --git a/src/internal/types/testdata/check/labels.go b/src/internal/types/testdata/check/labels.go new file mode 100644 index 0000000..5948952 --- /dev/null +++ b/src/internal/types/testdata/check/labels.go @@ -0,0 +1,207 @@ +// Copyright 2011 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 is a modified concatenation of the files +// $GOROOT/test/label.go and $GOROOT/test/label1.go. + +package labels + +var x int + +func f0() { +L1 /* ERROR "label L1 declared and not used" */ : + for { + } +L2 /* ERROR "label L2 declared and not used" */ : + select { + } +L3 /* ERROR "label L3 declared and not used" */ : + switch { + } +L4 /* ERROR "label L4 declared and not used" */ : + if true { + } +L5 /* ERROR "label L5 declared and not used" */ : + f0() +L6: + f0() +L6 /* ERROR "label L6 already declared" */ : + f0() + if x == 20 { + goto L6 + } + +L7: + for { + break L7 + break L8 /* ERROR "invalid break label L8" */ + } + +// A label must be directly associated with a switch, select, or +// for statement; it cannot be the label of a labeled statement. + +L7a /* ERROR "declared and not used" */ : L7b: + for { + break L7a /* ERROR "invalid break label L7a" */ + continue L7a /* ERROR "invalid continue label L7a" */ + continue L7b + } + +L8: + for { + if x == 21 { + continue L8 + continue L7 /* ERROR "invalid continue label L7" */ + } + } + +L9: + switch { + case true: + break L9 + defalt /* ERROR "label defalt declared and not used" */ : + } + +L10: + select { + default: + break L10 + break L9 /* ERROR "invalid break label L9" */ + } + + goto L10a +L10a: L10b: + select { + default: + break L10a /* ERROR "invalid break label L10a" */ + break L10b + continue L10b /* ERROR "invalid continue label L10b" */ + } +} + +func f1() { +L1: + for { + if x == 0 { + break L1 + } + if x == 1 { + continue L1 + } + goto L1 + } + +L2: + select { + default: + if x == 0 { + break L2 + } + if x == 1 { + continue L2 /* ERROR "invalid continue label L2" */ + } + goto L2 + } + +L3: + switch { + case x > 10: + if x == 11 { + break L3 + } + if x == 12 { + continue L3 /* ERROR "invalid continue label L3" */ + } + goto L3 + } + +L4: + if true { + if x == 13 { + break L4 /* ERROR "invalid break label L4" */ + } + if x == 14 { + continue L4 /* ERROR "invalid continue label L4" */ + } + if x == 15 { + goto L4 + } + } + +L5: + f1() + if x == 16 { + break L5 /* ERROR "invalid break label L5" */ + } + if x == 17 { + continue L5 /* ERROR "invalid continue label L5" */ + } + if x == 18 { + goto L5 + } + + for { + if x == 19 { + break L1 /* ERROR "invalid break label L1" */ + } + if x == 20 { + continue L1 /* ERROR "invalid continue label L1" */ + } + if x == 21 { + goto L1 + } + } +} + +// Additional tests not in the original files. + +func f2() { +L1 /* ERROR "label L1 declared and not used" */ : + if x == 0 { + for { + continue L1 /* ERROR "invalid continue label L1" */ + } + } +} + +func f3() { +L1: +L2: +L3: + for { + break L1 /* ERROR "invalid break label L1" */ + break L2 /* ERROR "invalid break label L2" */ + break L3 + continue L1 /* ERROR "invalid continue label L1" */ + continue L2 /* ERROR "invalid continue label L2" */ + continue L3 + goto L1 + goto L2 + goto L3 + } +} + +// Blank labels are never declared. + +func f4() { +_: +_: // multiple blank labels are ok + goto _ /* ERROR "label _ not declared" */ +} + +func f5() { +_: + for { + break _ /* ERROR "invalid break label _" */ + continue _ /* ERROR "invalid continue label _" */ + } +} + +func f6() { +_: + switch { + default: + break _ /* ERROR "invalid break label _" */ + } +} diff --git a/src/internal/types/testdata/check/linalg.go b/src/internal/types/testdata/check/linalg.go new file mode 100644 index 0000000..f02e773 --- /dev/null +++ b/src/internal/types/testdata/check/linalg.go @@ -0,0 +1,82 @@ +// Copyright 2019 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. + +package linalg + +// Numeric is type bound that matches any numeric type. +// It would likely be in a constraints package in the standard library. +type Numeric interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | + ~float32 | ~float64 | + ~complex64 | ~complex128 +} + +func DotProduct[T Numeric](s1, s2 []T) T { + if len(s1) != len(s2) { + panic("DotProduct: slices of unequal length") + } + var r T + for i := range s1 { + r += s1[i] * s2[i] + } + return r +} + +// NumericAbs matches numeric types with an Abs method. +type NumericAbs[T any] interface { + Numeric + + Abs() T +} + +// AbsDifference computes the absolute value of the difference of +// a and b, where the absolute value is determined by the Abs method. +func AbsDifference[T NumericAbs[T]](a, b T) T { + d := a - b + return d.Abs() +} + +// OrderedNumeric is a type bound that matches numeric types that support the < operator. +type OrderedNumeric interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | + ~float32 | ~float64 +} + +// Complex is a type bound that matches the two complex types, which do not have a < operator. +type Complex interface { + ~complex64 | ~complex128 +} + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// // OrderedAbs is a helper type that defines an Abs method for +// // ordered numeric types. +// type OrderedAbs[T OrderedNumeric] T +// +// func (a OrderedAbs[T]) Abs() OrderedAbs[T] { +// if a < 0 { +// return -a +// } +// return a +// } +// +// // ComplexAbs is a helper type that defines an Abs method for +// // complex types. +// type ComplexAbs[T Complex] T +// +// func (a ComplexAbs[T]) Abs() ComplexAbs[T] { +// r := float64(real(a)) +// i := float64(imag(a)) +// d := math.Sqrt(r * r + i * i) +// return ComplexAbs[T](complex(d, 0)) +// } +// +// func OrderedAbsDifference[T OrderedNumeric](a, b T) T { +// return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b))) +// } +// +// func ComplexAbsDifference[T Complex](a, b T) T { +// return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b))) +// } diff --git a/src/internal/types/testdata/check/literals.go b/src/internal/types/testdata/check/literals.go new file mode 100644 index 0000000..494a465 --- /dev/null +++ b/src/internal/types/testdata/check/literals.go @@ -0,0 +1,111 @@ +// Copyright 2019 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 tests various representations of literals +// and compares them with literals or constant expressions +// of equal values. + +package literals + +func _() { + // 0-octals + assert(0_123 == 0123) + assert(0123_456 == 0123456) + + // decimals + assert(1_234 == 1234) + assert(1_234_567 == 1234567) + + // hexadecimals + assert(0X_0 == 0) + assert(0X_1234 == 0x1234) + assert(0X_CAFE_f00d == 0xcafef00d) + + // octals + assert(0o0 == 0) + assert(0o1234 == 01234) + assert(0o01234567 == 01234567) + + assert(0O0 == 0) + assert(0O1234 == 01234) + assert(0O01234567 == 01234567) + + assert(0o_0 == 0) + assert(0o_1234 == 01234) + assert(0o0123_4567 == 01234567) + + assert(0O_0 == 0) + assert(0O_1234 == 01234) + assert(0O0123_4567 == 01234567) + + // binaries + assert(0b0 == 0) + assert(0b1011 == 0xb) + assert(0b00101101 == 0x2d) + + assert(0B0 == 0) + assert(0B1011 == 0xb) + assert(0B00101101 == 0x2d) + + assert(0b_0 == 0) + assert(0b10_11 == 0xb) + assert(0b_0010_1101 == 0x2d) + + // decimal floats + assert(1_2_3. == 123.) + assert(0_123. == 123.) + + assert(0_0e0 == 0.) + assert(1_2_3e0 == 123.) + assert(0_123e0 == 123.) + + assert(0e-0_0 == 0.) + assert(1_2_3E+0 == 123.) + assert(0123E1_2_3 == 123e123) + + assert(0.e+1 == 0.) + assert(123.E-1_0 == 123e-10) + assert(01_23.e123 == 123e123) + + assert(.0e-1 == .0) + assert(.123E+10 == .123e10) + assert(.0123E123 == .0123e123) + + assert(1_2_3.123 == 123.123) + assert(0123.01_23 == 123.0123) + + // hexadecimal floats + assert(0x0.p+0 == 0.) + assert(0Xdeadcafe.p-10 == 0xdeadcafe/1024.0) + assert(0x1234.P84 == 0x1234000000000000000000000) + + assert(0x.1p-0 == 1./16) + assert(0X.deadcafep4 == 1.0*0xdeadcafe/0x10000000) + assert(0x.1234P+12 == 1.0*0x1234/0x10) + + assert(0x0p0 == 0.) + assert(0Xdeadcafep+1 == 0x1bd5b95fc) + assert(0x1234P-10 == 0x1234/1024.0) + + assert(0x0.0p0 == 0.) + assert(0Xdead.cafep+1 == 1.0*0x1bd5b95fc/0x10000) + assert(0x12.34P-10 == 1.0*0x1234/0x40000) + + assert(0Xdead_cafep+1 == 0xdeadcafep+1) + assert(0x_1234P-10 == 0x1234p-10) + + assert(0X_dead_cafe.p-10 == 0xdeadcafe.p-10) + assert(0x12_34.P1_2_3 == 0x1234.p123) + + assert(1_234i == 1234i) + assert(1_234_567i == 1234567i) + + assert(0.i == 0i) + assert(123.i == 123i) + assert(0123.i == 123i) + + assert(0.e+1i == 0i) + assert(123.E-1_0i == 123e-10i) + assert(01_23.e123i == 123e123i) +} diff --git a/src/internal/types/testdata/check/main0.go b/src/internal/types/testdata/check/main0.go new file mode 100644 index 0000000..132a5fe --- /dev/null +++ b/src/internal/types/testdata/check/main0.go @@ -0,0 +1,9 @@ +// 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. + +package main + +func main() +func main /* ERROR "no arguments and no return values" */ /* ERROR redeclared */ (int) +func main /* ERROR "no arguments and no return values" */ /* ERROR redeclared */ () int diff --git a/src/internal/types/testdata/check/main1.go b/src/internal/types/testdata/check/main1.go new file mode 100644 index 0000000..fb567a0 --- /dev/null +++ b/src/internal/types/testdata/check/main1.go @@ -0,0 +1,7 @@ +// Copyright 2021 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. + +package main + +func main[T /* ERROR "func main must have no type parameters" */ any]() {} diff --git a/src/internal/types/testdata/check/map0.go b/src/internal/types/testdata/check/map0.go new file mode 100644 index 0000000..814d953 --- /dev/null +++ b/src/internal/types/testdata/check/map0.go @@ -0,0 +1,113 @@ +// Copyright 2019 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. + +// Package orderedmap provides an ordered map, implemented as a binary tree. +package orderedmap + +// TODO(gri) fix imports for tests +import "chans" // ERROR could not import + +// Map is an ordered map. +type Map[K, V any] struct { + root *node[K, V] + compare func(K, K) int +} + +// node is the type of a node in the binary tree. +type node[K, V any] struct { + key K + val V + left, right *node[K, V] +} + +// New returns a new map. +func New[K, V any](compare func(K, K) int) *Map[K, V] { + return &Map[K, V]{compare: compare} +} + +// find looks up key in the map, and returns either a pointer +// to the node holding key, or a pointer to the location where +// such a node would go. +func (m *Map[K, V]) find(key K) **node[K, V] { + pn := &m.root + for *pn != nil { + switch cmp := m.compare(key, (*pn).key); { + case cmp < 0: + pn = &(*pn).left + case cmp > 0: + pn = &(*pn).right + default: + return pn + } + } + return pn +} + +// Insert inserts a new key/value into the map. +// If the key is already present, the value is replaced. +// Returns true if this is a new key, false if already present. +func (m *Map[K, V]) Insert(key K, val V) bool { + pn := m.find(key) + if *pn != nil { + (*pn).val = val + return false + } + *pn = &node[K, V]{key: key, val: val} + return true +} + +// Find returns the value associated with a key, or zero if not present. +// The found result reports whether the key was found. +func (m *Map[K, V]) Find(key K) (V, bool) { + pn := m.find(key) + if *pn == nil { + var zero V // see the discussion of zero values, above + return zero, false + } + return (*pn).val, true +} + +// keyValue is a pair of key and value used when iterating. +type keyValue[K, V any] struct { + key K + val V +} + +// InOrder returns an iterator that does an in-order traversal of the map. +func (m *Map[K, V]) InOrder() *Iterator[K, V] { + sender, receiver := chans.Ranger[keyValue[K, V]]() + var f func(*node[K, V]) bool + f = func(n *node[K, V]) bool { + if n == nil { + return true + } + // Stop sending values if sender.Send returns false, + // meaning that nothing is listening at the receiver end. + return f(n.left) && + sender.Send(keyValue[K, V]{n.key, n.val}) && + f(n.right) + } + go func() { + f(m.root) + sender.Close() + }() + return &Iterator[K, V]{receiver} +} + +// Iterator is used to iterate over the map. +type Iterator[K, V any] struct { + r *chans.Receiver[keyValue[K, V]] +} + +// Next returns the next key and value pair, and a boolean indicating +// whether they are valid or whether we have reached the end. +func (it *Iterator[K, V]) Next() (K, V, bool) { + keyval, ok := it.r.Next() + if !ok { + var zerok K + var zerov V + return zerok, zerov, false + } + return keyval.key, keyval.val, true +} diff --git a/src/internal/types/testdata/check/map1.go b/src/internal/types/testdata/check/map1.go new file mode 100644 index 0000000..e13bf33 --- /dev/null +++ b/src/internal/types/testdata/check/map1.go @@ -0,0 +1,146 @@ +// Copyright 2019 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 is like map.go2, but instead if importing chans, it contains +// the necessary functionality at the end of the file. + +// Package orderedmap provides an ordered map, implemented as a binary tree. +package orderedmap + +// Map is an ordered map. +type Map[K, V any] struct { + root *node[K, V] + compare func(K, K) int +} + +// node is the type of a node in the binary tree. +type node[K, V any] struct { + key K + val V + left, right *node[K, V] +} + +// New returns a new map. +func New[K, V any](compare func(K, K) int) *Map[K, V] { + return &Map[K, V]{compare: compare} +} + +// find looks up key in the map, and returns either a pointer +// to the node holding key, or a pointer to the location where +// such a node would go. +func (m *Map[K, V]) find(key K) **node[K, V] { + pn := &m.root + for *pn != nil { + switch cmp := m.compare(key, (*pn).key); { + case cmp < 0: + pn = &(*pn).left + case cmp > 0: + pn = &(*pn).right + default: + return pn + } + } + return pn +} + +// Insert inserts a new key/value into the map. +// If the key is already present, the value is replaced. +// Returns true if this is a new key, false if already present. +func (m *Map[K, V]) Insert(key K, val V) bool { + pn := m.find(key) + if *pn != nil { + (*pn).val = val + return false + } + *pn = &node[K, V]{key: key, val: val} + return true +} + +// Find returns the value associated with a key, or zero if not present. +// The found result reports whether the key was found. +func (m *Map[K, V]) Find(key K) (V, bool) { + pn := m.find(key) + if *pn == nil { + var zero V // see the discussion of zero values, above + return zero, false + } + return (*pn).val, true +} + +// keyValue is a pair of key and value used when iterating. +type keyValue[K, V any] struct { + key K + val V +} + +// InOrder returns an iterator that does an in-order traversal of the map. +func (m *Map[K, V]) InOrder() *Iterator[K, V] { + sender, receiver := chans_Ranger[keyValue[K, V]]() + var f func(*node[K, V]) bool + f = func(n *node[K, V]) bool { + if n == nil { + return true + } + // Stop sending values if sender.Send returns false, + // meaning that nothing is listening at the receiver end. + return f(n.left) && + sender.Send(keyValue[K, V]{n.key, n.val}) && + f(n.right) + } + go func() { + f(m.root) + sender.Close() + }() + return &Iterator[K, V]{receiver} +} + +// Iterator is used to iterate over the map. +type Iterator[K, V any] struct { + r *chans_Receiver[keyValue[K, V]] +} + +// Next returns the next key and value pair, and a boolean indicating +// whether they are valid or whether we have reached the end. +func (it *Iterator[K, V]) Next() (K, V, bool) { + keyval, ok := it.r.Next() + if !ok { + var zerok K + var zerov V + return zerok, zerov, false + } + return keyval.key, keyval.val, true +} + +// chans + +func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T]) { panic(0) } + +// A sender is used to send values to a Receiver. +type chans_Sender[T any] struct { + values chan<- T + done <-chan bool +} + +func (s *chans_Sender[T]) Send(v T) bool { + select { + case s.values <- v: + return true + case <-s.done: + return false + } +} + +func (s *chans_Sender[T]) Close() { + close(s.values) +} + +type chans_Receiver[T any] struct { + values <-chan T + done chan<- bool +} + +func (r *chans_Receiver[T]) Next() (T, bool) { + v, ok := <-r.values + return v, ok +} diff --git a/src/internal/types/testdata/check/methodsets.go b/src/internal/types/testdata/check/methodsets.go new file mode 100644 index 0000000..d145bc0 --- /dev/null +++ b/src/internal/types/testdata/check/methodsets.go @@ -0,0 +1,214 @@ +// Copyright 2013 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. + +package methodsets + +type T0 struct {} + +func (T0) v0() {} +func (*T0) p0() {} + +type T1 struct {} // like T0 with different method names + +func (T1) v1() {} +func (*T1) p1() {} + +type T2 interface { + v2() + p2() +} + +type T3 struct { + T0 + *T1 + T2 +} + +// Method expressions +func _() { + var ( + _ func(T0) = T0.v0 + _ = T0.p0 /* ERROR invalid method expression T0\.p0 \(needs pointer receiver \(\*T0\)\.p0\) */ + + _ func (*T0) = (*T0).v0 + _ func (*T0) = (*T0).p0 + + // T1 is like T0 + + _ func(T2) = T2.v2 + _ func(T2) = T2.p2 + + _ func(T3) = T3.v0 + _ func(T3) = T3.p0 /* ERROR invalid method expression T3\.p0 \(needs pointer receiver \(\*T3\)\.p0\) */ + _ func(T3) = T3.v1 + _ func(T3) = T3.p1 + _ func(T3) = T3.v2 + _ func(T3) = T3.p2 + + _ func(*T3) = (*T3).v0 + _ func(*T3) = (*T3).p0 + _ func(*T3) = (*T3).v1 + _ func(*T3) = (*T3).p1 + _ func(*T3) = (*T3).v2 + _ func(*T3) = (*T3).p2 + ) +} + +// Method values with addressable receivers +func _() { + var ( + v0 T0 + _ func() = v0.v0 + _ func() = v0.p0 + ) + + var ( + p0 *T0 + _ func() = p0.v0 + _ func() = p0.p0 + ) + + // T1 is like T0 + + var ( + v2 T2 + _ func() = v2.v2 + _ func() = v2.p2 + ) + + var ( + v4 T3 + _ func() = v4.v0 + _ func() = v4.p0 + _ func() = v4.v1 + _ func() = v4.p1 + _ func() = v4.v2 + _ func() = v4.p2 + ) + + var ( + p4 *T3 + _ func() = p4.v0 + _ func() = p4.p0 + _ func() = p4.v1 + _ func() = p4.p1 + _ func() = p4.v2 + _ func() = p4.p2 + ) +} + +// Method calls with addressable receivers +func _() { + var v0 T0 + v0.v0() + v0.p0() + + var p0 *T0 + p0.v0() + p0.p0() + + // T1 is like T0 + + var v2 T2 + v2.v2() + v2.p2() + + var v4 T3 + v4.v0() + v4.p0() + v4.v1() + v4.p1() + v4.v2() + v4.p2() + + var p4 *T3 + p4.v0() + p4.p0() + p4.v1() + p4.p1() + p4.v2() + p4.p2() +} + +// Method values with value receivers +func _() { + var ( + _ func() = T0{}.v0 + _ func() = T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ + + _ func() = (&T0{}).v0 + _ func() = (&T0{}).p0 + + // T1 is like T0 + + // no values for T2 + + _ func() = T3{}.v0 + _ func() = T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ + _ func() = T3{}.v1 + _ func() = T3{}.p1 + _ func() = T3{}.v2 + _ func() = T3{}.p2 + + _ func() = (&T3{}).v0 + _ func() = (&T3{}).p0 + _ func() = (&T3{}).v1 + _ func() = (&T3{}).p1 + _ func() = (&T3{}).v2 + _ func() = (&T3{}).p2 + ) +} + +// Method calls with value receivers +func _() { + T0{}.v0() + T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ () + + (&T0{}).v0() + (&T0{}).p0() + + // T1 is like T0 + + // no values for T2 + + T3{}.v0() + T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ () + T3{}.v1() + T3{}.p1() + T3{}.v2() + T3{}.p2() + + (&T3{}).v0() + (&T3{}).p0() + (&T3{}).v1() + (&T3{}).p1() + (&T3{}).v2() + (&T3{}).p2() +} + +// *T has no methods if T is an interface type +func issue5918() { + var ( + err error + _ = err.Error() + _ func() string = err.Error + _ func(error) string = error.Error + + perr = &err + _ = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */ () + _ func() string = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */ + _ func(*error) string = (*error).Error /* ERROR "type \*error is pointer to interface, not interface" */ + ) + + type T *interface{ m() int } + var ( + x T + _ = (*x).m() + _ = (*x).m + + _ = x.m /* ERROR "type T is pointer to interface, not interface" */ () + _ = x.m /* ERROR "type T is pointer to interface, not interface" */ + _ = T.m /* ERROR "type T is pointer to interface, not interface" */ + ) +} diff --git a/src/internal/types/testdata/check/shifts.go b/src/internal/types/testdata/check/shifts.go new file mode 100644 index 0000000..5cd0182 --- /dev/null +++ b/src/internal/types/testdata/check/shifts.go @@ -0,0 +1,399 @@ +// Copyright 2013 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. + +package shifts + +func shifts0() { + // basic constant shifts + const ( + s = 10 + _ = 0<<0 + _ = 1<<s + _ = 1<<- /* ERROR "negative shift count" */ 1 + // For the test below we may decide to convert to int + // rather than uint and then report a negative shift + // count instead, which might be a better error. The + // (minor) difference is that this would restrict the + // shift count range by half (from all uint values to + // the positive int values). + // This depends on the exact spec wording which is not + // done yet. + // TODO(gri) revisit and adjust when spec change is done + _ = 1<<- /* ERROR "negative shift count" */ 1.0 + _ = 1<<1075 /* ERROR "invalid shift" */ + _ = 2.0<<1 + _ = 1<<1.0 + _ = 1<<(1+0i) + + _ int = 2<<s + _ float32 = 2<<s + _ complex64 = 2<<s + + _ int = 2.0<<s + _ float32 = 2.0<<s + _ complex64 = 2.0<<s + + _ int = 'a'<<s + _ float32 = 'a'<<s + _ complex64 = 'a'<<s + ) +} + +func shifts1() { + // basic non-constant shifts + var ( + i int + u uint + + _ = 1<<0 + _ = 1<<i + _ = 1<<u + _ = 1<<"foo" /* ERROR "cannot convert" */ + _ = i<<0 + _ = i<<- /* ERROR "negative shift count" */ 1 + _ = i<<1.0 + _ = 1<<(1+0i) + _ = 1 /* ERROR "overflows" */ <<100 + + _ uint = 1 << 0 + _ uint = 1 << u + _ float32 = 1 /* ERROR "must be integer" */ << u + + // issue #14822 + _ = 1<<( /* ERROR "overflows uint" */ 1<<64) + _ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1) + + // issue #43697 + _ = u<<( /* ERROR "overflows uint" */ 1<<64) + _ = u<<(1<<64-1) + ) +} + +func shifts2() { + // from the spec + var ( + s uint = 33 + i = 1<<s // 1 has type int + j int32 = 1<<s // 1 has type int32; j == 0 + k = uint64(1<<s) // 1 has type uint64; k == 1<<33 + m int = 1.0<<s // 1.0 has type int + n = 1.0<<s != i // 1.0 has type int; n == false if ints are 32bits in size + o = 1<<s == 2<<s // 1 and 2 have type int; o == true if ints are 32bits in size + p = 1<<s == 1<<33 // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int + u = 1.0 /* ERROR "must be integer" */ <<s // illegal: 1.0 has type float64, cannot shift + u1 = 1.0 /* ERROR "must be integer" */ <<s != 0 // illegal: 1.0 has type float64, cannot shift + u2 = 1 /* ERROR "must be integer" */ <<s != 1.0 // illegal: 1 has type float64, cannot shift + v float32 = 1 /* ERROR "must be integer" */ <<s // illegal: 1 has type float32, cannot shift + w int64 = 1.0<<33 // 1.0<<33 is a constant shift expression + ) + _, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w +} + +func shifts3(a int16, b float32) { + // random tests + var ( + s uint = 11 + u = 1 /* ERROR "must be integer" */ <<s + 1.0 + v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1 + ) + x := 1.0 /* ERROR "must be integer" */ <<s + 1 + shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s) + _, _, _ = u, v, x +} + +func shifts4() { + // shifts in comparisons w/ untyped operands + var s uint + + _ = 1<<s == 1 + _ = 1 /* ERROR "integer" */ <<s == 1. + _ = 1. /* ERROR "integer" */ <<s == 1 + _ = 1. /* ERROR "integer" */ <<s == 1. + + _ = 1<<s + 1 == 1 + _ = 1 /* ERROR "integer" */ <<s + 1 == 1. + _ = 1 /* ERROR "integer" */ <<s + 1. == 1 + _ = 1 /* ERROR "integer" */ <<s + 1. == 1. + _ = 1. /* ERROR "integer" */ <<s + 1 == 1 + _ = 1. /* ERROR "integer" */ <<s + 1 == 1. + _ = 1. /* ERROR "integer" */ <<s + 1. == 1 + _ = 1. /* ERROR "integer" */ <<s + 1. == 1. + + _ = 1<<s == 1<<s + _ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + + _ = 1<<s + 1<<s == 1 + _ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. + _ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 + _ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. + _ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 + _ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. + _ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 + _ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. + + _ = 1<<s + 1<<s == 1<<s + 1<<s + _ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s + _ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s +} + +func shifts5() { + // shifts in comparisons w/ typed operands + var s uint + var x int + + _ = 1<<s == x + _ = 1.<<s == x + _ = 1.1 /* ERROR "int" */ <<s == x + + _ = 1<<s + x == 1 + _ = 1<<s + x == 1. + _ = 1<<s + x == 1.1 /* ERROR "int" */ + _ = 1.<<s + x == 1 + _ = 1.<<s + x == 1. + _ = 1.<<s + x == 1.1 /* ERROR "int" */ + _ = 1.1 /* ERROR "int" */ <<s + x == 1 + _ = 1.1 /* ERROR "int" */ <<s + x == 1. + _ = 1.1 /* ERROR "int" */ <<s + x == 1.1 + + _ = 1<<s == x<<s + _ = 1.<<s == x<<s + _ = 1.1 /* ERROR "int" */ <<s == x<<s +} + +func shifts6() { + // shifts as operands in non-arithmetic operations and as arguments + var a [10]int + var s uint + + _ = a[1<<s] + _ = a[1.0] + _ = a[1.0<<s] + + _ = make([]int, 1.0) + _ = make([]int, 1.0<<s) + _ = make([]int, 1.1 /* ERROR "must be integer" */ <<s) + + _ = float32(1) + _ = float32(1 /* ERROR "must be integer" */ <<s) + _ = float32(1.0) + _ = float32(1.0 /* ERROR "must be integer" */ <<s) + _ = float32(1.1 /* ERROR "must be integer" */ <<s) + + // TODO(gri) Re-enable these tests once types2 has the go/types fixes. + // Issue #52080. + // _ = int32(0x80000000 /* ERROR "overflows int32" */ << s) + // TODO(rfindley) Eliminate the redundant error here. + // _ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s) + + _ = int(1+0i<<0) + // _ = int((1+0i)<<s) + // _ = int(1.0<<s) + // _ = int(complex(1, 0)<<s) + _ = int(float32/* ERROR "must be integer" */(1.0) <<s) + _ = int(1.1 /* ERROR must be integer */ <<s) + _ = int(( /* ERROR "must be integer" */ 1+1i) <<s) + + _ = complex(1 /* ERROR "must be integer" */ <<s, 0) + + var b []int + _ = append(b, 1<<s) + _ = append(b, 1.0<<s) + _ = append(b, (1+0i)<<s) + _ = append(b, 1.1 /* ERROR "must be integer" */ <<s) + _ = append(b, (1 + 0i) <<s) + _ = append(b, ( /* ERROR "must be integer" */ 1 + 1i) <<s) + + _ = complex(1.0 /* ERROR "must be integer" */ <<s, 0) + _ = complex(1.1 /* ERROR "must be integer" */ <<s, 0) + _ = complex(0, 1.0 /* ERROR "must be integer" */ <<s) + _ = complex(0, 1.1 /* ERROR "must be integer" */ <<s) + + // TODO(gri) The delete below is not type-checked correctly yet. + // var m1 map[int]string + // delete(m1, 1<<s) +} + +func shifts7() { + // shifts of shifts + var s uint + var x int + _ = x + + _ = 1<<(1<<s) + _ = 1<<(1.<<s) + _ = 1. /* ERROR "integer" */ <<(1<<s) + _ = 1. /* ERROR "integer" */ <<(1.<<s) + + x = 1<<(1<<s) + x = 1<<(1.<<s) + x = 1.<<(1<<s) + x = 1.<<(1.<<s) + + _ = (1<<s)<<(1<<s) + _ = (1<<s)<<(1.<<s) + _ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s) + _ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s) + + x = (1<<s)<<(1<<s) + x = (1<<s)<<(1.<<s) + x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s) + x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s) +} + +func shifts8() { + // shift examples from shift discussion: better error messages + var s uint + _ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1 + _ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0 + _ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0 + _ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1 + _ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1 + _ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0 + + // additional cases + _ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1) + _ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s) + + _ = int(1.<<s) + _ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s) + _ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s) + _ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s) + _ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s) + // TODO(gri) the error messages for these two are incorrect - disabled for now + // _ = complex64(1<<s) + // _ = complex64(1.<<s) + _ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s) +} + +func shifts9() { + // various originally failing snippets of code from the std library + // from src/compress/lzw/reader.go:90 + { + var d struct { + bits uint32 + width uint + } + _ = uint16(d.bits & (1<<d.width - 1)) + } + + // from src/debug/dwarf/buf.go:116 + { + var ux uint64 + var bits uint + x := int64(ux) + if x&(1<<(bits-1)) != 0 {} + } + + // from src/encoding/asn1/asn1.go:160 + { + var bytes []byte + if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {} + } + + // from src/math/big/rat.go:140 + { + var exp int + var mantissa uint64 + shift := uint64(-1022 - (exp - 1)) // [1..53) + _ = mantissa & (1<<shift - 1) + } + + // from src/net/interface.go:51 + { + type Flags uint + var f Flags + var i int + if f&(1<<uint(i)) != 0 {} + } + + // from src/runtime/softfloat64.go:234 + { + var gm uint64 + var shift uint + _ = gm & (1<<shift - 1) + } + + // from src/strconv/atof.go:326 + { + var mant uint64 + var mantbits uint + if mant == 2<<mantbits {} + } + + // from src/route_bsd.go:82 + { + var Addrs int32 + const rtaRtMask = 1 + var i uint + if Addrs&rtaRtMask&(1<<i) == 0 {} + } + + // from src/text/scanner/scanner.go:540 + { + var s struct { Whitespace uint64 } + var ch rune + for s.Whitespace&(1<<uint(ch)) != 0 {} + } +} + +func issue5895() { + var x = 'a' << 1 // type of x must be rune + var _ rune = x +} + +func issue11325() { + var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325 + _ = 0 >> 1.1 /* ERROR "truncated to uint" */ + _ = 0 << 1.1 /* ERROR "truncated to uint" */ + _ = 0 >> 1. + _ = 1 >> 1.1 /* ERROR "truncated to uint" */ + _ = 1 >> 1. + _ = 1. >> 1 + _ = 1. >> 1. + _ = 1.1 /* ERROR "must be integer" */ >> 1 +} + +func issue11594() { + var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594 + _ = float32 /* ERROR "must be integer" */ (0) << 1 + _ = float64 /* ERROR "must be integer" */ (0) >> 2 + _ = complex64 /* ERROR "must be integer" */ (0) << 3 + _ = complex64 /* ERROR "must be integer" */ (0) >> 4 +} + +func issue21727() { + var s uint + var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ ) + var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ] + var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */ + var _ = string(1 /* ERROR shifted operand 1 .* must be integer */ << s) + var _ = string(1.0 /* ERROR "cannot convert" */ << s) +} + +func issue22969() { + var s uint + var a []byte + _ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969 + _ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s) + _ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s) + var _ byte = 0x100 /* ERROR "overflows byte" */ << s + var _ int8 = 0xff /* ERROR "overflows int8" */ << s + var _ int16 = 0xffff /* ERROR "overflows int16" */ << s + var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s +} diff --git a/src/internal/types/testdata/check/slices.go b/src/internal/types/testdata/check/slices.go new file mode 100644 index 0000000..2bacd1c --- /dev/null +++ b/src/internal/types/testdata/check/slices.go @@ -0,0 +1,68 @@ +// Copyright 2019 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. + +// Package slices implements various slice algorithms. +package slices + +// Map turns a []T1 to a []T2 using a mapping function. +func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 { + r := make([]T2, len(s)) + for i, v := range s { + r[i] = f(v) + } + return r +} + +// Reduce reduces a []T1 to a single value using a reduction function. +func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 { + r := initializer + for _, v := range s { + r = f(r, v) + } + return r +} + +// Filter filters values from a slice using a filter function. +func Filter[T any](s []T, f func(T) bool) []T { + var r []T + for _, v := range s { + if f(v) { + r = append(r, v) + } + } + return r +} + +// Example uses + +func limiter(x int) byte { + switch { + case x < 0: + return 0 + default: + return byte(x) + case x > 255: + return 255 + } +} + +var input = []int{-4, 68954, 7, 44, 0, -555, 6945} +var limited1 = Map[int, byte](input, limiter) +var limited2 = Map(input, limiter) // using type inference + +func reducer(x float64, y int) float64 { + return x + float64(y) +} + +var reduced1 = Reduce[int, float64](input, 0, reducer) +var reduced2 = Reduce(input, 1i /* ERROR overflows */, reducer) // using type inference +var reduced3 = Reduce(input, 1, reducer) // using type inference + +func filter(x int) bool { + return x&1 != 0 +} + +var filtered1 = Filter[int](input, filter) +var filtered2 = Filter(input, filter) // using type inference + diff --git a/src/internal/types/testdata/check/stmt0.go b/src/internal/types/testdata/check/stmt0.go new file mode 100644 index 0000000..c456aac --- /dev/null +++ b/src/internal/types/testdata/check/stmt0.go @@ -0,0 +1,994 @@ +// Copyright 2012 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. + +// statements + +package stmt0 + +func assignments0() (int, int) { + var a, b, c int + var ch chan int + f0 := func() {} + f1 := func() int { return 1 } + f2 := func() (int, int) { return 1, 2 } + f3 := func() (int, int, int) { return 1, 2, 3 } + + a, b, c = 1, 2, 3 + a, b, c = 1 /* ERROR "assignment mismatch: 3 variables but 2 values" */ , 2 + a, b, c = 1 /* ERROR "assignment mismatch: 3 variables but 4 values" */ , 2, 3, 4 + _, _, _ = a, b, c + + a = f0 /* ERROR "used as value" */ () + a = f1() + a = f2 /* ERROR "assignment mismatch: 1 variable but f2 returns 2 values" */ () + a, b = f2() + a, b, c = f2 /* ERROR "assignment mismatch: 3 variables but f2 returns 2 values" */ () + a, b, c = f3() + a, b = f3 /* ERROR "assignment mismatch: 2 variables but f3 returns 3 values" */ () + + a, b, c = <- /* ERROR "assignment mismatch: 3 variables but 1 value" */ ch + + return /* ERROR "not enough return values\n\thave \(\)\n\twant \(int, int\)" */ + return 1 /* ERROR "not enough return values\n\thave \(number\)\n\twant \(int, int\)" */ + return 1, 2 + return 1, 2, 3 /* ERROR "too many return values\n\thave \(number, number, number\)\n\twant \(int, int\)" */ +} + +func assignments1() { + b, i, f, c, s := false, 1, 1.0, 1i, "foo" + b = i /* ERROR "cannot use .* in assignment" */ + i = f /* ERROR "cannot use .* in assignment" */ + f = c /* ERROR "cannot use .* in assignment" */ + c = s /* ERROR "cannot use .* in assignment" */ + s = b /* ERROR "cannot use .* in assignment" */ + + v0, v1, v2 := 1 /* ERROR "assignment mismatch" */ , 2, 3, 4 + _, _, _ = v0, v1, v2 + + b = true + + i += 1 + i /* ERROR "mismatched types int and untyped string" */+= "foo" + + f -= 1 + f /= 0 + f = float32(0)/0 /* ERROR "division by zero" */ + f /* ERROR "mismatched types float64 and untyped string" */-= "foo" + + c *= 1 + c /= 0 + + s += "bar" + s /* ERROR "mismatched types string and untyped int" */+= 1 + + var u64 uint64 + u64 += 1<<u64 + + undefined /* ERROR "undefined" */ = 991 + + // test cases for issue 5800 + var ( + _ int = nil /* ERROR "cannot use nil as int value in variable declaration" */ + _ [10]int = nil /* ERROR "cannot use nil as \[10\]int value in variable declaration" */ + _ []byte = nil + _ struct{} = nil /* ERROR "cannot use nil as struct{} value in variable declaration" */ + _ func() = nil + _ map[int]string = nil + _ chan int = nil + ) + + // test cases for issue 5500 + _ = func() (int, bool) { + var m map[int]int + return m /* ERROR "not enough return values" */ [0] + } + + g := func(int, bool){} + var m map[int]int + g(m[0]) /* ERROR "not enough arguments" */ + + // assignments to _ + _ = nil /* ERROR "use of untyped nil" */ + _ = 1 << /* ERROR constant shift overflow */ 1000 + (_) = 0 +} + +func assignments2() { + type mybool bool + var m map[string][]bool + var s []bool + var b bool + var d mybool + _ = s + _ = b + _ = d + + // assignments to map index expressions are ok + s, b = m["foo"] + _, d = m["bar"] + m["foo"] = nil + m["foo"] = nil /* ERROR assignment mismatch: 1 variable but 2 values */ , false + _ = append(m["foo"]) + _ = append(m["foo"], true) + + var c chan int + _, b = <-c + _, d = <-c + <- /* ERROR cannot assign */ c = 0 + <-c = 0 /* ERROR assignment mismatch: 1 variable but 2 values */ , false + + var x interface{} + _, b = x.(int) + x /* ERROR cannot assign */ .(int) = 0 + x.(int) = 0 /* ERROR assignment mismatch: 1 variable but 2 values */ , false + + assignments2 /* ERROR used as value */ () = nil + int /* ERROR not an expression */ = 0 +} + +func issue6487() { + type S struct{x int} + _ = &S /* ERROR "cannot take address" */ {}.x + _ = &( /* ERROR "cannot take address" */ S{}.x) + _ = (&S{}).x + S /* ERROR "cannot assign" */ {}.x = 0 + (&S{}).x = 0 + + type M map[string]S + var m M + m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0 + _ = &( /* ERROR "cannot take address" */ m["foo"].x) + _ = &m /* ERROR "cannot take address" */ ["foo"].x +} + +func issue6766a() { + a, a /* ERROR a repeated on left side of := */ := 1, 2 + _ = a + a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3 + _ = b + c, c /* ERROR c repeated on left side of := */, b := 1, 2, 3 + _ = c + a, b := /* ERROR no new variables */ 1, 2 +} + +func shortVarDecls1() { + const c = 0 + type d int + a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */ := 1, "zwei", 3.0, 4 + var _ int = a // a is of type int + var _ string = b // b is of type string +} + +func incdecs() { + const c = 3.14 + c /* ERROR "cannot assign" */ ++ + s := "foo" + s /* ERROR "invalid operation" */ -- + 3.14 /* ERROR "cannot assign" */ ++ + var ( + x int + y float32 + z complex128 + ) + x++ + y-- + z++ +} + +func sends() { + var ch chan int + var rch <-chan int + var x int + x <- /* ERROR "cannot send" */ x + rch <- /* ERROR "cannot send" */ x + ch <- "foo" /* ERROR "cannot use .* in send" */ + ch <- x +} + +func selects() { + select {} + var ( + ch chan int + sc chan <- bool + ) + select { + case <-ch: + case (<-ch): + case t := <-ch: + _ = t + case t := (<-ch): + _ = t + case t, ok := <-ch: + _, _ = t, ok + case t, ok := (<-ch): + _, _ = t, ok + case <-sc /* ERROR "cannot receive from send-only channel" */ : + } + select { + default: + default /* ERROR "multiple defaults" */ : + } + select { + case a, b := <-ch: + _, b = a, b + case x /* ERROR send or receive */ : + case a /* ERROR send or receive */ := ch: + } + + // test for issue 9570: ch2 in second case falsely resolved to + // ch2 declared in body of first case + ch1 := make(chan int) + ch2 := make(chan int) + select { + case <-ch1: + var ch2 /* ERROR ch2 declared and not used */ chan bool + case i := <-ch2: + print(i + 1) + } +} + +func gos() { + go 1; /* ERROR "must be function call" */ + go int /* ERROR "go requires function call, not conversion" */ (0) + go ( /* ERROR expression in go must not be parenthesized */ gos()) + go gos() + var c chan int + go close(c) + go len /* ERROR "go discards result" */ (c) +} + +func defers() { + defer 1; /* ERROR "must be function call" */ + defer int /* ERROR "defer requires function call, not conversion" */ (0) + defer ( /* ERROR expression in defer must not be parenthesized */ defers()) + defer defers() + var c chan int + defer close(c) + defer len /* ERROR "defer discards result" */ (c) +} + +func breaks() { + var x, y int + + break /* ERROR "break" */ + { + break /* ERROR "break" */ + } + if x < y { + break /* ERROR "break" */ + } + + switch x { + case 0: + break + case 1: + if x == y { + break + } + default: + break + break + } + + var z interface{} + switch z.(type) { + case int: + break + } + + for { + break + } + + var a []int + for _ = range a { + break + } + + for { + if x == y { + break + } + } + + var ch chan int + select { + case <-ch: + break + } + + select { + case <-ch: + if x == y { + break + } + default: + break + } +} + +func continues() { + var x, y int + + continue /* ERROR "continue" */ + { + continue /* ERROR "continue" */ + } + + if x < y { + continue /* ERROR "continue" */ + } + + switch x { + case 0: + continue /* ERROR "continue" */ + } + + var z interface{} + switch z.(type) { + case int: + continue /* ERROR "continue" */ + } + + var ch chan int + select { + case <-ch: + continue /* ERROR "continue" */ + } + + for i := 0; i < 10; i++ { + continue + if x < y { + continue + break + } + switch x { + case y: + continue + default: + break + } + select { + case <-ch: + continue + } + } + + var a []int + for _ = range a { + continue + if x < y { + continue + break + } + switch x { + case y: + continue + default: + break + } + select { + case <-ch: + continue + } + } +} + +func returns0() { + return + return 0 /* ERROR too many return values */ +} + +func returns1(x float64) (int, *float64) { + return 0, &x + return /* ERROR not enough return values */ + return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */ + return 0, &x, 1 /* ERROR too many return values */ +} + +func returns2() (a, b int) { + return + return 1, "foo" /* ERROR cannot use .* in return statement */ + return 1, 2, 3 /* ERROR too many return values */ + { + type a int + return 1, 2 + return /* ERROR a not in scope at return */ + } +} + +func returns3() (_ int) { + return + { + var _ int // blank (_) identifiers never shadow since they are in no scope + return + } +} + +func switches0() { + var x int + + switch x { + } + + switch x { + default: + default /* ERROR "multiple defaults" */ : + } + + switch { + case 1 /* ERROR "cannot convert" */ : + } + + true := "false" + _ = true + // A tagless switch is equivalent to the bool + // constant true, not the identifier 'true'. + switch { + case "false" /* ERROR "cannot convert" */: + } + + switch int32(x) { + case 1, 2: + case x /* ERROR "invalid case x in switch on int32\(x\) \(mismatched types int and int32\)" */ : + } + + switch x { + case 1 /* ERROR "overflows" */ << 100: + } + + switch x { + case 1: + case 1 /* ERROR "duplicate case" */ : + case ( /* ERROR "duplicate case" */ 1): + case 2, 3, 4: + case 5, 1 /* ERROR "duplicate case" */ : + } + + switch uint64(x) { + case 1<<64 - 1: + case 1 /* ERROR duplicate case */ <<64 - 1: + case 2, 3, 4: + case 5, 1 /* ERROR duplicate case */ <<64 - 1: + } + + var y32 float32 + switch y32 { + case 1.1: + case 11/10: // integer division! + case 11. /* ERROR duplicate case */ /10: + case 2, 3.0, 4.1: + case 5.2, 1.10 /* ERROR duplicate case */ : + } + + var y64 float64 + switch y64 { + case 1.1: + case 11/10: // integer division! + case 11. /* ERROR duplicate case */ /10: + case 2, 3.0, 4.1: + case 5.2, 1.10 /* ERROR duplicate case */ : + } + + var s string + switch s { + case "foo": + case "foo" /* ERROR duplicate case */ : + case "f" /* ERROR duplicate case */ + "oo": + case "abc", "def", "ghi": + case "jkl", "foo" /* ERROR duplicate case */ : + } + + type T int + type F float64 + type S string + type B bool + var i interface{} + switch i { + case nil: + case nil: // no duplicate detection + case (*int)(nil): + case (*int)(nil): // do duplicate detection + case 1: + case byte(1): + case int /* ERROR duplicate case */ (1): + case T(1): + case 1.0: + case F(1.0): + case F /* ERROR duplicate case */ (1.0): + case "hello": + case S("hello"): + case S /* ERROR duplicate case */ ("hello"): + case 1==1, B(false): + case false, B(2==2): + } + + // switch on array + var a [3]int + switch a { + case [3]int{1, 2, 3}: + case [3]int{1, 2, 3}: // no duplicate detection + case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}: + } + + // switch on channel + var c1, c2 chan int + switch c1 { + case nil: + case c1: + case c2: + case c1, c2: // no duplicate detection + } +} + +func switches1() { + fallthrough /* ERROR "fallthrough statement out of place" */ + + var x int + switch x { + case 0: + fallthrough /* ERROR "fallthrough statement out of place" */ + break + case 1: + fallthrough + case 2: + fallthrough; ; ; // trailing empty statements are ok + case 3: + default: + fallthrough; ; + case 4: + fallthrough /* ERROR "cannot fallthrough final case in switch" */ + } + + var y interface{} + switch y.(type) { + case int: + fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ; + default: + } + + switch x { + case 0: + if x == 0 { + fallthrough /* ERROR "fallthrough statement out of place" */ + } + } + + switch x { + case 0: + goto L1 + L1: fallthrough; ; + case 1: + goto L2 + goto L3 + goto L4 + L2: L3: L4: fallthrough + default: + } + + switch x { + case 0: + goto L5 + L5: fallthrough + default: + goto L6 + goto L7 + goto L8 + L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */ + } + + switch x { + case 0: + fallthrough; ; + case 1: + { + fallthrough /* ERROR "fallthrough statement out of place" */ + } + case 2: + fallthrough + case 3: + fallthrough /* ERROR "fallthrough statement out of place" */ + { /* empty block is not an empty statement */ }; ; + default: + fallthrough /* ERROR "cannot fallthrough final case in switch" */ + } + + switch x { + case 0: + { + fallthrough /* ERROR "fallthrough statement out of place" */ + } + } +} + +func switches2() { + // untyped nil is not permitted as switch expression + switch nil /* ERROR "use of untyped nil" */ { + case 1, 2, "foo": // don't report additional errors here + } + + // untyped constants are converted to default types + switch 1<<63-1 { + } + switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 { + } + var x int + switch 1.0 { + case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ : + } + switch x { + case 1.0: + } + + // untyped bools become of type bool + type B bool + var b B = true + switch x == x { + case b /* ERROR "mismatched types B and bool" */ : + } + switch { + case b /* ERROR "mismatched types B and bool" */ : + } +} + +func issue11667() { + switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ { + } + switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ { + case 9223372036854775808: + } + var x int + switch x { + case 9223372036854775808 /* ERROR "overflows int" */ : + } + var y float64 + switch y { + case 9223372036854775808: + } +} + +func issue11687() { + f := func() (_, _ int) { return } + switch f /* ERROR "multiple-value f" */ () { + } + var x int + switch f /* ERROR "multiple-value f" */ () { + case x: + } + switch x { + case f /* ERROR "multiple-value f" */ (): + } +} + +type I interface { + m() +} + +type I2 interface { + m(int) +} + +type T struct{} +type T1 struct{} +type T2 struct{} + +func (T) m() {} +func (T2) m(int) {} + +func typeswitches() { + var i int + var x interface{} + + switch x.(type) {} + switch (x /* ERROR "outside type switch" */ .(type)) {} + + switch x.(type) { + default: + default /* ERROR "multiple defaults" */ : + } + + switch x /* ERROR "declared and not used" */ := x.(type) {} + switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {} + + switch x := x.(type) { + case int: + var y int = x + _ = y + } + + switch x /* ERROR "x declared and not used" */ := i /* ERROR "not an interface" */ .(type) {} + + switch t := x.(type) { + case nil: + var v bool = t /* ERROR "cannot use .* in variable declaration" */ + _ = v + case int: + var v int = t + _ = v + case float32, complex64: + var v float32 = t /* ERROR "cannot use .* in variable declaration" */ + _ = v + default: + var v float32 = t /* ERROR "cannot use .* in variable declaration" */ + _ = v + } + + var t I + switch t.(type) { + case T: + case T1 /* ERROR "missing method m" */ : + case T2 /* ERROR "wrong type for method m" */ : + case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561) + } + + + { + x := 1 + v := 2 + switch v /* ERROR "v [(]variable of type int[)] is not an interface" */ .(type) { + case int: + println(x) + println(x / 0 /* ERROR "invalid operation: division by zero" */) + case 1 /* ERROR "1 is not a type" */: + } + } +} + +// Test that each case clause uses the correct type of the variable +// declared by the type switch (issue 5504). +func typeswitch0() { + switch y := interface{}(nil).(type) { + case int: + func() int { return y + 0 }() + case float32: + func() float32 { return y }() + } +} + +// Test correct scope setup. +// (no redeclaration errors expected in the type switch) +func typeswitch1() { + var t I + switch t := t; t := t.(type) { + case nil: + var _ I = t + case T: + var _ T = t + default: + var _ I = t + } +} + +// Test correct typeswitch against interface types. +type A interface { a() } +type B interface { b() } +type C interface { a(int) } + +func typeswitch2() { + switch A(nil).(type) { + case A: + case B: + case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561) + } +} + +func typeswitch3(x interface{}) { + switch x.(type) { + case int: + case float64: + case int /* ERROR duplicate case */ : + } + + switch x.(type) { + case nil: + case int: + case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ : + } + + type F func(int) + switch x.(type) { + case nil: + case int, func(int): + case float32, func /* ERROR duplicate case */ (x int): + case F: + } +} + +func fors1() { + for {} + var i string + _ = i + for i := 0; i < 10; i++ {} + for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {} +} + +func rangeloops1() { + var ( + x int + a [10]float32 + b []string + p *[10]complex128 + pp **[10]complex128 + s string + m map[int]bool + c chan int + sc chan<- int + rc <-chan int + ) + + for range x /* ERROR "cannot range over" */ {} + for _ = range x /* ERROR "cannot range over" */ {} + for i := range x /* ERROR "cannot range over" */ {} + + for range a {} + for i := range a { + var ii int + ii = i + _ = ii + } + for i, x := range a { + var ii int + ii = i + _ = ii + var xx float64 + xx = x /* ERROR "cannot use .* in assignment" */ + _ = xx + } + var ii int + var xx float32 + for ii, xx = range a {} + _, _ = ii, xx + + for range b {} + for i := range b { + var ii int + ii = i + _ = ii + } + for i, x := range b { + var ii int + ii = i + _ = ii + var xx string + xx = x + _ = xx + } + + for range s {} + for i := range s { + var ii int + ii = i + _ = ii + } + for i, x := range s { + var ii int + ii = i + _ = ii + var xx rune + xx = x + _ = xx + } + + for range p {} + for _, x := range p { + var xx complex128 + xx = x + _ = xx + } + + for range pp /* ERROR "cannot range over" */ {} + for _, x := range pp /* ERROR "cannot range over" */ {} + + for range m {} + for k := range m { + var kk int32 + kk = k /* ERROR "cannot use .* in assignment" */ + _ = kk + } + for k, v := range m { + var kk int + kk = k + _ = kk + if v {} + } + + for range c {} + for _, _ /* ERROR "only one iteration variable" */ = range c {} + for e := range c { + var ee int + ee = e + _ = ee + } + for _ = range sc /* ERROR "cannot range over" */ {} + for _ = range rc {} + + // constant strings + const cs = "foo" + for range cs {} + for range "" {} + for i, x := range cs { _, _ = i, x } + for i, x := range "" { + var ii int + ii = i + _ = ii + var xx rune + xx = x + _ = xx + } +} + +func rangeloops2() { + type I int + type R rune + + var a [10]int + var i I + _ = i + for i /* ERROR cannot use .* in assignment */ = range a {} + for i /* ERROR cannot use .* in assignment */ = range &a {} + for i /* ERROR cannot use .* in assignment */ = range a[:] {} + + var s string + var r R + _ = r + for i /* ERROR cannot use .* in assignment */ = range s {} + for i /* ERROR cannot use .* in assignment */ = range "foo" {} + for _, r /* ERROR cannot use .* in assignment */ = range s {} + for _, r /* ERROR cannot use .* in assignment */ = range "foo" {} +} + +func issue6766b() { + for _ := /* ERROR no new variables */ range "" {} + for a, a /* ERROR redeclared */ := range "" { _ = a } + var a int + _ = a + for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a } +} + +// Test that despite errors in the range clause, +// the loop body is still type-checked (and thus +// errors reported). +func issue10148() { + for y /* ERROR declared and not used */ := range "" { + _ = "" /* ERROR mismatched types untyped string and untyped int */ + 1 + } + for range 1 /* ERROR cannot range over 1 */ { + _ = "" /* ERROR mismatched types untyped string and untyped int */ + 1 + } + for y := range 1 /* ERROR cannot range over 1 */ { + _ = "" /* ERROR mismatched types untyped string and untyped int */ + 1 + } +} + +func labels0() { + goto L0 + goto L1 + L0: + L1: + L1 /* ERROR "already declared" */ : + if true { + goto L2 + L2: + L0 /* ERROR "already declared" */ : + } + _ = func() { + goto L0 + goto L1 + goto L2 + L0: + L1: + L2: + } +} + +func expression_statements(ch chan int) { + expression_statements(ch) + <-ch + println() + + 0 /* ERROR "not used" */ + 1 /* ERROR "not used" */ +2 + cap /* ERROR "not used" */ (ch) + println /* ERROR "must be called" */ +} diff --git a/src/internal/types/testdata/check/stmt1.go b/src/internal/types/testdata/check/stmt1.go new file mode 100644 index 0000000..f79f920 --- /dev/null +++ b/src/internal/types/testdata/check/stmt1.go @@ -0,0 +1,259 @@ +// Copyright 2013 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. + +// terminating statements + +package stmt1 + +func _() {} + +func _() int {} /* ERROR "missing return" */ + +func _() int { panic(0) } +func _() int { (panic(0)) } + +// block statements +func _(x, y int) (z int) { + { + return + } +} + +func _(x, y int) (z int) { + { + return; ; ; // trailing empty statements are ok + } + ; ; ; +} + +func _(x, y int) (z int) { + { + } +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + { + ; ; ; + } + ; ; ; +} /* ERROR "missing return" */ + +// if statements +func _(x, y int) (z int) { + if x < y { return } + return 1 +} + +func _(x, y int) (z int) { + if x < y { return; ; ; ; } + return 1 +} + +func _(x, y int) (z int) { + if x < y { return } + return 1; ; +} + +func _(x, y int) (z int) { + if x < y { return } +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + if x < y { + } else { return 1 + } +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + if x < y { return + } else { return + } +} + +// for statements +func _(x, y int) (z int) { + for x < y { + return + } +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + for { + return + } +} + +func _(x, y int) (z int) { + for { + return; ; ; ; + } +} + +func _(x, y int) (z int) { + for { + return + break + } + ; ; ; +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + for { + for { break } + return + } +} + +func _(x, y int) (z int) { + for { + for { break } + return ; ; + } + ; +} + +func _(x, y int) (z int) { +L: for { + for { break L } + return + } +} /* ERROR "missing return" */ + +// switch statements +func _(x, y int) (z int) { + switch x { + case 0: return + default: return + } +} + +func _(x, y int) (z int) { + switch x { + case 0: return; + default: return; ; ; + } +} + +func _(x, y int) (z int) { + switch x { + case 0: return + } +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + switch x { + case 0: return + case 1: break + } +} /* ERROR "missing return" */ + +func _(x, y int) (z int) { + switch x { + case 0: return + default: + switch y { + case 0: break + } + panic(0) + } +} + +func _(x, y int) (z int) { + switch x { + case 0: return + default: + switch y { + case 0: break + } + panic(0); ; ; + } + ; +} + +func _(x, y int) (z int) { +L: switch x { + case 0: return + default: + switch y { + case 0: break L + } + panic(0) + } +} /* ERROR "missing return" */ + +// select statements +func _(ch chan int) (z int) { + select {} +} // nice! + +func _(ch chan int) (z int) { + select {} + ; ; +} + +func _(ch chan int) (z int) { + select { + default: break + } +} /* ERROR "missing return" */ + +func _(ch chan int) (z int) { + select { + case <-ch: return + default: break + } +} /* ERROR "missing return" */ + +func _(ch chan int) (z int) { + select { + case <-ch: return + default: + for i := 0; i < 10; i++ { + break + } + return + } +} + +func _(ch chan int) (z int) { + select { + case <-ch: return; ; ; + default: + for i := 0; i < 10; i++ { + break + } + return; ; ; + } + ; ; ; +} + +func _(ch chan int) (z int) { +L: select { + case <-ch: return + default: + for i := 0; i < 10; i++ { + break L + } + return + } + ; ; ; +} /* ERROR "missing return" */ + +func parenPanic() int { + ((((((panic)))(0)))) +} + +func issue23218a() int { + { + panic := func(interface{}){} + panic(0) + } +} /* ERROR "missing return" */ + +func issue23218b() int { + { + panic := func(interface{}){} + ((((panic))))(0) + } +} /* ERROR "missing return" */ diff --git a/src/internal/types/testdata/check/typeinference.go b/src/internal/types/testdata/check/typeinference.go new file mode 100644 index 0000000..28f3e28 --- /dev/null +++ b/src/internal/types/testdata/check/typeinference.go @@ -0,0 +1,49 @@ +// Copyright 2021 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. + +package typeInference + +// As of issue #51527, type-type inference has been disabled. + +// basic inference +type Tb[P ~*Q, Q any] int +func _() { + var x Tb /* ERROR got 1 arguments */ [*int] + var y Tb[*int, int] + x = y /* ERROR cannot use y .* in assignment */ + _ = x +} + +// recursive inference +type Tr[A any, B *C, C *D, D *A] int +func _() { + var x Tr /* ERROR got 1 arguments */ [string] + var y Tr[string, ***string, **string, *string] + var z Tr[int, ***int, **int, *int] + x = y /* ERROR cannot use y .* in assignment */ + x = z // ERROR cannot use z .* as Tr + _ = x +} + +// other patterns of inference +type To0[A any, B []A] int +type To1[A any, B struct{a A}] int +type To2[A any, B [][]A] int +type To3[A any, B [3]*A] int +type To4[A any, B any, C struct{a A; b B}] int +func _() { + var _ To0 /* ERROR got 1 arguments */ [int] + var _ To1 /* ERROR got 1 arguments */ [int] + var _ To2 /* ERROR got 1 arguments */ [int] + var _ To3 /* ERROR got 1 arguments */ [int] + var _ To4 /* ERROR got 2 arguments */ [int, string] +} + +// failed inference +type Tf0[A, B any] int +type Tf1[A any, B ~struct{a A; c C}, C any] int +func _() { + var _ Tf0 /* ERROR got 1 arguments but 2 type parameters */ [int] + var _ Tf1 /* ERROR got 1 arguments but 3 type parameters */ [int] +} diff --git a/src/internal/types/testdata/check/typeinst0.go b/src/internal/types/testdata/check/typeinst0.go new file mode 100644 index 0000000..c21cb53 --- /dev/null +++ b/src/internal/types/testdata/check/typeinst0.go @@ -0,0 +1,62 @@ +// Copyright 2019 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. + +package p + +type myInt int + +// Parameterized type declarations + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +type T1[P any] P // ERROR cannot use a type parameter as RHS in type declaration + +type T2[P any] struct { + f P + g int // int should still be in scope chain +} + +type List[P any] []P + +// Alias type declarations cannot have type parameters. +// Issue #46477 proposses to change that. +type A1[P any] = /* ERROR cannot be alias */ struct{} + +// Pending clarification of #46477 we disallow aliases +// of generic types. +type A2 = List // ERROR cannot use generic type +var _ A2[int] +var _ A2 + +type A3 = List[int] +var _ A3 + +// Parameterized type instantiations + +var x int +type _ x /* ERROR not a type */ [int] + +type _ int /* ERROR not a generic type */ [] // ERROR expected type argument list +type _ myInt /* ERROR not a generic type */ [] // ERROR expected type argument list + +// TODO(gri) better error messages +type _ T1[] // ERROR expected type argument list +type _ T1[x /* ERROR not a type */ ] +type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32] + +var _ T2[int] = T2[int]{} + +var _ List[int] = []int{1, 2, 3} +var _ List[[]int] = [][]int{{1, 2, 3}} +var _ List[List[List[int]]] + +// Parameterized types containing parameterized types + +type T3[P any] List[P] + +var _ T3[int] = T3[int](List[int]{1, 2, 3}) + +// Self-recursive generic types are not permitted + +type self1[P any] self1 /* ERROR invalid recursive type */ [P] +type self2[P any] *self2[P] // this is ok diff --git a/src/internal/types/testdata/check/typeinst1.go b/src/internal/types/testdata/check/typeinst1.go new file mode 100644 index 0000000..e7bb247 --- /dev/null +++ b/src/internal/types/testdata/check/typeinst1.go @@ -0,0 +1,282 @@ +// Copyright 2019 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. + +package p + +type List[E any] []E +var _ List[List[List[int]]] +var _ List[List[List[int]]] = []List[List[int]]{} + +type ( + T1[P1 any] struct { + f1 T2[P1, float32] + } + + T2[P2, P3 any] struct { + f2 P2 + f3 P3 + } +) + +func _() { + var x1 T1[int] + var x2 T2[int, float32] + + x1.f1.f2 = 0 + x1.f1 = x2 +} + +type T3[P any] T1[T2[P, P]] + +func _() { + var x1 T3[int] + var x2 T2[int, int] + x1.f1.f2 = x2 +} + +func f[P any] (x P) List[P] { + return List[P]{x} +} + +var ( + _ []int = f(0) + _ []float32 = f[float32](10) + _ List[complex128] = f(1i) + _ []List[int] = f(List[int]{}) + _ List[List[int]] = []List[int]{} + _ = []List[int]{} +) + +// Parameterized types with methods + +func (l List[E]) Head() (_ E, _ bool) { + if len(l) > 0 { + return l[0], true + } + return +} + +// A test case for instantiating types with other types (extracted from map.go2) + +type Pair[K any] struct { + key K +} + +type Receiver[T any] struct { + values T +} + +type Iterator[K any] struct { + r Receiver[Pair[K]] +} + +func Values [T any] (r Receiver[T]) T { + return r.values +} + +func (it Iterator[K]) Next() K { + return Values[Pair[K]](it.r).key +} + +// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence) + +type NumericAbs[T any] interface { + Abs() T +} + +func AbsDifference[T NumericAbs[T]](x T) { panic(0) } + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// type OrderedAbs[T any] T +// +// func (a OrderedAbs[T]) Abs() OrderedAbs[T] +// +// func OrderedAbsDifference[T any](x T) { +// AbsDifference(OrderedAbs[T](x)) +// } + +// same code, reduced to essence + +func g[P interface{ m() P }](x P) { panic(0) } + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// type T4[P any] P +// +// func (_ T4[P]) m() T4[P] +// +// func _[Q any](x Q) { +// g(T4[Q](x)) +// } + +// Another test case that caused problems in the past + +type T5[_ interface { a() }, _ interface{}] struct{} + +type A[P any] struct{ x P } + +func (_ A[P]) a() {} + +var _ T5[A[int], int] + +// Invoking methods with parameterized receiver types uses +// type inference to determine the actual type arguments matching +// the receiver type parameters from the actual receiver argument. +// Go does implicit address-taking and dereferenciation depending +// on the actual receiver and the method's receiver type. To make +// type inference work, the type-checker matches "pointer-ness" +// of the actual receiver and the method's receiver type. +// The following code tests this mechanism. + +type R1[A any] struct{} +func (_ R1[A]) vm() +func (_ *R1[A]) pm() + +func _[T any](r R1[T], p *R1[T]) { + r.vm() + r.pm() + p.vm() + p.pm() +} + +type R2[A, B any] struct{} +func (_ R2[A, B]) vm() +func (_ *R2[A, B]) pm() + +func _[T any](r R2[T, int], p *R2[string, T]) { + r.vm() + r.pm() + p.vm() + p.pm() +} + +// It is ok to have multiple embedded unions. +type _ interface { + m0() + ~int | ~string | ~bool + ~float32 | ~float64 + m1() + m2() + ~complex64 | ~complex128 + ~rune +} + +// Type sets may contain each type at most once. +type _ interface { + ~int|~ /* ERROR overlapping terms ~int */ int + ~int|int /* ERROR overlapping terms int */ + int|int /* ERROR overlapping terms int */ +} + +type _ interface { + ~struct{f int} | ~struct{g int} | ~ /* ERROR overlapping terms */ struct{f int} +} + +// Interface term lists can contain any type, incl. *Named types. +// Verify that we use the underlying type(s) of the type(s) in the +// term list when determining if an operation is permitted. + +type MyInt int +func add1[T interface{MyInt}](x T) T { + return x + 1 +} + +type MyString string +func double[T interface{MyInt|MyString}](x T) T { + return x + x +} + +// Embedding of interfaces with term lists leads to interfaces +// with term lists that are the intersection of the embedded +// term lists. + +type E0 interface { + ~int | ~bool | ~string +} + +type E1 interface { + ~int | ~float64 | ~string +} + +type E2 interface { + ~float64 +} + +type I0 interface { + E0 +} + +func f0[T I0]() {} +var _ = f0[int] +var _ = f0[bool] +var _ = f0[string] +var _ = f0[float64 /* ERROR does not satisfy I0 */ ] + +type I01 interface { + E0 + E1 +} + +func f01[T I01]() {} +var _ = f01[int] +var _ = f01[bool /* ERROR does not satisfy I0 */ ] +var _ = f01[string] +var _ = f01[float64 /* ERROR does not satisfy I0 */ ] + +type I012 interface { + E0 + E1 + E2 +} + +func f012[T I012]() {} +var _ = f012[int /* ERROR cannot satisfy I012.*empty type set */ ] +var _ = f012[bool /* ERROR cannot satisfy I012.*empty type set */ ] +var _ = f012[string /* ERROR cannot satisfy I012.*empty type set */ ] +var _ = f012[float64 /* ERROR cannot satisfy I012.*empty type set */ ] + +type I12 interface { + E1 + E2 +} + +func f12[T I12]() {} +var _ = f12[int /* ERROR does not satisfy I12 */ ] +var _ = f12[bool /* ERROR does not satisfy I12 */ ] +var _ = f12[string /* ERROR does not satisfy I12 */ ] +var _ = f12[float64] + +type I0_ interface { + E0 + ~int +} + +func f0_[T I0_]() {} +var _ = f0_[int] +var _ = f0_[bool /* ERROR does not satisfy I0_ */ ] +var _ = f0_[string /* ERROR does not satisfy I0_ */ ] +var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ] + +// Using a function instance as a type is an error. +var _ f0 // ERROR not a type +var _ f0 /* ERROR not a type */ [int] + +// Empty type sets can only be satisfied by empty type sets. +type none interface { + // force an empty type set + int + string +} + +func ff[T none]() {} +func gg[T any]() {} +func hh[T ~int]() {} + +func _[T none]() { + _ = ff[int /* ERROR cannot satisfy none \(empty type set\) */ ] + _ = ff[T] // pathological but ok because T's type set is empty, too + _ = gg[int] + _ = gg[T] + _ = hh[int] + _ = hh[T] +} diff --git a/src/internal/types/testdata/check/typeinstcycles.go b/src/internal/types/testdata/check/typeinstcycles.go new file mode 100644 index 0000000..74fe191 --- /dev/null +++ b/src/internal/types/testdata/check/typeinstcycles.go @@ -0,0 +1,11 @@ +// Copyright 2021 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. + +package p + +import "unsafe" + +func F1[T any](_ [unsafe.Sizeof(F1[int])]T) (res T) { return } +func F2[T any](_ T) (res [unsafe.Sizeof(F2[string])]int) { return } +func F3[T any](_ [unsafe.Sizeof(F1[string])]int) {} diff --git a/src/internal/types/testdata/check/typeparams.go b/src/internal/types/testdata/check/typeparams.go new file mode 100644 index 0000000..0e440d8 --- /dev/null +++ b/src/internal/types/testdata/check/typeparams.go @@ -0,0 +1,508 @@ +// Copyright 2018 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. + +package p + +// import "io" // for type assertion tests + +var _ any // ok to use any anywhere +func _[_ any, _ interface{any}](any) { + var _ any +} + +func identity[T any](x T) T { return x } + +func _[_ any](x int) int { panic(0) } +func _[T any](T /* ERROR redeclared */ T)() {} +func _[T, T /* ERROR redeclared */ any]() {} + +// Constraints (incl. any) may be parenthesized. +func _[_ (any)]() {} +func _[_ (interface{})]() {} + +func reverse[T any](list []T) []T { + rlist := make([]T, len(list)) + i := len(list) + for _, x := range list { + i-- + rlist[i] = x + } + return rlist +} + +var _ = reverse /* ERROR cannot use generic function reverse */ +var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3}) +var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3}) +var f = reverse[chan int] +var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ ) + +func swap[A, B any](a A, b B) (B, A) { return b, a } + +var _ = swap /* ERROR multiple-value */ [int, float32](1, 2) +var f32, i = swap[int, float32](swap[float32, int](1, 2)) +var _ float32 = f32 +var _ int = i + +func swapswap[A, B any](a A, b B) (A, B) { + return swap[B, A](b, a) +} + +type F[A, B any] func(A, B) (B, A) + +func min[T interface{ ~int }](x, y T) T { + if x < y { + return x + } + return y +} + +func _[T interface{~int | ~float32}](x, y T) bool { return x < y } +func _[T any](x, y T) bool { return x /* ERROR type parameter T is not comparable */ < y } +func _[T interface{~int | ~float32 | ~bool}](x, y T) bool { return x /* ERROR type parameter T is not comparable */ < y } + +func _[T C1[T]](x, y T) bool { return x /* ERROR type parameter T is not comparable */ < y } +func _[T C2[T]](x, y T) bool { return x < y } + +type C1[T any] interface{} +type C2[T any] interface{ ~int | ~float32 } + +func new[T any]() *T { + var x T + return &x +} + +var _ = new /* ERROR cannot use generic function new */ +var _ *int = new[int]() + +func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) {} // w/o constraint we don't know if T is comparable + +func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int { panic(0) } +var _ = f1[int](struct{T1}{}) +type T1 = int + +func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int { panic(0) } +var _ = f2[t1](struct{t1; x float32}{}) +type t1 = int + + +func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int { panic(0) } + +var _ = f3[int, rune, bool](1, struct{x rune}{}, nil) + +// indexing + +func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } +func _[T interface{ ~int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } +func _[T interface{ ~string }] (x T, i int) { _ = x[i] } +func _[T interface{ ~[]int }] (x T, i int) { _ = x[i] } +func _[T interface{ ~[10]int | ~*[20]int | ~map[int]int }] (x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types +func _[T interface{ ~string | ~[]byte }] (x T, i int) { _ = x[i] } +func _[T interface{ ~[]int | ~[1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } +func _[T interface{ ~string | ~[]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } + +// indexing with various combinations of map types in type sets (see issue #42616) +func _[T interface{ ~[]E | ~map[int]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types +func _[T interface{ ~[]E }, E any](x T, i int) { _ = &x[i] } +func _[T interface{ ~map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted +func _[T interface{ ~map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] } +func _[T interface{ ~map[int]E | ~map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types +func _[T interface{ ~[]E | ~map[string]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types + +// indexing with various combinations of array and other types in type sets +func _[T interface{ [10]int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] } +func _[T interface{ [10]byte | string }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] } +func _[T interface{ [10]int | *[20]int | []int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] } + +// indexing with strings and non-variable arrays (assignment not permitted) +func _[T string](x T) { _ = x[0]; x /* ERROR cannot assign */ [0] = 0 } +func _[T []byte | string](x T) { x /* ERROR cannot assign */ [0] = 0 } +func _[T [10]byte]() { f := func() (x T) { return }; f /* ERROR cannot assign */ ()[0] = 0 } +func _[T [10]byte]() { f := func() (x *T) { return }; f /* ERROR cannot index */ ()[0] = 0 } +func _[T [10]byte]() { f := func() (x *T) { return }; (*f())[0] = 0 } +func _[T *[10]byte]() { f := func() (x T) { return }; f()[0] = 0 } + +// slicing + +func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j] } +func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j:k] } +func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j] } +func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j:k] } +func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j] } +func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] } + +type myByte1 []byte +type myByte2 []byte +func _[T interface{ []byte | myByte1 | myByte2 }] (x T, i, j, k int) { var _ T = x[i:j:k] } +func _[T interface{ []byte | myByte1 | []int }] (x T, i, j, k int) { var _ T = x /* ERROR no core type */ [i:j:k] } + +func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j] } +func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] } +func _[T interface{ []byte | myByte1 | []int | string }] (x T, i, j, k int) { var _ T = x /* ERROR no core type */ [i:j] } + +// len/cap built-ins + +func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) } +func _[T interface{ ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string }](x T) { _ = len(x) } +func _[T interface{ ~[10]int }](x T) { _ = len(x) } +func _[T interface{ ~[]byte }](x T) { _ = len(x) } +func _[T interface{ ~map[int]int }](x T) { _ = len(x) } +func _[T interface{ ~chan int }](x T) { _ = len(x) } +func _[T interface{ ~string | ~[]byte | ~chan int }](x T) { _ = len(x) } + +func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~string }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~[10]int }](x T) { _ = cap(x) } +func _[T interface{ ~[]byte }](x T) { _ = cap(x) } +func _[T interface{ ~map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } +func _[T interface{ ~chan int }](x T) { _ = cap(x) } +func _[T interface{ ~[]byte | ~chan int }](x T) { _ = cap(x) } + +// range iteration + +func _[T interface{}](x T) { + for range x /* ERROR cannot range */ {} +} + +type myString string + +func _[ + B1 interface{ string }, + B2 interface{ string | myString }, + + C1 interface{ chan int }, + C2 interface{ chan int | <-chan int }, + C3 interface{ chan<- int }, + + S1 interface{ []int }, + S2 interface{ []int | [10]int }, + + A1 interface{ [10]int }, + A2 interface{ [10]int | []int }, + + P1 interface{ *[10]int }, + P2 interface{ *[10]int | *[]int }, + + M1 interface{ map[string]int }, + M2 interface{ map[string]int | map[string]string }, +]() { + var b0 string + for range b0 {} + for _ = range b0 {} + for _, _ = range b0 {} + + var b1 B1 + for range b1 {} + for _ = range b1 {} + for _, _ = range b1 {} + + var b2 B2 + for range b2 {} + + var c0 chan int + for range c0 {} + for _ = range c0 {} + for _, _ /* ERROR permits only one iteration variable */ = range c0 {} + + var c1 C1 + for range c1 {} + for _ = range c1 {} + for _, _ /* ERROR permits only one iteration variable */ = range c1 {} + + var c2 C2 + for range c2 {} + + var c3 C3 + for range c3 /* ERROR receive from send-only channel */ {} + + var s0 []int + for range s0 {} + for _ = range s0 {} + for _, _ = range s0 {} + + var s1 S1 + for range s1 {} + for _ = range s1 {} + for _, _ = range s1 {} + + var s2 S2 + for range s2 /* ERROR cannot range over s2.*no core type */ {} + + var a0 []int + for range a0 {} + for _ = range a0 {} + for _, _ = range a0 {} + + var a1 A1 + for range a1 {} + for _ = range a1 {} + for _, _ = range a1 {} + + var a2 A2 + for range a2 /* ERROR cannot range over a2.*no core type */ {} + + var p0 *[10]int + for range p0 {} + for _ = range p0 {} + for _, _ = range p0 {} + + var p1 P1 + for range p1 {} + for _ = range p1 {} + for _, _ = range p1 {} + + var p2 P2 + for range p2 /* ERROR cannot range over p2.*no core type */ {} + + var m0 map[string]int + for range m0 {} + for _ = range m0 {} + for _, _ = range m0 {} + + var m1 M1 + for range m1 {} + for _ = range m1 {} + for _, _ = range m1 {} + + var m2 M2 + for range m2 /* ERROR cannot range over m2.*no core type */ {} +} + +// type inference checks + +var _ = new /* ERROR cannot infer T */ () + +func f4[A, B, C any](A, B) C { panic(0) } + +var _ = f4 /* ERROR cannot infer C */ (1, 2) +var _ = f4[int, float32, complex128](1, 2) + +func f5[A, B, C any](A, []*B, struct{f []C}) int { panic(0) } + +var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{}) +var _ = f5 /* ERROR cannot infer */ (0, nil, struct{f []complex128}{}) +var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{}) + +func f6[A any](A, []A) int { panic(0) } + +var _ = f6(0, nil) + +func f6nil[A any](A) int { panic(0) } + +var _ = f6nil /* ERROR cannot infer */ (nil) + +// type inference with variadic functions + +func f7[T any](...T) T { panic(0) } + +var _ int = f7 /* ERROR cannot infer T */ () +var _ int = f7(1) +var _ int = f7(1, 2) +var _ int = f7([]int{}...) +var _ int = f7 /* ERROR cannot use */ ([]float64{}...) +var _ float64 = f7([]float64{}...) +var _ = f7[float64](1, 2.3) +var _ = f7(float64(1), 2.3) +var _ = f7(1, 2.3 /* ERROR does not match */ ) +var _ = f7(1.2, 3 /* ERROR does not match */ ) + +func f8[A, B any](A, B, ...B) int { panic(0) } + +var _ = f8(1) /* ERROR not enough arguments */ +var _ = f8(1, 2.3) +var _ = f8(1, 2.3, 3.4, 4.5) +var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ ) +var _ = f8[int, float64](1, 2.3, 3.4, 4) + +var _ = f8[int, float64](0, 0, nil...) // test case for #18268 + +// init functions cannot have type parameters + +func init() {} +func init[_ /* ERROR func init must have no type parameters */ any]() {} +func init[P /* ERROR func init must have no type parameters */ any]() {} + +type T struct {} + +func (T) m1() {} +func (T) m2[ /* ERROR method must have no type parameters */ _ any]() {} +func (T) m3[ /* ERROR method must have no type parameters */ P any]() {} + +// type inference across parameterized types + +type S1[P any] struct { f P } + +func f9[P any](x S1[P]) {} + +func _() { + f9[int](S1[int]{42}) + f9(S1[int]{42}) +} + +type S2[A, B, C any] struct{} + +func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) {} + +func _[P any]() { + f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{}) + f10(S2[int, int, string]{}, S2[int, float32, bool]{}) + f10(S2[P, int, P]{}, S2[P, float32, bool]{}) +} + +// corner case for type inference +// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic) + +func f11[T any]() {} + +func _() { + f11[int]() +} + +// the previous example was extracted from + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// func f12[T interface{m() T}]() {} +// +// type A[T any] T +// +// func (a A[T]) m() A[T] +// +// func _[T any]() { +// f12[A[T]]() +// } + +// method expressions + +func (_ S1[P]) m() + +func _() { + m := S1[int].m + m(struct { f int }{42}) +} + +func _[T any] (x T) { + m := S1[T].m + m(S1[T]{x}) +} + +type I1[A any] interface { + m1(A) +} + +var _ I1[int] = r1[int]{} + +type r1[T any] struct{} + +func (_ r1[T]) m1(T) + +type I2[A, B any] interface { + m1(A) + m2(A) B +} + +var _ I2[int, float32] = R2[int, float32]{} + +type R2[P, Q any] struct{} + +func (_ R2[X, Y]) m1(X) +func (_ R2[X, Y]) m2(X) Y + +// type assertions and type switches over generic types +// NOTE: These are currently disabled because it's unclear what the correct +// approach is, and one can always work around by assigning the variable to +// an interface first. + +// // ReadByte1 corresponds to the ReadByte example in the draft design. +// func ReadByte1[T io.Reader](r T) (byte, error) { +// if br, ok := r.(io.ByteReader); ok { +// return br.ReadByte() +// } +// var b [1]byte +// _, err := r.Read(b[:]) +// return b[0], err +// } +// +// // ReadBytes2 is like ReadByte1 but uses a type switch instead. +// func ReadByte2[T io.Reader](r T) (byte, error) { +// switch br := r.(type) { +// case io.ByteReader: +// return br.ReadByte() +// } +// var b [1]byte +// _, err := r.Read(b[:]) +// return b[0], err +// } +// +// // type assertions and type switches over generic types are strict +// type I3 interface { +// m(int) +// } +// +// type I4 interface { +// m() int // different signature from I3.m +// } +// +// func _[T I3](x I3, p T) { +// // type assertions and type switches over interfaces are not strict +// _ = x.(I4) +// switch x.(type) { +// case I4: +// } +// +// // type assertions and type switches over generic types are strict +// _ = p /* ERROR cannot have dynamic type I4 */.(I4) +// switch p.(type) { +// case I4 /* ERROR cannot have dynamic type I4 */ : +// } +// } + +// type assertions and type switches over generic types lead to errors for now + +func _[T any](x T) { + _ = x /* ERROR cannot use type assertion */ .(int) + switch x /* ERROR cannot use type switch */ .(type) { + } + + // work-around + var t interface{} = x + _ = t.(int) + switch t.(type) { + } +} + +func _[T interface{~int}](x T) { + _ = x /* ERROR cannot use type assertion */ .(int) + switch x /* ERROR cannot use type switch */ .(type) { + } + + // work-around + var t interface{} = x + _ = t.(int) + switch t.(type) { + } +} + +// error messages related to type bounds mention those bounds +type C[P any] interface{} + +func _[P C[P]] (x P) { + x.m /* ERROR x.m undefined */ () +} + +type I interface {} + +func _[P I] (x P) { + x.m /* ERROR type P has no field or method m */ () +} + +func _[P interface{}] (x P) { + x.m /* ERROR type P has no field or method m */ () +} + +func _[P any] (x P) { + x.m /* ERROR type P has no field or method m */ () +} diff --git a/src/internal/types/testdata/check/unions.go b/src/internal/types/testdata/check/unions.go new file mode 100644 index 0000000..bcd7de6 --- /dev/null +++ b/src/internal/types/testdata/check/unions.go @@ -0,0 +1,66 @@ +// Copyright 2021 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. + +// Check that overlong unions don't bog down type checking. +// Disallow them for now. + +package p + +type t int + +type ( + t00 t; t01 t; t02 t; t03 t; t04 t; t05 t; t06 t; t07 t; t08 t; t09 t + t10 t; t11 t; t12 t; t13 t; t14 t; t15 t; t16 t; t17 t; t18 t; t19 t + t20 t; t21 t; t22 t; t23 t; t24 t; t25 t; t26 t; t27 t; t28 t; t29 t + t30 t; t31 t; t32 t; t33 t; t34 t; t35 t; t36 t; t37 t; t38 t; t39 t + t40 t; t41 t; t42 t; t43 t; t44 t; t45 t; t46 t; t47 t; t48 t; t49 t + t50 t; t51 t; t52 t; t53 t; t54 t; t55 t; t56 t; t57 t; t58 t; t59 t + t60 t; t61 t; t62 t; t63 t; t64 t; t65 t; t66 t; t67 t; t68 t; t69 t + t70 t; t71 t; t72 t; t73 t; t74 t; t75 t; t76 t; t77 t; t78 t; t79 t + t80 t; t81 t; t82 t; t83 t; t84 t; t85 t; t86 t; t87 t; t88 t; t89 t + t90 t; t91 t; t92 t; t93 t; t94 t; t95 t; t96 t; t97 t; t98 t; t99 t +) + +type u99 interface { + t00|t01|t02|t03|t04|t05|t06|t07|t08|t09| + t10|t11|t12|t13|t14|t15|t16|t17|t18|t19| + t20|t21|t22|t23|t24|t25|t26|t27|t28|t29| + t30|t31|t32|t33|t34|t35|t36|t37|t38|t39| + t40|t41|t42|t43|t44|t45|t46|t47|t48|t49| + t50|t51|t52|t53|t54|t55|t56|t57|t58|t59| + t60|t61|t62|t63|t64|t65|t66|t67|t68|t69| + t70|t71|t72|t73|t74|t75|t76|t77|t78|t79| + t80|t81|t82|t83|t84|t85|t86|t87|t88|t89| + t90|t91|t92|t93|t94|t95|t96|t97|t98 +} + +type u100a interface { + u99|float32 +} + +type u100b interface { + u99|float64 +} + +type u101 interface { + t00|t01|t02|t03|t04|t05|t06|t07|t08|t09| + t10|t11|t12|t13|t14|t15|t16|t17|t18|t19| + t20|t21|t22|t23|t24|t25|t26|t27|t28|t29| + t30|t31|t32|t33|t34|t35|t36|t37|t38|t39| + t40|t41|t42|t43|t44|t45|t46|t47|t48|t49| + t50|t51|t52|t53|t54|t55|t56|t57|t58|t59| + t60|t61|t62|t63|t64|t65|t66|t67|t68|t69| + t70|t71|t72|t73|t74|t75|t76|t77|t78|t79| + t80|t81|t82|t83|t84|t85|t86|t87|t88|t89| + t90|t91|t92|t93|t94|t95|t96|t97|t98|t99| + int // ERROR cannot handle more than 100 union terms +} + +type u102 interface { + int /* ERROR cannot handle more than 100 union terms */ |string|u100a +} + +type u200 interface { + u100a /* ERROR cannot handle more than 100 union terms */ |u100b +} diff --git a/src/internal/types/testdata/check/vardecl.go b/src/internal/types/testdata/check/vardecl.go new file mode 100644 index 0000000..5b68adb --- /dev/null +++ b/src/internal/types/testdata/check/vardecl.go @@ -0,0 +1,215 @@ +// Copyright 2013 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. + +package vardecl + +// Prerequisites. +import "math" +func f() {} +func g() (x, y int) { return } +var m map[string]int + +// Var decls must have a type or an initializer. +var _ int +var _, _ int + +var _; /* ERROR "expected type" */ +var _, _; /* ERROR "expected type" */ +var _, _, _; /* ERROR "expected type" */ + +// The initializer must be an expression. +var _ = int /* ERROR "not an expression" */ +var _ = f /* ERROR "used as value" */ () + +// Identifier and expression arity must match. +var _, _ = 1, 2 +var _ = 1, 2 /* ERROR "extra init expr 2" */ +var _, _ = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ +var _, _, _ /* ERROR "missing init expr for _" */ = 1, 2 + +var _ = g /* ERROR "multiple-value g" */ () +var _, _ = g() +var _, _, _ = g /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ () + +var _ = m["foo"] +var _, _ = m["foo"] +var _, _, _ = m /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ ["foo"] + +var _, _ int = 1, 2 +var _ int = 1, 2 /* ERROR "extra init expr 2" */ +var _, _ int = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ +var _, _, _ /* ERROR "missing init expr for _" */ int = 1, 2 + +var ( + _, _ = 1, 2 + _ = 1, 2 /* ERROR "extra init expr 2" */ + _, _ = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ + _, _, _ /* ERROR "missing init expr for _" */ = 1, 2 + + _ = g /* ERROR "multiple-value g" */ () + _, _ = g() + _, _, _ = g /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ () + + _ = m["foo"] + _, _ = m["foo"] + _, _, _ = m /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ ["foo"] + + _, _ int = 1, 2 + _ int = 1, 2 /* ERROR "extra init expr 2" */ + _, _ int = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ + _, _, _ /* ERROR "missing init expr for _" */ int = 1, 2 +) + +// Variables declared in function bodies must be 'used'. +type T struct{} +func (r T) _(a, b, c int) (u, v, w int) { + var x1 /* ERROR "declared and not used" */ int + var x2 /* ERROR "declared and not used" */ int + x1 = 1 + (x2) = 2 + + y1 /* ERROR "declared and not used" */ := 1 + y2 /* ERROR "declared and not used" */ := 2 + y1 = 1 + (y1) = 2 + + { + var x1 /* ERROR "declared and not used" */ int + var x2 /* ERROR "declared and not used" */ int + x1 = 1 + (x2) = 2 + + y1 /* ERROR "declared and not used" */ := 1 + y2 /* ERROR "declared and not used" */ := 2 + y1 = 1 + (y1) = 2 + } + + if x /* ERROR "declared and not used" */ := 0; a < b {} + + switch x /* ERROR "declared and not used" */, y := 0, 1; a { + case 0: + _ = y + case 1: + x /* ERROR "declared and not used" */ := 0 + } + + var t interface{} + switch t /* ERROR "declared and not used" */ := t.(type) {} + + switch t /* ERROR "declared and not used" */ := t.(type) { + case int: + } + + switch t /* ERROR "declared and not used" */ := t.(type) { + case int: + case float32, complex64: + t = nil + } + + switch t := t.(type) { + case int: + case float32, complex64: + _ = t + } + + switch t := t.(type) { + case int: + case float32: + case string: + _ = func() string { + return t + } + } + + switch t := t; t /* ERROR "declared and not used" */ := t.(type) {} + + var z1 /* ERROR "declared and not used" */ int + var z2 int + _ = func(a, b, c int) (u, v, w int) { + z1 = a + (z1) = b + a = z2 + return + } + + var s []int + var i /* ERROR "declared and not used" */ , j int + for i, j = range s { + _ = j + } + + for i, j /* ERROR "declared and not used" */ := range s { + _ = func() int { + return i + } + } + return +} + +// Unused variables in function literals must lead to only one error (issue #22524). +func _() { + _ = func() { + var x /* ERROR declared and not used */ int + } +} + +// Invalid variable declarations must not lead to "declared and not used errors". +// TODO(gri) enable these tests once go/types follows types2 logic for declared and not used variables +// func _() { +// var a x // DISABLED_ERROR undefined: x +// var b = x // DISABLED_ERROR undefined: x +// var c int = x // DISABLED_ERROR undefined: x +// var d, e, f x /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ +// var g, h, i = x, x, x /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ +// var j, k, l float32 = x, x, x /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ +// // but no "declared and not used" errors +// } + +// Invalid (unused) expressions must not lead to spurious "declared and not used errors". +func _() { + var a, b, c int + var x, y int + x, y = a /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ , b, c + _ = x + _ = y +} + +func _() { + var x int + return x /* ERROR too many return values */ + return math /* ERROR too many return values */ .Sin(0) +} + +func _() int { + var x, y int + return x, y /* ERROR too many return values */ +} + +// Short variable declarations must declare at least one new non-blank variable. +func _() { + _ := /* ERROR no new variables */ 0 + _, a := 0, 1 + _, a := /* ERROR no new variables */ 0, 1 + _, a, b := 0, 1, 2 + _, _, _ := /* ERROR no new variables */ 0, 1, 2 + + _ = a + _ = b +} + +// Test case for variables depending on function literals (see also #22992). +var A /* ERROR initialization cycle */ = func() int { return A }() + +func _() { + // The function literal below must not see a. + var a = func() int { return a /* ERROR "undefined" */ }() + var _ = func() int { return a }() + + // The function literal below must not see x, y, or z. + var x, y, z = 0, 1, func() int { return x /* ERROR "undefined" */ + y /* ERROR "undefined" */ + z /* ERROR "undefined" */ }() + _, _, _ = x, y, z +} + +// TODO(gri) consolidate other var decl checks in this file
\ No newline at end of file diff --git a/src/internal/types/testdata/examples/constraints.go b/src/internal/types/testdata/examples/constraints.go new file mode 100644 index 0000000..5b14489 --- /dev/null +++ b/src/internal/types/testdata/examples/constraints.go @@ -0,0 +1,80 @@ +// Copyright 2021 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 shows some examples of generic constraint interfaces. + +package p + +type MyInt int + +type ( + // Arbitrary types may be embedded like interfaces. + _ interface{int} + _ interface{~int} + + // Types may be combined into a union. + union interface{int|~string} + + // Union terms must describe disjoint (non-overlapping) type sets. + _ interface{int|int /* ERROR overlapping terms int */ } + _ interface{int|~ /* ERROR overlapping terms ~int */ int } + _ interface{~int|~ /* ERROR overlapping terms ~int */ int } + _ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ } + _ interface{int|any} + _ interface{int|~string|union} + _ interface{int|~string|interface{int}} + _ interface{union|int} // interfaces (here: union) are ignored when checking for overlap + _ interface{union|union} // ditto + + // For now we do not permit interfaces with methods in unions. + _ interface{~ /* ERROR invalid use of ~ */ any} + _ interface{int|interface /* ERROR cannot use .* in union */ { m() }} +) + +type ( + // Tilde is not permitted on defined types or interfaces. + foo int + bar any + _ interface{foo} + _ interface{~ /* ERROR invalid use of ~ */ foo } + _ interface{~ /* ERROR invalid use of ~ */ bar } +) + +// Stand-alone type parameters are not permitted as elements or terms in unions. +type ( + _[T interface{ *T } ] struct{} // ok + _[T interface{ int | *T } ] struct{} // ok + _[T interface{ T /* ERROR term cannot be a type parameter */ } ] struct{} + _[T interface{ ~T /* ERROR type in term ~T cannot be a type parameter */ } ] struct{} + _[T interface{ int|T /* ERROR term cannot be a type parameter */ }] struct{} +) + +// Multiple embedded union elements are intersected. The order in which they +// appear in the interface doesn't matter since intersection is a symmetric +// operation. + +type myInt1 int +type myInt2 int + +func _[T interface{ myInt1|myInt2; ~int }]() T { return T(0) } +func _[T interface{ ~int; myInt1|myInt2 }]() T { return T(0) } + +// Here the intersections are empty - there's no type that's in the type set of T. +func _[T interface{ myInt1|myInt2; int }]() T { return T(0 /* ERROR cannot convert */ ) } +func _[T interface{ int; myInt1|myInt2 }]() T { return T(0 /* ERROR cannot convert */ ) } + +// Union elements may be interfaces as long as they don't define +// any methods or embed comparable. + +type ( + Integer interface{ ~int|~int8|~int16|~int32|~int64 } + Unsigned interface{ ~uint|~uint8|~uint16|~uint32|~uint64 } + Floats interface{ ~float32|~float64 } + Complex interface{ ~complex64|~complex128 } + Number interface{ Integer|Unsigned|Floats|Complex } + Ordered interface{ Integer|Unsigned|Floats|~string } + + _ interface{ Number | error /* ERROR cannot use error in union */ } + _ interface{ Ordered | comparable /* ERROR cannot use comparable in union */ } +) diff --git a/src/internal/types/testdata/examples/functions.go b/src/internal/types/testdata/examples/functions.go new file mode 100644 index 0000000..47e1c35 --- /dev/null +++ b/src/internal/types/testdata/examples/functions.go @@ -0,0 +1,219 @@ +// Copyright 2019 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 shows some examples of type-parameterized functions. + +package p + +// Reverse is a generic function that takes a []T argument and +// reverses that slice in place. +func Reverse[T any](list []T) { + i := 0 + j := len(list)-1 + for i < j { + list[i], list[j] = list[j], list[i] + i++ + j-- + } +} + +func _() { + // Reverse can be called with an explicit type argument. + Reverse[int](nil) + Reverse[string]([]string{"foo", "bar"}) + Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}}) + + // Since the type parameter is used for an incoming argument, + // it can be inferred from the provided argument's type. + Reverse([]string{"foo", "bar"}) + Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}}) + + // But the incoming argument must have a type, even if it's a + // default type. An untyped nil won't work. + // Reverse(nil) // this won't type-check + + // A typed nil will work, though. + Reverse([]int(nil)) +} + +// Certain functions, such as the built-in `new` could be written using +// type parameters. +func new[T any]() *T { + var x T + return &x +} + +// When calling our own `new`, we need to pass the type parameter +// explicitly since there is no (value) argument from which the +// result type could be inferred. We don't try to infer the +// result type from the assignment to keep things simple and +// easy to understand. +var _ = new[int]() +var _ *float64 = new[float64]() // the result type is indeed *float64 + +// A function may have multiple type parameters, of course. +func foo[A, B, C any](a A, b []B, c *C) B { + // do something here + return b[0] +} + +// As before, we can pass type parameters explicitly. +var s = foo[int, string, float64](1, []string{"first"}, new[float64]()) + +// Or we can use type inference. +var _ float64 = foo(42, []float64{1.0}, &s) + +// Type inference works in a straight-forward manner even +// for variadic functions. +func variadic[A, B any](A, B, ...B) int { panic(0) } + +// var _ = variadic(1) // ERROR not enough arguments +var _ = variadic(1, 2.3) +var _ = variadic(1, 2.3, 3.4, 4.5) +var _ = variadic[int, float64](1, 2.3, 3.4, 4) + +// Type inference also works in recursive function calls where +// the inferred type is the type parameter of the caller. +func f1[T any](x T) { + f1(x) +} + +func f2a[T any](x, y T) { + f2a(x, y) +} + +func f2b[T any](x, y T) { + f2b(y, x) +} + +func g2a[P, Q any](x P, y Q) { + g2a(x, y) +} + +func g2b[P, Q any](x P, y Q) { + g2b(y, x) +} + +// Here's an example of a recursive function call with variadic +// arguments and type inference inferring the type parameter of +// the caller (i.e., itself). +func max[T interface{ ~int }](x ...T) T { + var x0 T + if len(x) > 0 { + x0 = x[0] + } + if len(x) > 1 { + x1 := max(x[1:]...) + if x1 > x0 { + return x1 + } + } + return x0 +} + +// When inferring channel types, the channel direction is ignored +// for the purpose of type inference. Once the type has been in- +// fered, the usual parameter passing rules are applied. +// Thus even if a type can be inferred successfully, the function +// call may not be valid. + +func fboth[T any](chan T) {} +func frecv[T any](<-chan T) {} +func fsend[T any](chan<- T) {} + +func _() { + var both chan int + var recv <-chan int + var send chan<-int + + fboth(both) + fboth(recv /* ERROR cannot use */ ) + fboth(send /* ERROR cannot use */ ) + + frecv(both) + frecv(recv) + frecv(send /* ERROR cannot use */ ) + + fsend(both) + fsend(recv /* ERROR cannot use */) + fsend(send) +} + +func ffboth[T any](func(chan T)) {} +func ffrecv[T any](func(<-chan T)) {} +func ffsend[T any](func(chan<- T)) {} + +func _() { + var both func(chan int) + var recv func(<-chan int) + var send func(chan<- int) + + ffboth(both) + ffboth(recv /* ERROR cannot use */ ) + ffboth(send /* ERROR cannot use */ ) + + ffrecv(both /* ERROR cannot use */ ) + ffrecv(recv) + ffrecv(send /* ERROR cannot use */ ) + + ffsend(both /* ERROR cannot use */ ) + ffsend(recv /* ERROR cannot use */ ) + ffsend(send) +} + +// When inferring elements of unnamed composite parameter types, +// if the arguments are defined types, use their underlying types. +// Even though the matching types are not exactly structurally the +// same (one is a type literal, the other a named type), because +// assignment is permitted, parameter passing is permitted as well, +// so type inference should be able to handle these cases well. + +func g1[T any]([]T) {} +func g2[T any]([]T, T) {} +func g3[T any](*T, ...T) {} + +func _() { + type intSlize []int + g1([]int{}) + g1(intSlize{}) + g2(nil, 0) + + type myString string + var s1 string + g3(nil, "1", myString("2"), "3") + g3(& /* ERROR does not match */ s1, "1", myString("2"), "3") + _ = s1 + + type myStruct struct{x int} + var s2 myStruct + g3(nil, struct{x int}{}, myStruct{}) + g3(&s2, struct{x int}{}, myStruct{}) + g3(nil, myStruct{}, struct{x int}{}) + g3(&s2, myStruct{}, struct{x int}{}) +} + +// Here's a realistic example. + +func append[T any](s []T, t ...T) []T { panic(0) } + +func _() { + var f func() + type Funcs []func() + var funcs Funcs + _ = append(funcs, f) +} + +// Generic type declarations cannot have empty type parameter lists +// (that would indicate a slice type). Thus, generic functions cannot +// have empty type parameter lists, either. This is a syntax error. + +func h[] /* ERROR empty type parameter list */ () {} + +func _() { + h /* ERROR cannot index */ [] /* ERROR operand */ () +} + +// Generic functions must have a function body. + +func _ /* ERROR generic function is missing function body */ [P any]() diff --git a/src/internal/types/testdata/examples/inference.go b/src/internal/types/testdata/examples/inference.go new file mode 100644 index 0000000..073df9c --- /dev/null +++ b/src/internal/types/testdata/examples/inference.go @@ -0,0 +1,116 @@ +// Copyright 2021 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 shows some examples of type inference. + +package p + +type Ordered interface { + ~int | ~float64 | ~string +} + +func min[T Ordered](x, y T) T { panic(0) } + +func _() { + // min can be called with explicit instantiation. + _ = min[int](1, 2) + + // Alternatively, the type argument can be inferred from + // one of the arguments. Untyped arguments will be considered + // last. + var x int + _ = min(x, x) + _ = min(x, 1) + _ = min(x, 1.0) + _ = min(1, 2) + _ = min(1, 2.3 /* ERROR default type float64 .* does not match */) + + var y float64 + _ = min(1, y) + _ = min(1.2, y) + _ = min(1.2, 3.4) + _ = min(1.2, 3 /* ERROR default type int .* does not match */) + + var s string + _ = min(s, "foo") + _ = min("foo", "bar") +} + +func mixed[T1, T2, T3 any](T1, T2, T3) {} + +func _() { + // mixed can be called with explicit instantiation. + mixed[int, string, bool](0, "", false) + + // Alternatively, partial type arguments may be provided + // (from left to right), and the other may be inferred. + mixed[int, string](0, "", false) + mixed[int](0, "", false) + mixed(0, "", false) + + // Provided type arguments always take precedence over + // inferred types. + mixed[int, string](1.1 /* ERROR cannot use 1.1 */, "", false) +} + +func related1[Slice interface{ ~[]Elem }, Elem any](s Slice, e Elem) {} + +func _() { + // related1 can be called with explicit instantiation. + var si []int + related1[[]int, int](si, 0) + + // Alternatively, the 2nd type argument can be inferred + // from the first one through constraint type inference. + var ss []string + _ = related1[[]string] + related1[[]string](ss, "foo") + + // A type argument inferred from another explicitly provided + // type argument overrides whatever value argument type is given. + related1[[]string](ss, 0 /* ERROR cannot use 0 */) + + // A type argument may be inferred from a value argument + // and then help infer another type argument via constraint + // type inference. + related1(si, 0) + related1(si, "foo" /* ERROR cannot use "foo" */) +} + +func related2[Elem any, Slice interface{ []Elem }](e Elem, s Slice) {} + +func _() { + // related2 can be called with explicit instantiation. + var si []int + related2[int, []int](0, si) + + // Alternatively, the 2nd type argument can be inferred + // from the first one through constraint type inference. + var ss []string + _ = related2[string] + related2[string]("foo", ss) + + // A type argument may be inferred from a value argument + // and then help infer another type argument via constraint + // type inference. Untyped arguments are always considered + // last. + related2(1.2, []float64{}) + related2(1.0, []int{}) + related2 /* ERROR does not satisfy */ (float64(1.0), []int{}) // TODO(gri) fix error position +} + +type List[P any] []P + +func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil } + +func _() { + // related3 can be instantiated explicitly + related3[int, []int]() + related3[byte, List[byte]]() + + // The 2nd type argument cannot be inferred from the first + // one because there's two possible choices: []Elem and + // List[Elem]. + related3 /* ERROR cannot infer Slice */ [int]() +} diff --git a/src/internal/types/testdata/examples/methods.go b/src/internal/types/testdata/examples/methods.go new file mode 100644 index 0000000..a46f789 --- /dev/null +++ b/src/internal/types/testdata/examples/methods.go @@ -0,0 +1,112 @@ +// Copyright 2019 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 shows some examples of methods on type-parameterized types. + +package p + +// Parameterized types may have methods. +type T1[A any] struct{ a A } + +// When declaring a method for a parameterized type, the "instantiated" +// receiver type acts as an implicit declaration of the type parameters +// for the receiver type. In the example below, method m1 on type T1 has +// the receiver type T1[A] which declares the type parameter A for use +// with this method. That is, within the method m1, A stands for the +// actual type argument provided to an instantiated T1. +func (t T1[A]) m1() A { return t.a } + +// For instance, if T1 is instantiated with the type int, the type +// parameter A in m1 assumes that type (int) as well and we can write +// code like this: +var x T1[int] +var _ int = x.m1() + +// Because the type parameter provided to a parameterized receiver type +// is declared through that receiver declaration, it must be an identifier. +// It cannot possibly be some other type because the receiver type is not +// instantiated with concrete types, it is standing for the parameterized +// receiver type. +func (t T1[[ /* ERROR must be an identifier */ ]int]) m2() {} + +// Note that using what looks like a predeclared identifier, say int, +// as type parameter in this situation is deceptive and considered bad +// style. In m3 below, int is the name of the local receiver type parameter +// and it shadows the predeclared identifier int which then cannot be used +// anymore as expected. +// This is no different from locally re-declaring a predeclared identifier +// and usually should be avoided. There are some notable exceptions; e.g., +// sometimes it makes sense to use the identifier "copy" which happens to +// also be the name of a predeclared built-in function. +func (t T1[int]) m3() { var _ int = 42 /* ERROR cannot use 42 .* as int */ } + +// The names of the type parameters used in a parameterized receiver +// type don't have to match the type parameter names in the declaration +// of the type used for the receiver. In our example, even though T1 is +// declared with type parameter named A, methods using that receiver type +// are free to use their own name for that type parameter. That is, the +// name of type parameters is always local to the declaration where they +// are introduced. In our example we can write a method m2 and use the +// name X instead of A for the type parameter w/o any difference. +func (t T1[X]) m4() X { return t.a } + +// If the receiver type is parameterized, type parameters must always be +// provided: this simply follows from the general rule that a parameterized +// type must be instantiated before it can be used. A method receiver +// declaration using a parameterized receiver type is no exception. It is +// simply that such receiver type expressions perform two tasks simultaneously: +// they declare the (local) type parameters and then use them to instantiate +// the receiver type. Forgetting to provide a type parameter leads to an error. +func (t T1 /* ERROR generic type .* without instantiation */ ) m5() {} + +// However, sometimes we don't need the type parameter, and thus it is +// inconvenient to have to choose a name. Since the receiver type expression +// serves as a declaration for its type parameters, we are free to choose the +// blank identifier: +func (t T1[_]) m6() {} + +// Naturally, these rules apply to any number of type parameters on the receiver +// type. Here are some more complex examples. +type T2[A, B, C any] struct { + a A + b B + c C +} + +// Naming of the type parameters is local and has no semantic impact: +func (t T2[A, B, C]) m1() (A, B, C) { return t.a, t.b, t.c } +func (t T2[C, B, A]) m2() (C, B, A) { return t.a, t.b, t.c } +func (t T2[X, Y, Z]) m3() (X, Y, Z) { return t.a, t.b, t.c } + +// Type parameters may be left blank if they are not needed: +func (t T2[A, _, C]) m4() (A, C) { return t.a, t.c } +func (t T2[_, _, X]) m5() X { return t.c } +func (t T2[_, _, _]) m6() {} + +// As usual, blank names may be used for any object which we don't care about +// using later. For instance, we may write an unnamed method with a receiver +// that cannot be accessed: +func (_ T2[_, _, _]) _() int { return 42 } + +// Because a receiver parameter list is simply a parameter list, we can +// leave the receiver argument away for receiver types. +type T0 struct{} +func (T0) _() {} +func (T1[A]) _() {} + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// // A generic receiver type may constrain its type parameter such +// // that it must be a pointer type. Such receiver types are not +// // permitted. +// type T3a[P interface{ ~int | ~string | ~float64 }] P +// +// func (T3a[_]) m() {} // this is ok +// +// type T3b[P interface{ ~unsafe.Pointer }] P +// +// func (T3b /* ERROR invalid receiver */ [_]) m() {} +// +// type T3c[P interface{ *int | *string }] P +// +// func (T3c /* ERROR invalid receiver */ [_]) m() {} diff --git a/src/internal/types/testdata/examples/operations.go b/src/internal/types/testdata/examples/operations.go new file mode 100644 index 0000000..18e4d60 --- /dev/null +++ b/src/internal/types/testdata/examples/operations.go @@ -0,0 +1,29 @@ +// Copyright 2021 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. + +package p + +// indirection + +func _[P any](p P) { + _ = *p // ERROR cannot indirect p +} + +func _[P interface{ int }](p P) { + _ = *p // ERROR cannot indirect p +} + +func _[P interface{ *int }](p P) { + _ = *p +} + +func _[P interface{ *int | *string }](p P) { + _ = *p // ERROR must have identical base types +} + +type intPtr *int + +func _[P interface{ *int | intPtr } ](p P) { + var _ int = *p +} diff --git a/src/internal/types/testdata/examples/types.go b/src/internal/types/testdata/examples/types.go new file mode 100644 index 0000000..052d168 --- /dev/null +++ b/src/internal/types/testdata/examples/types.go @@ -0,0 +1,315 @@ +// Copyright 2019 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 shows some examples of generic types. + +package p + +// List is just what it says - a slice of E elements. +type List[E any] []E + +// A generic (parameterized) type must always be instantiated +// before it can be used to designate the type of a variable +// (including a struct field, or function parameter); though +// for the latter cases, the provided type may be another type +// parameter. So: +var _ List[byte] = []byte{} + +// A generic binary tree might be declared as follows. +type Tree[E any] struct { + left, right *Tree[E] + payload E +} + +// A simple instantiation of Tree: +var root1 Tree[int] + +// The actual type parameter provided may be a generic type itself: +var root2 Tree[List[int]] + +// A couple of more complex examples. +// We don't need extra parentheses around the element type of the slices on +// the right (unlike when we use ()'s rather than []'s for type parameters). +var _ List[List[int]] = []List[int]{} +var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{} + +// Type parameters act like type aliases when used in generic types +// in the sense that we can "emulate" a specific type instantiation +// with type aliases. +type T1[P any] struct { + f P +} + +type T2[P any] struct { + f struct { + g P + } +} + +var x1 T1[struct{ g int }] +var x2 T2[int] + +func _() { + // This assignment is invalid because the types of x1, x2 are T1(...) + // and T2(...) respectively, which are two different defined types. + x1 = x2 // ERROR assignment + + // This assignment is valid because the types of x1.f and x2.f are + // both struct { g int }; the type parameters act like type aliases + // and their actual names don't come into play here. + x1.f = x2.f +} + +// We can verify this behavior using type aliases instead: +type T1a struct { + f A1 +} +type A1 = struct { g int } + +type T2a struct { + f struct { + g A2 + } +} +type A2 = int + +var x1a T1a +var x2a T2a + +func _() { + x1a = x2a // ERROR assignment + x1a.f = x2a.f +} + +// Another interesting corner case are generic types that don't use +// their type arguments. For instance: +type T[P any] struct{} + +var xint T[int] +var xbool T[bool] + +// Are these two variables of the same type? After all, their underlying +// types are identical. We consider them to be different because each type +// instantiation creates a new named type, in this case T<int> and T<bool> +// even if their underlying types are identical. This is sensible because +// we might still have methods that have different signatures or behave +// differently depending on the type arguments, and thus we can't possibly +// consider such types identical. Consequently: +func _() { + xint = xbool // ERROR assignment +} + +// Generic types cannot be used without instantiation. +var _ T // ERROR cannot use generic type T +var _ = T /* ERROR cannot use generic type T */ (0) + +// In type context, generic (parameterized) types cannot be parenthesized before +// being instantiated. See also NOTES entry from 12/4/2019. +var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR unexpected \[|expected ';' */ int] + +// All types may be parameterized, including interfaces. +type I1[T any] interface{ + m1(T) +} + +// There is no such thing as a variadic generic type. +type _[T ... /* ERROR invalid use of ... */ any] struct{} + +// Generic interfaces may be embedded as one would expect. +type I2 interface { + I1(int) // method! + I1[string] // embedded I1 +} + +func _() { + var x I2 + x.I1(0) + x.m1("foo") +} + +type I0 interface { + m0() +} + +type I3 interface { + I0 + I1[bool] + m(string) +} + +func _() { + var x I3 + x.m0() + x.m1(true) + x.m("foo") +} + +type _ struct { + ( /* ERROR cannot parenthesize */ int8) + ( /* ERROR cannot parenthesize */ *int16) + *( /* ERROR cannot parenthesize */ int32) + List[int] + + int8 /* ERROR int8 redeclared */ + * /* ERROR int16 redeclared */ int16 + List /* ERROR List redeclared */ [int] +} + +// Issue #45639: We don't allow this anymore. Keep this code +// in case we decide to revisit this decision. +// +// It's possible to declare local types whose underlying types +// are type parameters. As with ordinary type definitions, the +// types underlying properties are "inherited" but the methods +// are not. +// func _[T interface{ m(); ~int }]() { +// type L T +// var x L +// +// // m is not defined on L (it is not "inherited" from +// // its underlying type). +// x.m /* ERROR x.m undefined */ () +// +// // But the properties of T, such that as that it supports +// // the operations of the types given by its type bound, +// // are also the properties of L. +// x++ +// _ = x - x +// +// // On the other hand, if we define a local alias for T, +// // that alias stands for T as expected. +// type A = T +// var y A +// y.m() +// _ = y < 0 +// } + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// // It is not permitted to declare a local type whose underlying +// // type is a type parameter not declared by that type declaration. +// func _[T any]() { +// type _ T // ERROR cannot use function type parameter T as RHS in type declaration +// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration +// } + +// As a special case, an explicit type argument may be omitted +// from a type parameter bound if the type bound expects exactly +// one type argument. In that case, the type argument is the +// respective type parameter to which the type bound applies. +// Note: We may not permit this syntactic sugar at first. +// Note: This is now disabled. All examples below are adjusted. +type Adder[T any] interface { + Add(T) T +} + +// We don't need to explicitly instantiate the Adder bound +// if we have exactly one type parameter. +func Sum[T Adder[T]](list []T) T { + var sum T + for _, x := range list { + sum = sum.Add(x) + } + return sum +} + +// Valid and invalid variations. +type B0 any +type B1[_ any] any +type B2[_, _ any] any + +func _[T1 B0]() {} +func _[T1 B1[T1]]() {} +func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {} + +func _[T1, T2 B0]() {} +func _[T1 B1[T1], T2 B1[T2]]() {} +func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {} + +func _[T1 B0, T2 B1[T2]]() {} // here B1 applies to T2 + +// When the type argument is left away, the type bound is +// instantiated for each type parameter with that type +// parameter. +// Note: We may not permit this syntactic sugar at first. +func _[A Adder[A], B Adder[B], C Adder[A]]() { + var a A // A's type bound is Adder[A] + a = a.Add(a) + var b B // B's type bound is Adder[B] + b = b.Add(b) + var c C // C's type bound is Adder[A] + a = c.Add(a) +} + +// The type of variables (incl. parameters and return values) cannot +// be an interface with type constraints or be/embed comparable. +type I interface { + ~int +} + +var ( + _ interface /* ERROR contains type constraints */ {~int} + _ I /* ERROR contains type constraints */ +) + +func _(I /* ERROR contains type constraints */ ) +func _(x, y, z I /* ERROR contains type constraints */ ) +func _() I /* ERROR contains type constraints */ + +func _() { + var _ I /* ERROR contains type constraints */ +} + +type C interface { + comparable +} + +var _ comparable /* ERROR comparable */ +var _ C /* ERROR comparable */ + +func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ ) + +func _() { + var _ comparable /* ERROR comparable */ + var _ C /* ERROR comparable */ +} + +// Type parameters are never const types, i.e., it's +// not possible to declare a constant of type parameter type. +// (If a type set contains just a single const type, we could +// allow it, but such type sets don't make much sense in the +// first place.) +func _[T interface{~int|~float64}]() { + // not valid + const _ = T /* ERROR not constant */ (0) + const _ T /* ERROR invalid constant type T */ = 1 + + // valid + var _ = T(0) + var _ T = 1 + _ = T(0) +} + +// It is possible to create composite literals of type parameter +// type as long as it's possible to create a composite literal +// of the core type of the type parameter's constraint. +func _[P interface{ ~[]int }]() P { + return P{} + return P{1, 2, 3} +} + +func _[P interface{ ~[]E }, E interface{ map[string]P } ]() P { + x := P{} + return P{{}} + return P{E{}} + return P{E{"foo": x}} + return P{{"foo": x}, {}} +} + +// This is a degenerate case with a singleton type set, but we can create +// composite literals even if the core type is a defined type. +type MyInts []int + +func _[P MyInts]() P { + return P{} +} diff --git a/src/internal/types/testdata/examples/typesets.go b/src/internal/types/testdata/examples/typesets.go new file mode 100644 index 0000000..a50beb9 --- /dev/null +++ b/src/internal/types/testdata/examples/typesets.go @@ -0,0 +1,59 @@ +// Copyright 2021 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 shows some examples of constraint literals with elided interfaces. +// These examples are permitted if proposal issue #48424 is accepted. + +package p + +// Constraint type sets of the form T, ~T, or A|B may omit the interface. +type ( + _[T int] struct{} + _[T ~int] struct{} + _[T int | string] struct{} + _[T ~int | ~string] struct{} +) + +func min[T int | string](x, y T) T { + if x < y { + return x + } + return y +} + +func lookup[M ~map[K]V, K comparable, V any](m M, k K) V { + return m[k] +} + +func deref[P ~*E, E any](p P) E { + return *p +} + +func _() int { + p := new(int) + return deref(p) +} + +func addrOfCopy[V any, P *V](v V) P { + return &v +} + +func _() *int { + return addrOfCopy(0) +} + +// A type parameter may not be embedded in an interface; +// so it can also not be used as a constraint. +func _[A any, B A /* ERROR cannot use a type parameter as constraint */]() {} +func _[A any, B, C A /* ERROR cannot use a type parameter as constraint */]() {} + +// Error messages refer to the type constraint as it appears in the source. +// (No implicit interface should be exposed.) +func _[T string](x T) T { + return x /* ERROR constrained by string */ * x +} + +func _[T int | string](x T) T { + return x /* ERROR constrained by int|string */ * x +} diff --git a/src/internal/types/testdata/fixedbugs/54942.go b/src/internal/types/testdata/fixedbugs/54942.go new file mode 100644 index 0000000..f2e733b --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/54942.go @@ -0,0 +1,38 @@ +// Copyright 2022 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. + +package p + +import ( + "context" + "database/sql" +) + +type I interface { + m(int, int, *int, int) +} + +type T struct{} + +func (_ *T) m(a, b, c, d int) {} + +var _ I = new /* ERROR have m\(int, int, int, int\)\n\t\twant m\(int, int, \*int, int\) */ (T) + +// (slightly modified) test case from issue + +type Result struct { + Value string +} + +type Executor interface { + Execute(context.Context, sql.Stmt, int, []sql.NamedArg, int) (Result, error) +} + +type myExecutor struct{} + +func (_ *myExecutor) Execute(ctx context.Context, stmt sql.Stmt, maxrows int, args []sql.NamedArg, urgency int) (*Result, error) { + return &Result{}, nil +} + +var ex Executor = new /* ERROR have Execute\(context\.Context, sql\.Stmt, int, \[\]sql\.NamedArg, int\) \(\*Result, error\)\n\t\twant Execute\(context\.Context, sql\.Stmt, int, \[\]sql\.NamedArg, int\) \(Result, error\) */ (myExecutor) diff --git a/src/internal/types/testdata/fixedbugs/issue20583.go b/src/internal/types/testdata/fixedbugs/issue20583.go new file mode 100644 index 0000000..d26dbad --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue20583.go @@ -0,0 +1,14 @@ +// 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. + +package issue20583 + +const ( + _ = 6e886451608 /* ERROR malformed constant */ /2 + _ = 6e886451608i /* ERROR malformed constant */ /2 + _ = 0 * 1e+1000000000 // ERROR malformed constant + + x = 1e100000000 + _ = x*x*x*x*x*x* /* ERROR not representable */ x +) diff --git a/src/internal/types/testdata/fixedbugs/issue23203a.go b/src/internal/types/testdata/fixedbugs/issue23203a.go new file mode 100644 index 0000000..48cb588 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue23203a.go @@ -0,0 +1,14 @@ +// Copyright 2018 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. + +package main + +import "unsafe" + +type T struct{} + +func (T) m1() {} +func (T) m2([unsafe.Sizeof(T.m1)]int) {} + +func main() {} diff --git a/src/internal/types/testdata/fixedbugs/issue23203b.go b/src/internal/types/testdata/fixedbugs/issue23203b.go new file mode 100644 index 0000000..638ec6c --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue23203b.go @@ -0,0 +1,14 @@ +// Copyright 2018 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. + +package main + +import "unsafe" + +type T struct{} + +func (T) m2([unsafe.Sizeof(T.m1)]int) {} +func (T) m1() {} + +func main() {} diff --git a/src/internal/types/testdata/fixedbugs/issue25838.go b/src/internal/types/testdata/fixedbugs/issue25838.go new file mode 100644 index 0000000..adbd138 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue25838.go @@ -0,0 +1,26 @@ +// Copyright 2022 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. + +package p + +// examples from the issue + +type ( + e = f + f = g + g = []h + h i + i = j + j = e +) + +type ( + e1 = []h1 + h1 e1 +) + +type ( + P = *T + T P +) diff --git a/src/internal/types/testdata/fixedbugs/issue26390.go b/src/internal/types/testdata/fixedbugs/issue26390.go new file mode 100644 index 0000000..9e0101f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue26390.go @@ -0,0 +1,13 @@ +// Copyright 2018 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. + +// stand-alone test to ensure case is triggered + +package issue26390 + +type A = T + +func (t *T) m() *A { return t } + +type T struct{} diff --git a/src/internal/types/testdata/fixedbugs/issue28251.go b/src/internal/types/testdata/fixedbugs/issue28251.go new file mode 100644 index 0000000..ef5e61d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue28251.go @@ -0,0 +1,65 @@ +// Copyright 2018 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 contains test cases for various forms of +// method receiver declarations, per the spec clarification +// https://golang.org/cl/142757. + +package issue28251 + +// test case from issue28251 +type T struct{} + +type T0 = *T + +func (T0) m() {} + +func _() { (&T{}).m() } + +// various alternative forms +type ( + T1 = (((T))) +) + +func ((*(T1))) m1() {} +func _() { (T{}).m2() } +func _() { (&T{}).m2() } + +type ( + T2 = (((T3))) + T3 = T +) + +func (T2) m2() {} +func _() { (T{}).m2() } +func _() { (&T{}).m2() } + +type ( + T4 = ((*(T5))) + T5 = T +) + +func (T4) m4() {} +func _() { (T{}).m4 /* ERROR "cannot call pointer method m4 on T" */ () } +func _() { (&T{}).m4() } + +type ( + T6 = (((T7))) + T7 = (*(T8)) + T8 = T +) + +func (T6) m6() {} +func _() { (T{}).m6 /* ERROR "cannot call pointer method m6 on T" */ () } +func _() { (&T{}).m6() } + +type ( + T9 = *T10 + T10 = *T11 + T11 = T +) + +func (T9 /* ERROR invalid receiver type \*\*T */ ) m9() {} +func _() { (T{}).m9 /* ERROR has no field or method m9 */ () } +func _() { (&T{}).m9 /* ERROR has no field or method m9 */ () } diff --git a/src/internal/types/testdata/fixedbugs/issue39634.go b/src/internal/types/testdata/fixedbugs/issue39634.go new file mode 100644 index 0000000..6ee1548 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39634.go @@ -0,0 +1,90 @@ +// 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. + +// Examples adjusted to match new [T any] syntax for type parameters. +// Also, previously permitted empty type parameter lists and instantiations +// are now syntax errors. + +package p + +// crash 1 +type nt1[_ any]interface{g /* ERROR undefined */ } +type ph1[e nt1[e],g(d /* ERROR undefined */ )]s /* ERROR undefined */ +func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undefined */ ) + +// crash 2 +// Disabled: empty []'s are now syntax errors. This example leads to too many follow-on errors. +// type Numeric2 interface{t2 /* ERROR not a type */ } +// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}} + +// crash 3 +type t3 *interface{ t3.p /* ERROR t3.p is not a type */ } + +// crash 4 +type Numeric4 interface{t4 /* ERROR not a type */ } +func t4[T Numeric4](s[]T){if( /* ERROR non-boolean */ 0){*s /* ERROR cannot indirect */ [0]}} + +// crash 7 +type foo7 interface { bar() } +type x7[A any] struct{ foo7 } +func main7() { var _ foo7 = x7[int]{} } + +// crash 8 +type foo8[A any] interface { ~A /* ERROR cannot be a type parameter */ } +func bar8[A foo8[A]](a A) {} + +// crash 9 +type foo9[A any] interface { foo9 /* ERROR invalid recursive type */ [A] } +func _() { var _ = new(foo9[int]) } + +// crash 12 +var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undefined */ /* ERROR undefined */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undefined */ /* ERROR undefined */ + +// crash 15 +func y15() { var a /* ERROR declared and not used */ interface{ p() } = G15[string]{} } +type G15[X any] s /* ERROR undefined */ +func (G15 /* ERROR generic type .* without instantiation */ ) p() + +// crash 16 +type Foo16[T any] r16 /* ERROR not a type */ +func r16[T any]() Foo16[Foo16[T]] { panic(0) } + +// crash 17 +type Y17 interface{ c() } +type Z17 interface { + c() Y17 + Y17 /* ERROR duplicate method */ +} +func F17[T Z17](T) {} + +// crash 18 +type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ]) + +// crash 19 +type Z19 [][[]Z19{}[0][0]]c19 /* ERROR undefined */ + +// crash 20 +type Z20 /* ERROR invalid recursive type */ interface{ Z20 } +func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) } + +// crash 21 +type Z21 /* ERROR invalid recursive type */ interface{ Z21 } +func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) } + +// crash 24 +type T24[P any] P // ERROR cannot use a type parameter as RHS in type declaration +func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() } + +// crash 25 +type T25[A any] int +func (t T25[A]) m1() {} +var x T25 /* ERROR without instantiation */ .m1 + +// crash 26 +type T26 = interface{ F26[ /* ERROR interface method must have no type parameters */ Z any]() } +func F26[Z any]() T26 { return F26[] /* ERROR operand */ } + +// crash 27 +func e27[T any]() interface{ x27 /* ERROR not a type */ } { panic(0) } +func x27() { e27 /* ERROR cannot infer T */ () } diff --git a/src/internal/types/testdata/fixedbugs/issue39664.go b/src/internal/types/testdata/fixedbugs/issue39664.go new file mode 100644 index 0000000..3b3ec56 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39664.go @@ -0,0 +1,15 @@ +// 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. + +package p + +type T[_ any] struct {} + +func (T /* ERROR instantiation */ ) m() + +func _() { + var x interface { m() } + x = T[int]{} + _ = x +} diff --git a/src/internal/types/testdata/fixedbugs/issue39680.go b/src/internal/types/testdata/fixedbugs/issue39680.go new file mode 100644 index 0000000..e56bc35 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39680.go @@ -0,0 +1,31 @@ +// 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. + +package p + +// Embedding stand-alone type parameters is not permitted for now. Disabled. + +/* +import "fmt" + +// Minimal test case. +func _[T interface{~T}](x T) T{ + return x +} + +// Test case from issue. +type constr[T any] interface { + ~T +} + +func Print[T constr[T]](s []T) { + for _, v := range s { + fmt.Print(v) + } +} + +func f() { + Print([]string{"Hello, ", "playground\n"}) +} +*/ diff --git a/src/internal/types/testdata/fixedbugs/issue39693.go b/src/internal/types/testdata/fixedbugs/issue39693.go new file mode 100644 index 0000000..496754d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39693.go @@ -0,0 +1,23 @@ +// 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. + +package p + +type Number1 interface { + // embedding non-interface types is permitted + int + float64 +} + +func Add1[T Number1](a, b T) T { + return a /* ERROR not defined */ + b +} + +type Number2 interface { + int | float64 +} + +func Add2[T Number2](a, b T) T { + return a + b +} diff --git a/src/internal/types/testdata/fixedbugs/issue39699.go b/src/internal/types/testdata/fixedbugs/issue39699.go new file mode 100644 index 0000000..72f8399 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39699.go @@ -0,0 +1,29 @@ +// 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. + +package p + +type T0 interface{ +} + +type T1 interface{ + ~int +} + +type T2 interface{ + comparable +} + +type T3 interface { + T0 + T1 + T2 +} + +func _() { + _ = T0(0) + _ = T1 /* ERROR cannot use interface T1 in conversion */ (1) + _ = T2 /* ERROR cannot use interface T2 in conversion */ (2) + _ = T3 /* ERROR cannot use interface T3 in conversion */ (3) +} diff --git a/src/internal/types/testdata/fixedbugs/issue39711.go b/src/internal/types/testdata/fixedbugs/issue39711.go new file mode 100644 index 0000000..d85fa03 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39711.go @@ -0,0 +1,13 @@ +// 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. + +package p + +// Do not report a duplicate type error for this term list. +// (Check types after interfaces have been completed.) +type _ interface { + // TODO(rfindley) Once we have full type sets we can enable this again. + // Fow now we don't permit interfaces in term lists. + // type interface{ Error() string }, interface{ String() string } +} diff --git a/src/internal/types/testdata/fixedbugs/issue39723.go b/src/internal/types/testdata/fixedbugs/issue39723.go new file mode 100644 index 0000000..0088523 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39723.go @@ -0,0 +1,9 @@ +// 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. + +package p + +// A constraint must be an interface; it cannot +// be a type parameter, for instance. +func _[A interface{ ~int }, B A /* ERROR cannot use a type parameter as constraint */ ]() {} diff --git a/src/internal/types/testdata/fixedbugs/issue39725.go b/src/internal/types/testdata/fixedbugs/issue39725.go new file mode 100644 index 0000000..62dc45a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39725.go @@ -0,0 +1,16 @@ +// 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. + +package p + +func f1[T1, T2 any](T1, T2, struct{a T1; b T2}) {} +func _() { + f1(42, string("foo"), struct /* ERROR does not match inferred type struct\{a int; b string\} */ {a, b int}{}) +} + +// simplified test case from issue +func f2[T any](_ []T, _ func(T)) {} +func _() { + f2([]string{}, func /* ERROR does not match inferred type func\(string\) */ (f []byte) {}) +} diff --git a/src/internal/types/testdata/fixedbugs/issue39754.go b/src/internal/types/testdata/fixedbugs/issue39754.go new file mode 100644 index 0000000..97365e2 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39754.go @@ -0,0 +1,21 @@ +// 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.
+
+package p
+
+type Optional[T any] struct {}
+
+func (_ Optional[T]) Val() (T, bool)
+
+type Box[T any] interface {
+ Val() (T, bool)
+}
+
+func f[V interface{}, A, B Box[V]]() {}
+
+func _() {
+ f[int, Optional[int], Optional[int]]()
+ _ = f[int, Optional[int], Optional /* ERROR does not satisfy Box */ [string]]
+ _ = f[int, Optional[int], Optional /* ERROR Optional.* does not satisfy Box.* */ [string]]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue39755.go b/src/internal/types/testdata/fixedbugs/issue39755.go new file mode 100644 index 0000000..257b73a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39755.go @@ -0,0 +1,23 @@ +// 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. + +package p + +func _[T interface{~map[string]int}](x T) { + _ = x == nil +} + +// simplified test case from issue + +type PathParamsConstraint interface { + ~map[string]string | ~[]struct{key, value string} +} + +type PathParams[T PathParamsConstraint] struct { + t T +} + +func (pp *PathParams[T]) IsNil() bool { + return pp.t == nil // this must succeed +} diff --git a/src/internal/types/testdata/fixedbugs/issue39768.go b/src/internal/types/testdata/fixedbugs/issue39768.go new file mode 100644 index 0000000..696d9d9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39768.go @@ -0,0 +1,21 @@ +// 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. + +package p + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// type T[P any] P +// type A = T // ERROR cannot use generic type +// var x A[int] +// var _ A +// +// type B = T[int] +// var y B = x +// var _ B /* ERROR not a generic type */ [int] + +// test case from issue + +type Vector[T any] []T +type VectorAlias = Vector // ERROR cannot use generic type +var v Vector[int] diff --git a/src/internal/types/testdata/fixedbugs/issue39938.go b/src/internal/types/testdata/fixedbugs/issue39938.go new file mode 100644 index 0000000..633698d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39938.go @@ -0,0 +1,54 @@ +// 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. + +package p + +// All but E2 and E5 provide an "indirection" and break infinite expansion of a type. +type E0[P any] []P +type E1[P any] *P +type E2[P any] struct{ _ P } +type E3[P any] struct{ _ *P } +type E5[P any] struct{ _ [10]P } + +type T0 struct { + _ E0[T0] +} + +type T0_ struct { + E0[T0_] +} + +type T1 struct { + _ E1[T1] +} + +type T2 /* ERROR invalid recursive type */ struct { + _ E2[T2] +} + +type T3 struct { + _ E3[T3] +} + +type T4 /* ERROR invalid recursive type */ [10]E5[T4] + +type T5 struct { + _ E0[E2[T5]] +} + +type T6 struct { + _ E0[E2[E0[E1[E2[[10]T6]]]]] +} + +type T7 struct { + _ E0[[10]E2[E0[E2[E2[T7]]]]] +} + +type T8 struct { + _ E0[[]E2[E0[E2[E2[T8]]]]] +} + +type T9 /* ERROR invalid recursive type */ [10]E2[E5[E2[T9]]] + +type T10 [10]E2[E5[E2[func(T10)]]] diff --git a/src/internal/types/testdata/fixedbugs/issue39948.go b/src/internal/types/testdata/fixedbugs/issue39948.go new file mode 100644 index 0000000..c893cc0 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39948.go @@ -0,0 +1,9 @@ +// 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. + +package p + +type T[P any] interface{ + P // ERROR term cannot be a type parameter +} diff --git a/src/internal/types/testdata/fixedbugs/issue39976.go b/src/internal/types/testdata/fixedbugs/issue39976.go new file mode 100644 index 0000000..d703da9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39976.go @@ -0,0 +1,16 @@ +// 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. + +package p + +type policy[K, V any] interface{} +type LRU[K, V any] struct{} + +func NewCache[K, V any](p policy[K, V]) {} + +func _() { + var lru LRU[int, string] + NewCache[int, string](&lru) + NewCache(& /* ERROR does not match policy\[K, V\] \(cannot infer K and V\) */ lru) +} diff --git a/src/internal/types/testdata/fixedbugs/issue39982.go b/src/internal/types/testdata/fixedbugs/issue39982.go new file mode 100644 index 0000000..9810b63 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue39982.go @@ -0,0 +1,36 @@ +// 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. + +package p + +type ( + T[_ any] struct{} + S[_ any] struct { + data T[*T[int]] + } +) + +func _() { + _ = S[int]{ + data: T[*T[int]]{}, + } +} + +// full test case from issue + +type ( + Element[TElem any] struct{} + + entry[K comparable] struct{} + + Cache[K comparable] struct { + data map[K]*Element[*entry[K]] + } +) + +func _() { + _ = Cache[int]{ + data: make(map[int](*Element[*entry[int]])), + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue40038.go b/src/internal/types/testdata/fixedbugs/issue40038.go new file mode 100644 index 0000000..5f81fcb --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40038.go @@ -0,0 +1,15 @@ +// 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. + +package p + +type A[T any] int + +func (A[T]) m(A[T]) + +func f[P interface{m(P)}]() {} + +func _() { + _ = f[A[int]] +} diff --git a/src/internal/types/testdata/fixedbugs/issue40056.go b/src/internal/types/testdata/fixedbugs/issue40056.go new file mode 100644 index 0000000..66130c0 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40056.go @@ -0,0 +1,15 @@ +// 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. + +package p + +func _() { + NewS /* ERROR cannot infer T */ ().M() +} + +type S struct {} + +func NewS[T any]() *S { panic(0) } + +func (_ *S /* ERROR S is not a generic type */ [T]) M() diff --git a/src/internal/types/testdata/fixedbugs/issue40057.go b/src/internal/types/testdata/fixedbugs/issue40057.go new file mode 100644 index 0000000..fdc8fb1 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40057.go @@ -0,0 +1,17 @@ +// 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. + +package p + +func _() { + var x interface{} + switch t := x.(type) { + case S /* ERROR cannot use generic type */ : + t.m() + } +} + +type S[T any] struct {} + +func (_ S[T]) m() diff --git a/src/internal/types/testdata/fixedbugs/issue40301.go b/src/internal/types/testdata/fixedbugs/issue40301.go new file mode 100644 index 0000000..c78f9a1 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40301.go @@ -0,0 +1,12 @@ +// 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. + +package p + +import "unsafe" + +func _[T any](x T) { + _ = unsafe.Alignof(x) + _ = unsafe.Sizeof(x) +} diff --git a/src/internal/types/testdata/fixedbugs/issue40350.go b/src/internal/types/testdata/fixedbugs/issue40350.go new file mode 100644 index 0000000..08eb426 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40350.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +package p + +type number interface { + ~float64 | ~int | ~int32 + float64 | ~int32 +} + +func f[T number]() {} + +func _() { + _ = f[int /* ERROR int does not satisfy number \(number mentions int, but int is not in the type set of number\)*/] +} diff --git a/src/internal/types/testdata/fixedbugs/issue40684.go b/src/internal/types/testdata/fixedbugs/issue40684.go new file mode 100644 index 0000000..63a058d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40684.go @@ -0,0 +1,15 @@ +// 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. + +package p + +type T[_ any] int + +func f[_ any]() {} +func g[_, _ any]() {} + +func _() { + _ = f[T /* ERROR without instantiation */ ] + _ = g[T /* ERROR without instantiation */ , T /* ERROR without instantiation */ ] +} diff --git a/src/internal/types/testdata/fixedbugs/issue40789.go b/src/internal/types/testdata/fixedbugs/issue40789.go new file mode 100644 index 0000000..9eea4ad --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue40789.go @@ -0,0 +1,37 @@ +// Copyright 2021 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. + +package main + +import "fmt" + +func main() { + m := map[string]int{ + "a": 6, + "b": 7, + } + fmt.Println(copyMap[map[string]int, string, int](m)) +} + +type Map[K comparable, V any] interface { + map[K] V +} + +func copyMap[M Map[K, V], K comparable, V any](m M) M { + m1 := make(M) + for k, v := range m { + m1[k] = v + } + return m1 +} + +// simpler test case from the same issue + +type A[X comparable] interface { + []X +} + +func f[B A[X], X comparable]() B { + return nil +} diff --git a/src/internal/types/testdata/fixedbugs/issue41124.go b/src/internal/types/testdata/fixedbugs/issue41124.go new file mode 100644 index 0000000..80d1ff4 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue41124.go @@ -0,0 +1,91 @@ +// 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. + +package p + +// Test case from issue. + +type Nat /* ERROR invalid recursive type */ interface { + Zero|Succ +} + +type Zero struct{} +type Succ struct{ + Nat // Nat contains type constraints but is invalid, so no error +} + +// Struct tests. + +type I1 interface { + comparable +} + +type I2 interface { + ~int +} + +type I3 interface { + I1 + I2 +} + +type _ struct { + f I1 // ERROR interface is .* comparable +} + +type _ struct { + comparable // ERROR interface is .* comparable +} + +type _ struct{ + I1 // ERROR interface is .* comparable +} + +type _ struct{ + I2 // ERROR interface contains type constraints +} + +type _ struct{ + I3 // ERROR interface contains type constraints +} + +// General composite types. + +type ( + _ [10]I1 // ERROR interface is .* comparable + _ [10]I2 // ERROR interface contains type constraints + + _ []I1 // ERROR interface is .* comparable + _ []I2 // ERROR interface contains type constraints + + _ *I3 // ERROR interface contains type constraints + _ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints + _ chan I3 // ERROR interface contains type constraints + _ func(I1 /* ERROR interface is .* comparable */ ) + _ func() I2 // ERROR interface contains type constraints +) + +// Other cases. + +var _ = [...]I3 /* ERROR interface contains type constraints */ {} + +func _(x interface{}) { + _ = x.(I3 /* ERROR interface contains type constraints */ ) +} + +type T1[_ any] struct{} +type T3[_, _, _ any] struct{} +var _ T1[I2 /* ERROR interface contains type constraints */ ] +var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32] + +func f1[_ any]() int { panic(0) } +var _ = f1[I2 /* ERROR interface contains type constraints */ ]() +func f3[_, _, _ any]() int { panic(0) } +var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]() + +func _(x interface{}) { + switch x.(type) { + case I2 /* ERROR interface contains type constraints */ : + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue42695.go b/src/internal/types/testdata/fixedbugs/issue42695.go new file mode 100644 index 0000000..d0d6200 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue42695.go @@ -0,0 +1,17 @@ +// 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. + +package issue42695 + +const _ = 6e5518446744 // ERROR malformed constant +const _ uint8 = 6e5518446744 // ERROR malformed constant + +var _ = 6e5518446744 // ERROR malformed constant +var _ uint8 = 6e5518446744 // ERROR malformed constant + +func f(x int) int { + return x + 6e5518446744 // ERROR malformed constant +} + +var _ = f(6e5518446744 /* ERROR malformed constant */ ) diff --git a/src/internal/types/testdata/fixedbugs/issue42758.go b/src/internal/types/testdata/fixedbugs/issue42758.go new file mode 100644 index 0000000..6d75b10 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue42758.go @@ -0,0 +1,33 @@ +// 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. + +package p + +func _[T any](x interface{}){ + switch x.(type) { + case T: // ok to use a type parameter + case int: + } + + switch x.(type) { + case T: + case T /* ERROR duplicate case */ : + } +} + +type constraint interface { + ~int +} + +func _[T constraint](x interface{}){ + switch x.(type) { + case T: // ok to use a type parameter even if type set contains int + case int: + } +} + +func _(x constraint /* ERROR contains type constraints */ ) { + switch x.(type) { // no need to report another error + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue42881.go b/src/internal/types/testdata/fixedbugs/issue42881.go new file mode 100644 index 0000000..7122d1c --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue42881.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +package p + +type ( + T1 interface{ comparable } + T2 interface{ int } +) + +var ( + _ comparable // ERROR cannot use type comparable outside a type constraint: interface is \(or embeds\) comparable + _ T1 // ERROR cannot use type T1 outside a type constraint: interface is \(or embeds\) comparable + _ T2 // ERROR cannot use type T2 outside a type constraint: interface contains type constraints +) diff --git a/src/internal/types/testdata/fixedbugs/issue42987.go b/src/internal/types/testdata/fixedbugs/issue42987.go new file mode 100644 index 0000000..f58c63f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue42987.go @@ -0,0 +1,8 @@ +// Copyright 2021 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. + +// Check that there is only one error (no follow-on errors). + +package p +var _ = [ ... /* ERROR invalid use of \[...\] array */ ]byte("foo")
\ No newline at end of file diff --git a/src/internal/types/testdata/fixedbugs/issue43056.go b/src/internal/types/testdata/fixedbugs/issue43056.go new file mode 100644 index 0000000..8ff4e7f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43056.go @@ -0,0 +1,31 @@ +// Copyright 2022 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. + +package p + +// simplified example +func f[T ~func(T)](a, b T) {} + +type F func(F) + +func _() { + var i F + var j func(F) + + f(i, j) + f(j, i) +} + +// example from issue +func g[T interface{ Equal(T) bool }](a, b T) {} + +type I interface{ Equal(I) bool } + +func _() { + var i I + var j interface{ Equal(I) bool } + + g(i, j) + g(j, i) +} diff --git a/src/internal/types/testdata/fixedbugs/issue43087.go b/src/internal/types/testdata/fixedbugs/issue43087.go new file mode 100644 index 0000000..85d4450 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43087.go @@ -0,0 +1,43 @@ +// Copyright 2021 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. + +package p + +func _() { + a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3 + _ = a + _ = b +} + +func _() { + a, _, _ := 1, 2, 3 // multiple _'s ok + _ = a +} + +func _() { + var b int + a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3 + _ = a + _ = b +} + +func _() { + var a []int + a /* ERROR non-name .* on left side of := */ [0], b := 1, 2 + _ = a + _ = b +} + +func _() { + var a int + a, a /* ERROR a repeated on left side of := */ := 1, 2 + _ = a +} + +func _() { + var a, b int + a, b := /* ERROR no new variables on left side of := */ 1, 2 + _ = a + _ = b +} diff --git a/src/internal/types/testdata/fixedbugs/issue43109.go b/src/internal/types/testdata/fixedbugs/issue43109.go new file mode 100644 index 0000000..f242f16 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43109.go @@ -0,0 +1,10 @@ +// Copyright 2022 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. + +// Ensure there is no "imported and not used" error +// if a package wasn't imported in the first place. + +package p + +import . "/foo" // ERROR could not import \/foo diff --git a/src/internal/types/testdata/fixedbugs/issue43110.go b/src/internal/types/testdata/fixedbugs/issue43110.go new file mode 100644 index 0000000..8d5c983 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43110.go @@ -0,0 +1,43 @@ +// 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. + +package p + +type P *struct{} + +func _() { + // want an error even if the switch is empty + var a struct{ _ func() } + switch a /* ERROR cannot switch on a */ { + } + + switch a /* ERROR cannot switch on a */ { + case a: // no follow-on error here + } + + // this is ok because f can be compared to nil + var f func() + switch f { + } + + switch f { + case nil: + } + + switch (func())(nil) { + case nil: + } + + switch (func())(nil) { + case f /* ERROR invalid case f in switch on .* \(func can only be compared to nil\) */ : + } + + switch nil /* ERROR use of untyped nil in switch expression */ { + } + + // this is ok + switch P(nil) { + case P(nil): + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue43124.go b/src/internal/types/testdata/fixedbugs/issue43124.go new file mode 100644 index 0000000..f429f74 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43124.go @@ -0,0 +1,16 @@ +// 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. + +package p + +var _ = int(0 /* ERROR invalid use of \.\.\. in conversion to int */ ...) + +// test case from issue + +type M []string + +var ( + x = []string{"a", "b"} + _ = M(x /* ERROR invalid use of \.\.\. in conversion to M */ ...) +) diff --git a/src/internal/types/testdata/fixedbugs/issue43125.go b/src/internal/types/testdata/fixedbugs/issue43125.go new file mode 100644 index 0000000..456888d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43125.go @@ -0,0 +1,8 @@ +// Copyright 2021 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. + +package p + +var _ = new(- /* ERROR not a type */ 1) +var _ = new(1 /* ERROR not a type */ + 1) diff --git a/src/internal/types/testdata/fixedbugs/issue43190.go b/src/internal/types/testdata/fixedbugs/issue43190.go new file mode 100644 index 0000000..d1b46b5 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43190.go @@ -0,0 +1,31 @@ +// 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. + +// The errors below are produced by the parser, but we check +// them here for consistency with the types2 tests. + +package p + +import ; // ERROR missing import path +import "" // ERROR invalid import path \(empty string\) +import +var /* ERROR missing import path */ _ int +import .; // ERROR missing import path +import 'x' // ERROR import path must be a string +var _ int +import /* ERROR imports must appear before other declarations */ _ "math" + +// Don't repeat previous error for each immediately following import ... +import () +import (.) // ERROR missing import path +import ( + "fmt" + . +) // ERROR missing import path + +// ... but remind with error again if we start a new import section after +// other declarations +var _ = fmt.Println +import /* ERROR imports must appear before other declarations */ _ "math" +import _ "math" diff --git a/src/internal/types/testdata/fixedbugs/issue43527.go b/src/internal/types/testdata/fixedbugs/issue43527.go new file mode 100644 index 0000000..b515100 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43527.go @@ -0,0 +1,16 @@ +// Copyright 2021 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. + +package p + +const L = 10 + +type ( + _ [L]struct{} + _ [A /* ERROR undefined array length A or missing type constraint */ ]struct{} + _ [B /* ERROR invalid array length B */ ]struct{} + _[A any] struct{} + + B int +) diff --git a/src/internal/types/testdata/fixedbugs/issue43671.go b/src/internal/types/testdata/fixedbugs/issue43671.go new file mode 100644 index 0000000..6879aec --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue43671.go @@ -0,0 +1,58 @@ +// Copyright 2021 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. + +package p + +type C0 interface{ int } +type C1 interface{ chan int } +type C2 interface{ chan int | <-chan int } +type C3 interface{ chan int | chan float32 } +type C4 interface{ chan int | chan<- int } +type C5[T any] interface{ ~chan T | <-chan T } + +func _[T any](ch T) { + <-ch // ERROR cannot receive from ch .* \(no core type\) +} + +func _[T C0](ch T) { + <-ch // ERROR cannot receive from non-channel ch +} + +func _[T C1](ch T) { + <-ch +} + +func _[T C2](ch T) { + <-ch +} + +func _[T C3](ch T) { + <-ch // ERROR cannot receive from ch .* \(no core type\) +} + +func _[T C4](ch T) { + <-ch // ERROR cannot receive from send-only channel +} + +func _[T C5[X], X any](ch T, x X) { + x = <-ch +} + +// test case from issue, slightly modified +type RecvChan[T any] interface { + ~chan T | ~<-chan T +} + +func _[T any, C RecvChan[T]](ch C) T { + return <-ch +} + +func f[T any, C interface{ chan T }](ch C) T { + return <-ch +} + +func _(ch chan int) { + var x int = f(ch) // test constraint type inference for this case + _ = x +} diff --git a/src/internal/types/testdata/fixedbugs/issue44688.go b/src/internal/types/testdata/fixedbugs/issue44688.go new file mode 100644 index 0000000..512bfcc --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue44688.go @@ -0,0 +1,83 @@ +// Copyright 2021 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. + +package P + +type A1[T any] struct{} + +func (*A1[T]) m1(T) {} + +type A2[T any] interface { + m2(T) +} + +type B1[T any] struct { + filler int + *A1[T] + A2[T] +} + +type B2[T any] interface { + A2[T] +} + +type C[T any] struct { + filler1 int + filler2 int + B1[T] +} + +type D[T any] struct { + filler1 int + filler2 int + filler3 int + C[T] +} + +func _() { + // calling embedded methods + var b1 B1[string] + + b1.A1.m1("") + b1.m1("") + + b1.A2.m2("") + b1.m2("") + + var b2 B2[string] + b2.m2("") + + // a deeper nesting + var d D[string] + d.m1("") + d.m2("") + + // calling method expressions + m1x := B1[string].m1 + m1x(b1, "") + m2x := B2[string].m2 + m2x(b2, "") + + // calling method values + m1v := b1.m1 + m1v("") + m2v := b1.m2 + m2v("") + b2v := b2.m2 + b2v("") +} + +// actual test case from issue + +type A[T any] struct{} + +func (*A[T]) f(T) {} + +type B[T any] struct{ A[T] } + +func _() { + var b B[string] + b.A.f("") + b.f("") +} diff --git a/src/internal/types/testdata/fixedbugs/issue44799.go b/src/internal/types/testdata/fixedbugs/issue44799.go new file mode 100644 index 0000000..9e528a7 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue44799.go @@ -0,0 +1,19 @@ +// Copyright 2021 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. + +package main + +func Map[F, T any](s []F, f func(F) T) []T { return nil } + +func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { var x Elem2; return x } + +func main() { + var s []int + var f1 func(int) float64 + var f2 func(float64, int) float64 + _ = Map[int](s, f1) + _ = Map(s, f1) + _ = Reduce[int](s, 0, f2) + _ = Reduce(s, 0, f2) +} diff --git a/src/internal/types/testdata/fixedbugs/issue45114.go b/src/internal/types/testdata/fixedbugs/issue45114.go new file mode 100644 index 0000000..0093660 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45114.go @@ -0,0 +1,8 @@ +// Copyright 2022 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. + +package p + +var s uint +var _ = string(1 /* ERROR shifted operand 1 .* must be integer */ << s) diff --git a/src/internal/types/testdata/fixedbugs/issue45548.go b/src/internal/types/testdata/fixedbugs/issue45548.go new file mode 100644 index 0000000..01c9672 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45548.go @@ -0,0 +1,13 @@ +// Copyright 2021 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. + +package p + +func f[F interface{*Q}, G interface{*R}, Q, R any](q Q, r R) {} + +func _() { + f[*float64, *int](1, 2) + f[*float64](1, 2) + f(1, 2) +} diff --git a/src/internal/types/testdata/fixedbugs/issue45550.go b/src/internal/types/testdata/fixedbugs/issue45550.go new file mode 100644 index 0000000..498b1eb --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45550.go @@ -0,0 +1,10 @@ +// Copyright 2021 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. + +package p + +type Builder /* ERROR invalid recursive type */ [T interface{ struct{ Builder[T] } }] struct{} +type myBuilder struct { + Builder[myBuilder] +} diff --git a/src/internal/types/testdata/fixedbugs/issue45635.go b/src/internal/types/testdata/fixedbugs/issue45635.go new file mode 100644 index 0000000..af05ff0 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45635.go @@ -0,0 +1,31 @@ +// Copyright 2021 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. + +package main + +func main() { + some /* ERROR "undefined" */ [int, int]() +} + +type N[T any] struct{} + +var _ N [] // ERROR expected type argument list + +type I interface { + ~[]int +} + +func _[T I](i, j int) { + var m map[int]int + _ = m[i, j /* ERROR "more than one index" */ ] + + var a [3]int + _ = a[i, j /* ERROR "more than one index" */ ] + + var s []int + _ = s[i, j /* ERROR "more than one index" */ ] + + var t T + _ = t[i, j /* ERROR "more than one index" */ ] +} diff --git a/src/internal/types/testdata/fixedbugs/issue45639.go b/src/internal/types/testdata/fixedbugs/issue45639.go new file mode 100644 index 0000000..80148fe --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45639.go @@ -0,0 +1,13 @@ +// Copyright 2021 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. + +package P + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// // It is not permitted to declare a local type whose underlying +// // type is a type parameters not declared by that type declaration. +// func _[T any]() { +// type _ T // ERROR cannot use function type parameter T as RHS in type declaration +// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration +// } diff --git a/src/internal/types/testdata/fixedbugs/issue45920.go b/src/internal/types/testdata/fixedbugs/issue45920.go new file mode 100644 index 0000000..0a281c5 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45920.go @@ -0,0 +1,17 @@ +// Copyright 2021 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. + +package p + +func f1[T any, C chan T | <-chan T](ch C) {} + +func _(ch chan int) { f1(ch) } +func _(ch <-chan int) { f1(ch) } +func _(ch chan<- int) { f1 /* ERROR chan<- int does not satisfy chan int \| <-chan int */ (ch) } + +func f2[T any, C chan T | chan<- T](ch C) {} + +func _(ch chan int) { f2(ch) } +func _(ch <-chan int) { f2 /* ERROR <-chan int does not satisfy chan int \| chan<- int */ (ch) } +func _(ch chan<- int) { f2(ch) } diff --git a/src/internal/types/testdata/fixedbugs/issue45985.go b/src/internal/types/testdata/fixedbugs/issue45985.go new file mode 100644 index 0000000..ae04ce2 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue45985.go @@ -0,0 +1,13 @@ +// Copyright 2021 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. + +package issue45985 + +func app[S interface{ ~[]T }, T any](s S, e T) S { + return append(s, e) +} + +func _() { + _ = app /* ERROR "int does not match" */ [int] +} diff --git a/src/internal/types/testdata/fixedbugs/issue46090.go b/src/internal/types/testdata/fixedbugs/issue46090.go new file mode 100644 index 0000000..07f0101 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue46090.go @@ -0,0 +1,11 @@ +// -lang=go1.17 + +// 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. + +// The predeclared type comparable is not visible before Go 1.18. + +package p + +type _ comparable // ERROR predeclared comparable diff --git a/src/internal/types/testdata/fixedbugs/issue46275.go b/src/internal/types/testdata/fixedbugs/issue46275.go new file mode 100644 index 0000000..0862d5b --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue46275.go @@ -0,0 +1,26 @@ +// Copyright 2021 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. + +package issue46275 + +type N[T any] struct { + *N[T] + t T +} + +func (n *N[T]) Elem() T { + return n.t +} + +type I interface { + Elem() string +} + +func _() { + var n1 *N[string] + var _ I = n1 + type NS N[string] + var n2 *NS + var _ I = n2 +} diff --git a/src/internal/types/testdata/fixedbugs/issue46403.go b/src/internal/types/testdata/fixedbugs/issue46403.go new file mode 100644 index 0000000..9d47522 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue46403.go @@ -0,0 +1,11 @@ +// Copyright 2021 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. + +package issue46403 + +func _() { + // a should be used, despite the parser error below. + var a []int + var _ = a[] // ERROR expected operand +} diff --git a/src/internal/types/testdata/fixedbugs/issue46404.go b/src/internal/types/testdata/fixedbugs/issue46404.go new file mode 100644 index 0000000..e3c93f6 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue46404.go @@ -0,0 +1,10 @@ +// Copyright 2021 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. + +package issue46404 + +// TODO(gri) re-enable this test with matching errors +// between go/types and types2 +// Check that we don't type check t[_] as an instantiation. +// type t [t /* type parameters must be named */ /* not a generic type */ [_]]_ // cannot use diff --git a/src/internal/types/testdata/fixedbugs/issue46461.go b/src/internal/types/testdata/fixedbugs/issue46461.go new file mode 100644 index 0000000..fce06f7 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue46461.go @@ -0,0 +1,20 @@ +// Copyright 2021 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. + +package p + +// test case 1 +type T /* ERROR invalid recursive type */ [U interface{ M() T[U] }] int + +type X int + +func (X) M() T[X] { return 0 } + +// test case 2 +type A /* ERROR invalid recursive type */ [T interface{ A[T] }] interface{} + +// test case 3 +type A2 /* ERROR invalid recursive type */ [U interface{ A2[U] }] interface{ M() A2[U] } + +type I interface{ A2[I]; M() A2[I] } diff --git a/src/internal/types/testdata/fixedbugs/issue46583.go b/src/internal/types/testdata/fixedbugs/issue46583.go new file mode 100644 index 0000000..da1f1ff --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue46583.go @@ -0,0 +1,28 @@ +// Copyright 2021 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. + +package p + +type T1 struct{} +func (t T1) m(int) {} +var f1 func(T1) + +type T2 struct{} +func (t T2) m(x int) {} +var f2 func(T2) + +type T3 struct{} +func (T3) m(int) {} +var f3 func(T3) + +type T4 struct{} +func (T4) m(x int) {} +var f4 func(T4) + +func _() { + f1 = T1 /* ERROR func\(T1, int\) */ .m + f2 = T2 /* ERROR func\(t T2, x int\) */ .m + f3 = T3 /* ERROR func\(T3, int\) */ .m + f4 = T4 /* ERROR func\(_ T4, x int\) */ .m +} diff --git a/src/internal/types/testdata/fixedbugs/issue47031.go b/src/internal/types/testdata/fixedbugs/issue47031.go new file mode 100644 index 0000000..b184f9b --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47031.go @@ -0,0 +1,20 @@ +// Copyright 2021 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. + +package p + +type Mer interface { M() } + +func F[T Mer](p *T) { + p.M /* ERROR p\.M undefined */ () +} + +type MyMer int + +func (MyMer) M() {} + +func _() { + F(new(MyMer)) + F[Mer](nil) +} diff --git a/src/internal/types/testdata/fixedbugs/issue47115.go b/src/internal/types/testdata/fixedbugs/issue47115.go new file mode 100644 index 0000000..a0bfe38 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47115.go @@ -0,0 +1,40 @@ +// Copyright 2021 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. + +package p + +type C0 interface{ int } +type C1 interface{ chan int } +type C2 interface{ chan int | <-chan int } +type C3 interface{ chan int | chan float32 } +type C4 interface{ chan int | chan<- int } +type C5[T any] interface{ ~chan T | chan<- T } + +func _[T any](ch T) { + ch <- /* ERROR cannot send to ch .* no core type */ 0 +} + +func _[T C0](ch T) { + ch <- /* ERROR cannot send to non-channel */ 0 +} + +func _[T C1](ch T) { + ch <- 0 +} + +func _[T C2](ch T) { + ch <-/* ERROR cannot send to receive-only channel */ 0 +} + +func _[T C3](ch T) { + ch <- /* ERROR cannot send to ch .* no core type */ 0 +} + +func _[T C4](ch T) { + ch <- 0 +} + +func _[T C5[X], X any](ch T, x X) { + ch <- x +} diff --git a/src/internal/types/testdata/fixedbugs/issue47127.go b/src/internal/types/testdata/fixedbugs/issue47127.go new file mode 100644 index 0000000..bb4b487 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47127.go @@ -0,0 +1,37 @@ +// Copyright 2021 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. + +// Embedding of stand-alone type parameters is not permitted. + +package p + +type ( + _[P any] interface{ *P | []P | chan P | map[string]P } + _[P any] interface{ P /* ERROR term cannot be a type parameter */ } + _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ } + _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ } + _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ } +) + +func _[P any]() { + type ( + _[P any] interface{ *P | []P | chan P | map[string]P } + _[P any] interface{ P /* ERROR term cannot be a type parameter */ } + _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ } + _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ } + _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ } + + _ interface{ *P | []P | chan P | map[string]P } + _ interface{ P /* ERROR term cannot be a type parameter */ } + _ interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ } + _ interface{ int | P /* ERROR term cannot be a type parameter */ } + _ interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ } + ) +} + +func _[P any, Q interface{ *P | []P | chan P | map[string]P }]() {} +func _[P any, Q interface{ P /* ERROR term cannot be a type parameter */ }]() {} +func _[P any, Q interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {} +func _[P any, Q interface{ int | P /* ERROR term cannot be a type parameter */ }]() {} +func _[P any, Q interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {} diff --git a/src/internal/types/testdata/fixedbugs/issue47411.go b/src/internal/types/testdata/fixedbugs/issue47411.go new file mode 100644 index 0000000..33b169a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47411.go @@ -0,0 +1,26 @@ +// Copyright 2021 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. + +package p + +func f[_ comparable]() {} +func g[_ interface{interface{comparable; ~int|~string}}]() {} + +func _[P comparable, + Q interface{ comparable; ~int|~string }, + R any, // not comparable + S interface{ comparable; ~func() }, // not comparable +]() { + _ = f[int] + _ = f[P] + _ = f[Q] + _ = f[func /* ERROR does not satisfy comparable */ ()] + _ = f[R /* ERROR R does not satisfy comparable */ ] + + _ = g[int] + _ = g[P /* ERROR P does not satisfy interface{interface{comparable; ~int \| ~string} */ ] + _ = g[Q] + _ = g[func /* ERROR func\(\) does not satisfy interface{interface{comparable; ~int \| ~string}} */ ()] + _ = g[R /* ERROR R does not satisfy interface{interface{comparable; ~int \| ~string} */ ] +} diff --git a/src/internal/types/testdata/fixedbugs/issue47747.go b/src/internal/types/testdata/fixedbugs/issue47747.go new file mode 100644 index 0000000..6f09fc2 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47747.go @@ -0,0 +1,71 @@ +// Copyright 2021 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. + +package p + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// type T1[P any] P +// +// func (T1[_]) m() {} +// +// func _[P any](x *T1[P]) { +// // x.m exists because x is of type *T1 where T1 is a defined type +// // (even though under(T1) is a type parameter) +// x.m() +// } + + +func _[P interface{ m() }](x P) { + x.m() + // (&x).m doesn't exist because &x is of type *P + // and pointers to type parameters don't have methods + (&x).m /* ERROR type \*P is pointer to type parameter, not type parameter */ () +} + + +type T2 interface{ m() } + +func _(x *T2) { + // x.m doesn't exists because x is of type *T2 + // and pointers to interfaces don't have methods + x.m /* ERROR type \*T2 is pointer to interface, not interface */() +} + +// Test case 1 from issue + +type Fooer1[t any] interface { + Foo(Barer[t]) +} +type Barer[t any] interface { + Bar(t) +} + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// type Foo1[t any] t +// type Bar[t any] t +// +// func (l Foo1[t]) Foo(v Barer[t]) { v.Bar(t(l)) } +// func (b *Bar[t]) Bar(l t) { *b = Bar[t](l) } +// +// func _[t any](f Fooer1[t]) t { +// var b Bar[t] +// f.Foo(&b) +// return t(b) +// } + +// Test case 2 from issue + +// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639). +// type Fooer2[t any] interface { +// Foo() +// } +// +// type Foo2[t any] t +// +// func (f *Foo2[t]) Foo() {} +// +// func _[t any](v t) { +// var f = Foo2[t](v) +// _ = Fooer2[t](&f) +// } diff --git a/src/internal/types/testdata/fixedbugs/issue47796.go b/src/internal/types/testdata/fixedbugs/issue47796.go new file mode 100644 index 0000000..4c59106 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47796.go @@ -0,0 +1,33 @@ +// Copyright 2021 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. + +package p + +// parameterized types with self-recursive constraints +type ( + T1 /* ERROR invalid recursive type */ [P T1[P]] interface{} + T2 /* ERROR invalid recursive type */ [P, Q T2[P, Q]] interface{} + T3[P T2[P, Q], Q interface{ ~string }] interface{} + + T4a /* ERROR invalid recursive type */ [P T4a[P]] interface{ ~int } + T4b /* ERROR invalid recursive type */ [P T4b[int]] interface{ ~int } + T4c /* ERROR invalid recursive type */ [P T4c[string]] interface{ ~int } + + // mutually recursive constraints + T5 /* ERROR invalid recursive type */ [P T6[P]] interface{ int } + T6[P T5[P]] interface{ int } +) + +// verify that constraints are checked as expected +var ( + _ T1[int] + _ T2[int, string] + _ T3[int, string] +) + +// test case from issue + +type Eq /* ERROR invalid recursive type */ [a Eq[a]] interface { + Equal(that a) bool +} diff --git a/src/internal/types/testdata/fixedbugs/issue47818.go b/src/internal/types/testdata/fixedbugs/issue47818.go new file mode 100644 index 0000000..e9b0adb --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47818.go @@ -0,0 +1,61 @@ +// -lang=go1.17 + +// Copyright 2021 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. + +// Parser accepts type parameters but the type checker +// needs to report any operations that are not permitted +// before Go 1.18. + +package p + +type T[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */] struct{} + +// for init (and main, but we're not in package main) we should only get one error +func init[P /* ERROR func init must have no type parameters */ any /* ERROR predeclared any requires go1\.18 or later */]() { +} +func main[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */]() { +} + +func f[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */](x P) { + var _ T[ /* ERROR type instantiation requires go1\.18 or later */ int] + var _ (T[ /* ERROR type instantiation requires go1\.18 or later */ int]) + _ = T[ /* ERROR type instantiation requires go1\.18 or later */ int]{} + _ = T[ /* ERROR type instantiation requires go1\.18 or later */ int](struct{}{}) +} + +func (T[ /* ERROR type instantiation requires go1\.18 or later */ P]) g(x int) { + f[ /* ERROR function instantiation requires go1\.18 or later */ int](0) // explicit instantiation + (f[ /* ERROR function instantiation requires go1\.18 or later */ int])(0) // parentheses (different code path) + f( /* ERROR implicit function instantiation requires go1\.18 or later */ x) // implicit instantiation +} + +type C1 interface { + comparable // ERROR predeclared comparable requires go1\.18 or later +} + +type C2 interface { + comparable // ERROR predeclared comparable requires go1\.18 or later + int // ERROR embedding non-interface type int requires go1\.18 or later + ~ /* ERROR embedding interface element ~int requires go1\.18 or later */ int + int /* ERROR embedding interface element int \| ~string requires go1\.18 or later */ | ~string +} + +type _ interface { + // errors for these were reported with their declaration + C1 + C2 +} + +type ( + _ comparable // ERROR predeclared comparable requires go1\.18 or later + // errors for these were reported with their declaration + _ C1 + _ C2 + + _ = comparable // ERROR predeclared comparable requires go1\.18 or later + // errors for these were reported with their declaration + _ = C1 + _ = C2 +) diff --git a/src/internal/types/testdata/fixedbugs/issue47887.go b/src/internal/types/testdata/fixedbugs/issue47887.go new file mode 100644 index 0000000..4c4fc2f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47887.go @@ -0,0 +1,28 @@ +// Copyright 2021 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. + +package p + +type Fooer[t any] interface { + foo(Barer[t]) +} +type Barer[t any] interface { + bar(Bazer[t]) +} +type Bazer[t any] interface { + Fooer[t] + baz(t) +} + +type Int int + +func (n Int) baz(int) {} +func (n Int) foo(b Barer[int]) { b.bar(n) } + +type F[t any] interface { f(G[t]) } +type G[t any] interface { g(H[t]) } +type H[t any] interface { F[t] } + +type T struct{} +func (n T) f(b G[T]) { b.g(n) } diff --git a/src/internal/types/testdata/fixedbugs/issue47968.go b/src/internal/types/testdata/fixedbugs/issue47968.go new file mode 100644 index 0000000..3dd3039 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue47968.go @@ -0,0 +1,21 @@ +// Copyright 2021 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. + +package p + +type T[P any] struct{} + +func (T[P]) m1() + +type A1 = T // ERROR cannot use generic type + +func (A1[P]) m2() {} + +type A2 = T[int] + +func (A2 /* ERROR cannot define new methods on instantiated type T\[int\] */) m3() {} +func (_ /* ERROR cannot define new methods on instantiated type T\[int\] */ A2) m4() {} + +func (T[int]) m5() {} // int is the type parameter name, not an instantiation +func (T[* /* ERROR must be an identifier */ int]) m6() {} // syntax error diff --git a/src/internal/types/testdata/fixedbugs/issue48008.go b/src/internal/types/testdata/fixedbugs/issue48008.go new file mode 100644 index 0000000..6c14c78 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48008.go @@ -0,0 +1,60 @@ +// Copyright 2021 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. + +package p + +type T[P any] struct{} + +func _(x interface{}) { + switch x.(type) { + case nil: + case int: + + case T[int]: + case []T[int]: + case [10]T[int]: + case struct{T[int]}: + case *T[int]: + case func(T[int]): + case interface{m(T[int])}: + case map[T[int]] string: + case chan T[int]: + + case T /* ERROR cannot use generic type T\[P any\] without instantiation */ : + case []T /* ERROR cannot use generic type */ : + case [10]T /* ERROR cannot use generic type */ : + case struct{T /* ERROR cannot use generic type */ }: + case *T /* ERROR cannot use generic type */ : + case func(T /* ERROR cannot use generic type */ ): + case interface{m(T /* ERROR cannot use generic type */ )}: + case map[T /* ERROR cannot use generic type */ ] string: + case chan T /* ERROR cannot use generic type */ : + + case T /* ERROR cannot use generic type */ , *T /* ERROR cannot use generic type */ : + } +} + +// Make sure a parenthesized nil is ok. + +func _(x interface{}) { + switch x.(type) { + case ((nil)), int: + } +} + +// Make sure we look for the predeclared nil. + +func _(x interface{}) { + type nil int + switch x.(type) { + case nil: // ok - this is the type nil + } +} + +func _(x interface{}) { + var nil int + switch x.(type) { + case nil /* ERROR not a type */ : // not ok - this is the variable nil + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue48018.go b/src/internal/types/testdata/fixedbugs/issue48018.go new file mode 100644 index 0000000..e6ccc6b --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48018.go @@ -0,0 +1,20 @@ +// Copyright 2021 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. + +package main + +type Box[A any] struct { + value A +} + +func Nest[A /* ERROR instantiation cycle */ any](b Box[A], n int) interface{} { + if n == 0 { + return b + } + return Nest(Box[Box[A]]{b}, n-1) +} + +func main() { + Nest(Box[int]{0}, 10) +} diff --git a/src/internal/types/testdata/fixedbugs/issue48048.go b/src/internal/types/testdata/fixedbugs/issue48048.go new file mode 100644 index 0000000..f401330 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48048.go @@ -0,0 +1,15 @@ +// Copyright 2021 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. + +package p + +type T[P any] struct{} + +func (T[_]) A() {} + +var _ = (T[int]).A +var _ = (*T[int]).A + +var _ = (T /* ERROR cannot use generic type */).A +var _ = (*T /* ERROR cannot use generic type */).A diff --git a/src/internal/types/testdata/fixedbugs/issue48082.go b/src/internal/types/testdata/fixedbugs/issue48082.go new file mode 100644 index 0000000..5395154 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48082.go @@ -0,0 +1,7 @@ +// Copyright 2021 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. + +package issue48082 + +import "init" /* ERROR init must be a func */ /* ERROR could not import init */ diff --git a/src/internal/types/testdata/fixedbugs/issue48083.go b/src/internal/types/testdata/fixedbugs/issue48083.go new file mode 100644 index 0000000..3dae514 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48083.go @@ -0,0 +1,9 @@ +// Copyright 2021 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. + +package p + +type T[P any] struct{} + +type _ interface{ int | T /* ERROR cannot use generic type */ }
\ No newline at end of file diff --git a/src/internal/types/testdata/fixedbugs/issue48136.go b/src/internal/types/testdata/fixedbugs/issue48136.go new file mode 100644 index 0000000..b87f84a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48136.go @@ -0,0 +1,36 @@ +// Copyright 2021 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. + +package p + +func f1[P interface{ *P }]() {} +func f2[P interface{ func(P) }]() {} +func f3[P, Q interface{ func(Q) P }]() {} +func f4[P interface{ *Q }, Q interface{ func(P) }]() {} +func f5[P interface{ func(P) }]() {} +func f6[P interface { *Tree[P] }, Q any ]() {} + +func _() { + f1 /* ERROR cannot infer P */ () + f2 /* ERROR cannot infer P */ () + f3 /* ERROR cannot infer P */ () + f4 /* ERROR cannot infer P */ () + f5 /* ERROR cannot infer P */ () + f6 /* ERROR cannot infer P */ () +} + +type Tree[P any] struct { + left, right *Tree[P] + data P +} + +// test case from issue + +func foo[Src interface { func() Src }]() Src { + return foo[Src] +} + +func _() { + foo /* ERROR cannot infer Src */ () +} diff --git a/src/internal/types/testdata/fixedbugs/issue48234.go b/src/internal/types/testdata/fixedbugs/issue48234.go new file mode 100644 index 0000000..e069930 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48234.go @@ -0,0 +1,10 @@ +// Copyright 2021 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. + +package p + +var _ = interface{ + m() + m /* ERROR "duplicate method" */ () +}(nil) diff --git a/src/internal/types/testdata/fixedbugs/issue48312.go b/src/internal/types/testdata/fixedbugs/issue48312.go new file mode 100644 index 0000000..2fdb7ca --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48312.go @@ -0,0 +1,20 @@ +// Copyright 2022 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. + +package p + +type T interface{ m() } +type P *T + +func _(p *T) { + p.m /* ERROR type \*T is pointer to interface, not interface */ () +} + +func _(p P) { + p.m /* ERROR type P is pointer to interface, not interface */ () +} + +func _[P T](p *P) { + p.m /* ERROR type \*P is pointer to type parameter, not type parameter */ () +} diff --git a/src/internal/types/testdata/fixedbugs/issue48472.go b/src/internal/types/testdata/fixedbugs/issue48472.go new file mode 100644 index 0000000..2d908f4 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48472.go @@ -0,0 +1,16 @@ +// Copyright 2021 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. + +package p + +func g() { + var s string + var i int + _ = s /* ERROR invalid operation: s \+ i \(mismatched types string and int\) */ + i +} + +func f(i int) int { + i /* ERROR invalid operation: i \+= "1" \(mismatched types int and untyped string\) */ += "1" + return i +} diff --git a/src/internal/types/testdata/fixedbugs/issue48529.go b/src/internal/types/testdata/fixedbugs/issue48529.go new file mode 100644 index 0000000..d7a70b1 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48529.go @@ -0,0 +1,11 @@ +// Copyright 2021 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. + +package p + +type T /* ERROR invalid recursive type */ [U interface{ M() T[U, int] }] int + +type X int + +func (X) M() T[X] { return 0 } diff --git a/src/internal/types/testdata/fixedbugs/issue48582.go b/src/internal/types/testdata/fixedbugs/issue48582.go new file mode 100644 index 0000000..9e1d526 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48582.go @@ -0,0 +1,29 @@ +// Copyright 2021 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. + +package p + +type N /* ERROR invalid recursive type */ interface { + int | N +} + +type A /* ERROR invalid recursive type */ interface { + int | B +} + +type B interface { + int | A +} + +type S /* ERROR invalid recursive type */ struct { + I // ERROR interface contains type constraints +} + +type I interface { + int | S +} + +type P interface { + *P // ERROR interface contains type constraints +} diff --git a/src/internal/types/testdata/fixedbugs/issue48619.go b/src/internal/types/testdata/fixedbugs/issue48619.go new file mode 100644 index 0000000..72eea1e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48619.go @@ -0,0 +1,22 @@ +// Copyright 2021 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. + +package p + +func f[P any](a, _ P) { + var x int + // TODO(gri) these error messages, while correct, could be better + f(a, x /* ERROR type int of x does not match inferred type P for P */) + f(x, a /* ERROR type P of a does not match inferred type int for P */) +} + +func g[P any](a, b P) { + g(a, b) + g(&a, &b) + g([]P{}, []P{}) + + // work-around: provide type argument explicitly + g[*P](&a, &b) + g[[]P]([]P{}, []P{}) +} diff --git a/src/internal/types/testdata/fixedbugs/issue48656.go b/src/internal/types/testdata/fixedbugs/issue48656.go new file mode 100644 index 0000000..0f60f47 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48656.go @@ -0,0 +1,13 @@ +// Copyright 2021 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. + +package p + +func f[P *Q, Q any](P, Q) { + _ = f[P] +} + +func f2[P /* ERROR instantiation cycle */ *Q, Q any](P, Q) { + _ = f2[*P] +} diff --git a/src/internal/types/testdata/fixedbugs/issue48695.go b/src/internal/types/testdata/fixedbugs/issue48695.go new file mode 100644 index 0000000..9f4a768 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48695.go @@ -0,0 +1,14 @@ +// Copyright 2021 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. + +package p + +func g[P ~func(T) P, T any](P) {} + +func _() { + type F func(int) F + var f F + g(f) + _ = g[F] +} diff --git a/src/internal/types/testdata/fixedbugs/issue48703.go b/src/internal/types/testdata/fixedbugs/issue48703.go new file mode 100644 index 0000000..8a32c1e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48703.go @@ -0,0 +1,27 @@ +// Copyright 2021 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. + +package p + +import "unsafe" + +// The actual example from the issue. +type List[P any] struct{} + +func (_ List[P]) m() (_ List[List[P]]) { return } + +// Other types of recursion through methods. +type R[P any] int + +func (*R[R /* ERROR must be an identifier */ [int]]) m0() {} +func (R[P]) m1(R[R[P]]) {} +func (R[P]) m2(R[*P]) {} +func (R[P]) m3([unsafe.Sizeof(new(R[P]))]int) {} +func (R[P]) m4([unsafe.Sizeof(new(R[R[P]]))]int) {} + +// Mutual recursion +type M[P any] int + +func (R[P]) m5(M[M[P]]) {} +func (M[P]) m(R[R[P]]) {} diff --git a/src/internal/types/testdata/fixedbugs/issue48712.go b/src/internal/types/testdata/fixedbugs/issue48712.go new file mode 100644 index 0000000..63ce7bc --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48712.go @@ -0,0 +1,41 @@ +// Copyright 2022 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. + +package p + +func _[P comparable](x, y P) { + _ = x == x + _ = x == y + _ = y == x + _ = y == y + + _ = x /* ERROR type parameter P is not comparable with < */ < y +} + +func _[P comparable](x P, y any) { + _ = x == x + _ = x == y + _ = y == x + _ = y == y + + _ = x /* ERROR type parameter P is not comparable with < */ < y +} + +func _[P any](x, y P) { + _ = x /* ERROR incomparable types in type set */ == x + _ = x /* ERROR incomparable types in type set */ == y + _ = y /* ERROR incomparable types in type set */ == x + _ = y /* ERROR incomparable types in type set */ == y + + _ = x /* ERROR type parameter P is not comparable with < */ < y +} + +func _[P any](x P, y any) { + _ = x /* ERROR incomparable types in type set */ == x + _ = x /* ERROR incomparable types in type set */ == y + _ = y == x // ERROR incomparable types in type set + _ = y == y + + _ = x /* ERROR type parameter P is not comparable with < */ < y +} diff --git a/src/internal/types/testdata/fixedbugs/issue48819.go b/src/internal/types/testdata/fixedbugs/issue48819.go new file mode 100644 index 0000000..5d61803 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48819.go @@ -0,0 +1,15 @@ +// Copyright 2021 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. + +package p + +import "unsafe" + +type T /* ERROR invalid recursive type: T refers to itself */ struct { + T +} + +func _(t T) { + _ = unsafe.Sizeof(t) // should not go into infinite recursion here +} diff --git a/src/internal/types/testdata/fixedbugs/issue48827.go b/src/internal/types/testdata/fixedbugs/issue48827.go new file mode 100644 index 0000000..aa1d12a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48827.go @@ -0,0 +1,19 @@ +// Copyright 2021 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. + +package p + +type G[P any] int + +type ( + _ G[int] + _ G[G /* ERROR "cannot use.*without instantiation" */] + _ bool /* ERROR "invalid operation: bool\[int\] \(bool is not a generic type\)" */ [int] + _ bool /* ERROR "invalid operation: bool\[G\] \(bool is not a generic type\)" */[G] +) + +// The example from the issue. +func _() { + _ = &([10]bool /* ERROR "invalid operation.*bool is not a generic type" */ [1 /* ERROR "expected type" */ ]{}) +} diff --git a/src/internal/types/testdata/fixedbugs/issue48951.go b/src/internal/types/testdata/fixedbugs/issue48951.go new file mode 100644 index 0000000..c94b027 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48951.go @@ -0,0 +1,21 @@ +// 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. + +package p + +type ( + A1[P any] [10]A1 /* ERROR invalid recursive type */ [P] + A2[P any] [10]A2 /* ERROR invalid recursive type */ [*P] + A3[P any] [10]*A3[P] + + L1[P any] []L1[P] + + S1[P any] struct{ f S1 /* ERROR invalid recursive type */ [P] } + S2[P any] struct{ f S2 /* ERROR invalid recursive type */ [*P] } // like example in issue + S3[P any] struct{ f *S3[P] } + + I1[P any] interface{ I1 /* ERROR invalid recursive type */ [P] } + I2[P any] interface{ I2 /* ERROR invalid recursive type */ [*P] } + I3[P any] interface{ *I3 /* ERROR interface contains type constraints */ [P] } +) diff --git a/src/internal/types/testdata/fixedbugs/issue48962.go b/src/internal/types/testdata/fixedbugs/issue48962.go new file mode 100644 index 0000000..05c681d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48962.go @@ -0,0 +1,13 @@ +// Copyright 2022 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. + +package p + +type T0[P any] struct { + f P +} + +type T1 /* ERROR invalid recursive type */ struct { + _ T0[T1] +} diff --git a/src/internal/types/testdata/fixedbugs/issue48974.go b/src/internal/types/testdata/fixedbugs/issue48974.go new file mode 100644 index 0000000..d8ff7c8 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue48974.go @@ -0,0 +1,22 @@ +// Copyright 2021 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. + +package p + +type Fooer interface { + Foo() +} + +type Fooable[F /* ERROR instantiation cycle */ Fooer] struct { + ptr F +} + +func (f *Fooable[F]) Adapter() *Fooable[*FooerImpl[F]] { + return &Fooable[*FooerImpl[F]]{&FooerImpl[F]{}} +} + +type FooerImpl[F Fooer] struct { +} + +func (fi *FooerImpl[F]) Foo() {} diff --git a/src/internal/types/testdata/fixedbugs/issue49003.go b/src/internal/types/testdata/fixedbugs/issue49003.go new file mode 100644 index 0000000..ece1a27 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49003.go @@ -0,0 +1,10 @@ +// Copyright 2021 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. + +package p + +func f(s string) int { + for range s { + } +} // ERROR missing return diff --git a/src/internal/types/testdata/fixedbugs/issue49005.go b/src/internal/types/testdata/fixedbugs/issue49005.go new file mode 100644 index 0000000..5f551b9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49005.go @@ -0,0 +1,31 @@ +// Copyright 2021 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. + +package p + +type T1 interface{ M() } + +func F1() T1 + +var _ = F1().(*X1 /* ERROR undefined: X1 */) + +func _() { + switch F1().(type) { + case *X1 /* ERROR undefined: X1 */ : + } +} + +type T2 interface{ M() } + +func F2() T2 + +var _ = F2 /* ERROR impossible type assertion: F2\(\)\.\(\*X2\)\n\t\*X2 does not implement T2 \(missing method M\) */ ().(*X2) + +type X2 struct{} + +func _() { + switch F2().(type) { + case * /* ERROR impossible type switch case: \*X2\n\tF2\(\) \(value of type T2\) cannot have dynamic type \*X2 \(missing method M\) */ X2: + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue49043.go b/src/internal/types/testdata/fixedbugs/issue49043.go new file mode 100644 index 0000000..3971cf8 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49043.go @@ -0,0 +1,24 @@ +// Copyright 2021 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. + +package p + +// The example from the issue. +type ( + N[P any] M /* ERROR invalid recursive type */ [P] + M[P any] N[P] +) + +// A slightly more complicated case. +type ( + A[P any] B /* ERROR invalid recursive type */ [P] + B[P any] C[P] + C[P any] A[P] +) + +// Confusing but valid (note that `type T *T` is valid). +type ( + N1[P any] *M1[P] + M1[P any] *N1[P] +) diff --git a/src/internal/types/testdata/fixedbugs/issue49112.go b/src/internal/types/testdata/fixedbugs/issue49112.go new file mode 100644 index 0000000..dea2608 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49112.go @@ -0,0 +1,15 @@ +// Copyright 2021 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. + +package p + +func f[P int](P) {} + +func _() { + _ = f[int] + _ = f[[ /* ERROR \[\]int does not satisfy int */ ]int] + + f(0) + f/* ERROR \[\]int does not satisfy int */ ([]int{}) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49179.go b/src/internal/types/testdata/fixedbugs/issue49179.go new file mode 100644 index 0000000..2ddfa33 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49179.go @@ -0,0 +1,37 @@ +// Copyright 2021 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. + +package p + +func f1[P int | string]() {} +func f2[P ~int | string | float64]() {} +func f3[P int](x P) {} + +type myInt int +type myFloat float64 + +func _() { + _ = f1[int] + _ = f1[myInt /* ERROR possibly missing ~ for int in int \| string */] + _ = f2[myInt] + _ = f2[myFloat /* ERROR possibly missing ~ for float64 in ~int \| string \| float64 */] + var x myInt + f3 /* ERROR myInt does not satisfy int \(possibly missing ~ for int in int\) */ (x) +} + +// test case from the issue + +type SliceConstraint[T any] interface { + []T +} + +func Map[S SliceConstraint[E], E any](s S, f func(E) E) S { + return s +} + +type MySlice []int + +func f(s MySlice) { + Map[MySlice /* ERROR MySlice does not satisfy SliceConstraint\[int\] \(possibly missing ~ for \[\]int in SliceConstraint\[int\]\) */, int](s, nil) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49242.go b/src/internal/types/testdata/fixedbugs/issue49242.go new file mode 100644 index 0000000..524a0cb --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49242.go @@ -0,0 +1,27 @@ +// Copyright 2021 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. + +package p + +func _[P int](x P) int { + return x // ERROR cannot use x .* as int value in return statement +} + +func _[P int]() int { + return P /* ERROR cannot use P\(1\) .* as int value in return statement */ (1) +} + +func _[P int](x int) P { + return x // ERROR cannot use x .* as P value in return statement +} + +func _[P, Q any](x P) Q { + return x // ERROR cannot use x .* as Q value in return statement +} + +// test case from issue +func F[G interface{ uint }]() int { + f := func(uint) int { return 0 } + return f(G /* ERROR cannot use G\(1\) .* as uint value in argument to f */ (1)) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49247.go b/src/internal/types/testdata/fixedbugs/issue49247.go new file mode 100644 index 0000000..5be6001 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49247.go @@ -0,0 +1,20 @@ +// Copyright 2021 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. + +package p + +type integer interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +func Add1024[T integer](s []T) { + for i, v := range s { + s[i] = v + 1024 // ERROR cannot convert 1024 \(untyped int constant\) to type T + } +} + +func f[T interface{ int8 }]() { + println(T(1024 /* ERROR cannot convert 1024 \(untyped int value\) to type T */)) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49276.go b/src/internal/types/testdata/fixedbugs/issue49276.go new file mode 100644 index 0000000..ab5794a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49276.go @@ -0,0 +1,46 @@ +// Copyright 2021 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. + +package p + +import "unsafe" + +type S /* ERROR invalid recursive type S */ struct { + _ [unsafe.Sizeof(s)]byte +} + +var s S + +// Since f is a pointer, this case could be valid. +// But it's pathological and not worth the expense. +type T struct { + f *[unsafe.Sizeof(T /* ERROR invalid recursive type */ {})]int +} + +// a mutually recursive case using unsafe.Sizeof +type ( + A1 struct { + _ [unsafe.Sizeof(B1{})]int + } + + B1 struct { + _ [unsafe.Sizeof(A1 /* ERROR invalid recursive type */ {})]int + } +) + +// a mutually recursive case using len +type ( + A2 struct { + f [len(B2{}.f)]int + } + + B2 struct { + f [len(A2 /* ERROR invalid recursive type */ {}.f)]int + } +) + +// test case from issue +type a struct { + _ [42 - unsafe.Sizeof(a /* ERROR invalid recursive type */ {})]byte +} diff --git a/src/internal/types/testdata/fixedbugs/issue49296.go b/src/internal/types/testdata/fixedbugs/issue49296.go new file mode 100644 index 0000000..98ad6f5 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49296.go @@ -0,0 +1,20 @@ +// Copyright 2021 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. + +package p + +func _[ + T0 any, + T1 []int, + T2 ~float64 | ~complex128 | chan int, +]() { + _ = T0(nil /* ERROR cannot convert nil to type T0 */ ) + _ = T1(1 /* ERROR cannot convert 1 .* to type T1 */ ) + _ = T2(2 /* ERROR cannot convert 2 .* to type T2 */ ) +} + +// test case from issue +func f[T interface{[]int}]() { + _ = T(1 /* ERROR cannot convert */ ) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49439.go b/src/internal/types/testdata/fixedbugs/issue49439.go new file mode 100644 index 0000000..b8ad495 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49439.go @@ -0,0 +1,26 @@ +// Copyright 2021 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. + +package p + +import "unsafe" + +type T0 /* ERROR invalid recursive type */ [P T0[P]] struct{} + +type T1 /* ERROR invalid recursive type */ [P T2[P]] struct{} +type T2[P T1[P]] struct{} + +type T3 /* ERROR invalid recursive type */ [P interface{ ~struct{ f T3[int] } }] struct{} + +// valid cycle in M +type N[P M[P]] struct{} +type M[Q any] struct { F *M[Q] } + +// "crazy" case +type TC[P [unsafe.Sizeof(func() { + type T [P [unsafe.Sizeof(func(){})]byte] struct{} +})]byte] struct{} + +// test case from issue +type X /* ERROR invalid recursive type */ [T any, PT X[T]] interface{} diff --git a/src/internal/types/testdata/fixedbugs/issue49482.go b/src/internal/types/testdata/fixedbugs/issue49482.go new file mode 100644 index 0000000..2b9e748 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49482.go @@ -0,0 +1,26 @@ +// Copyright 2022 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. + +package p + +// The following is OK, per the special handling for type literals discussed in issue #49482. +type _[P *struct{}] struct{} +type _[P *int,] int +type _[P (*int),] int + +const P = 2 // declare P to avoid noisy 'undefined' errors below. + +// The following parse as invalid array types due to parsing ambiguitiues. +type _ [P *int /* ERROR "int \(type\) is not an expression" */ ]int +type _ [P /* ERROR non-function P */ (*int)]int + +// Adding a trailing comma or an enclosing interface resolves the ambiguity. +type _[P *int,] int +type _[P (*int),] int +type _[P interface{*int}] int +type _[P interface{(*int)}] int + +// The following parse correctly as valid generic types. +type _[P *struct{} | int] struct{} +type _[P *struct{} | ~int] struct{} diff --git a/src/internal/types/testdata/fixedbugs/issue49541.go b/src/internal/types/testdata/fixedbugs/issue49541.go new file mode 100644 index 0000000..c8499c1 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49541.go @@ -0,0 +1,45 @@ +// Copyright 2022 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. + +package p + +type S[A, B any] struct { + f int +} + +func (S[A, B]) m() {} + +// TODO(gri): with type-type inference enabled we should only report one error +// below. See issue #50588. + +func _[A any](s S /* ERROR got 1 arguments but 2 type parameters */ [A]) { + // we should see no follow-on errors below + s.f = 1 + s.m() +} + +// another test case from the issue + +func _() { + X(Interface[*F /* ERROR got 1 arguments but 2 type parameters */ [string]](Impl{})) +} + +func X[Q Qer](fs Interface[Q]) { +} + +type Impl struct{} + +func (Impl) M() {} + +type Interface[Q Qer] interface { + M() +} + +type Qer interface { + Q() +} + +type F[A, B any] struct{} + +func (f *F[A, B]) Q() {} diff --git a/src/internal/types/testdata/fixedbugs/issue49579.go b/src/internal/types/testdata/fixedbugs/issue49579.go new file mode 100644 index 0000000..ee2d94a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49579.go @@ -0,0 +1,17 @@ +// Copyright 2021 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. + +package p + +type I[F any] interface { + Q(*F) +} + +func G[F any]() I[any] { + return g /* ERROR cannot use g\[F\]{} .* as I\[any\] value in return statement: g\[F\] does not implement I\[any\] \(method Q has pointer receiver\) */ [F]{} +} + +type g[F any] struct{} + +func (*g[F]) Q(*any) {} diff --git a/src/internal/types/testdata/fixedbugs/issue49592.go b/src/internal/types/testdata/fixedbugs/issue49592.go new file mode 100644 index 0000000..846deaa --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49592.go @@ -0,0 +1,11 @@ +// Copyright 2021 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. + +package p + +func _() { + var x *interface{} + var y interface{} + _ = x == y +} diff --git a/src/internal/types/testdata/fixedbugs/issue49602.go b/src/internal/types/testdata/fixedbugs/issue49602.go new file mode 100644 index 0000000..208501f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49602.go @@ -0,0 +1,19 @@ +// Copyright 2021 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. + +package p + +type M interface { + m() +} + +type C interface { + comparable +} + +type _ interface { + int | M // ERROR cannot use p\.M in union \(p\.M contains methods\) + int | comparable // ERROR cannot use comparable in union + int | C // ERROR cannot use p\.C in union \(p\.C embeds comparable\) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49705.go b/src/internal/types/testdata/fixedbugs/issue49705.go new file mode 100644 index 0000000..5b5fba2 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49705.go @@ -0,0 +1,14 @@ +// Copyright 2021 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. + +package p + +type Integer interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +func shl[I Integer](n int) I { + return 1 << n +} diff --git a/src/internal/types/testdata/fixedbugs/issue49735.go b/src/internal/types/testdata/fixedbugs/issue49735.go new file mode 100644 index 0000000..5087022 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49735.go @@ -0,0 +1,11 @@ +// Copyright 2022 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. + +package p + +func _[P1 any, P2 ~byte](s1 P1, s2 P2) { + _ = append(nil /* ERROR first argument to append must be a slice; have untyped nil */ , 0) + _ = append(s1 /* ERROR s1 .* has no core type */ , 0) + _ = append(s2 /* ERROR s2 .* has core type byte */ , 0) +} diff --git a/src/internal/types/testdata/fixedbugs/issue49739.go b/src/internal/types/testdata/fixedbugs/issue49739.go new file mode 100644 index 0000000..7feb563 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49739.go @@ -0,0 +1,23 @@ +// Copyright 2021 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. + +// Verify that we get an empty type set (not just an error) +// when using an invalid ~A. + +package p + +type A int +type C interface { + ~ /* ERROR invalid use of ~ */ A +} + +func f[_ C]() {} +func g[_ interface{ C }]() {} +func h[_ C | int]() {} + +func _() { + _ = f[int /* ERROR cannot satisfy C \(empty type set\) */] + _ = g[int /* ERROR cannot satisfy interface{C} \(empty type set\) */] + _ = h[int] +} diff --git a/src/internal/types/testdata/fixedbugs/issue49864.go b/src/internal/types/testdata/fixedbugs/issue49864.go new file mode 100644 index 0000000..0437e74 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue49864.go @@ -0,0 +1,9 @@ +// Copyright 2021 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. + +package p + +func _[P ~int, Q any](p P) { + _ = Q(p /* ERROR cannot convert */ ) +} diff --git a/src/internal/types/testdata/fixedbugs/issue50259.go b/src/internal/types/testdata/fixedbugs/issue50259.go new file mode 100644 index 0000000..6df8c64 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50259.go @@ -0,0 +1,18 @@ +// Copyright 2022 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. + +package p + +var x T[B] + +type T[_ any] struct{} +type A T[B] +type B = T[A] + +// test case from issue + +var v Box[Step] +type Box[T any] struct{} +type Step = Box[StepBox] +type StepBox Box[Step] diff --git a/src/internal/types/testdata/fixedbugs/issue50276.go b/src/internal/types/testdata/fixedbugs/issue50276.go new file mode 100644 index 0000000..97e477e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50276.go @@ -0,0 +1,39 @@ +// Copyright 2022 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. + +package p + +// simplified test case + +type transform[T any] struct{} +type pair[S any] struct {} + +var _ transform[step] + +type box transform[step] +type step = pair[box] + +// test case from issue + +type Transform[T any] struct{ hold T } +type Pair[S, T any] struct { + First S + Second T +} + +var first Transform[Step] + +// This line doesn't use the Step alias, and it compiles fine if you uncomment it. +var second Transform[Pair[Box, interface{}]] + +type Box *Transform[Step] + +// This line is the same as the `first` line, but it comes after the Box declaration and +// does not break the compile. +var third Transform[Step] + +type Step = Pair[Box, interface{}] + +// This line also does not break the compile +var fourth Transform[Step] diff --git a/src/internal/types/testdata/fixedbugs/issue50281.go b/src/internal/types/testdata/fixedbugs/issue50281.go new file mode 100644 index 0000000..f333e81 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50281.go @@ -0,0 +1,26 @@ +// Copyright 2022 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. + +package p + +func _[S string | []byte](s S) { + var buf []byte + _ = append(buf, s...) +} + +func _[S ~string | ~[]byte](s S) { + var buf []byte + _ = append(buf, s...) +} + +// test case from issue + +type byteseq interface { + string | []byte +} + +// This should allow to eliminate the two functions above. +func AppendByteString[source byteseq](buf []byte, s source) []byte { + return append(buf, s[1:6]...) +} diff --git a/src/internal/types/testdata/fixedbugs/issue50321.go b/src/internal/types/testdata/fixedbugs/issue50321.go new file mode 100644 index 0000000..199e66e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50321.go @@ -0,0 +1,8 @@ +// Copyright 2021 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. + +package p + +func Ln[A A /* ERROR cannot use a type parameter as constraint */ ](p A) { +} diff --git a/src/internal/types/testdata/fixedbugs/issue50372.go b/src/internal/types/testdata/fixedbugs/issue50372.go new file mode 100644 index 0000000..4c9b65a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50372.go @@ -0,0 +1,27 @@ +// Copyright 2021 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. + +package p + +func _(s []int) { + var i, j, k, l int + _, _, _, _ = i, j, k, l + + for range s {} + for i = range s {} + for i, j = range s {} + for i, j, k /* ERROR range clause permits at most two iteration variables|at most 2 expressions */ = range s {} + for i, j, k, l /* ERROR range clause permits at most two iteration variables|at most 2 expressions */ = range s {} +} + +func _(s chan int) { + var i, j, k, l int + _, _, _, _ = i, j, k, l + + for range s {} + for i = range s {} + for i, j /* ERROR range over .* permits only one iteration variable */ = range s {} + for i, j, k /* ERROR range over .* permits only one iteration variable|at most 2 expressions */ = range s {} + for i, j, k, l /* ERROR range over .* permits only one iteration variable|at most 2 expressions */ = range s {} +} diff --git a/src/internal/types/testdata/fixedbugs/issue50417.go b/src/internal/types/testdata/fixedbugs/issue50417.go new file mode 100644 index 0000000..69ebf31 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50417.go @@ -0,0 +1,68 @@ +// Copyright 2022 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. + +// Field accesses through type parameters are disabled +// until we have a more thorough understanding of the +// implications on the spec. See issue #51576. + +package p + +type Sf struct { + f int +} + +func f0[P Sf](p P) { + _ = p.f // ERROR p\.f undefined + p.f /* ERROR p\.f undefined */ = 0 +} + +func f0t[P ~struct{f int}](p P) { + _ = p.f // ERROR p\.f undefined + p.f /* ERROR p\.f undefined */ = 0 +} + +var _ = f0[Sf] +var _ = f0t[Sf] + +var _ = f0[Sm /* ERROR does not satisfy */ ] +var _ = f0t[Sm /* ERROR does not satisfy */ ] + +func f1[P interface{ Sf; m() }](p P) { + _ = p.f // ERROR p\.f undefined + p.f /* ERROR p\.f undefined */ = 0 + p.m() +} + +var _ = f1[Sf /* ERROR missing method m */ ] +var _ = f1[Sm /* ERROR does not satisfy */ ] + +type Sm struct {} + +func (Sm) m() {} + +type Sfm struct { + f int +} + +func (Sfm) m() {} + +func f2[P interface{ Sfm; m() }](p P) { + _ = p.f // ERROR p\.f undefined + p.f /* ERROR p\.f undefined */ = 0 + p.m() +} + +var _ = f2[Sfm] + +// special case: core type is a named pointer type + +type PSfm *Sfm + +func f3[P interface{ PSfm }](p P) { + _ = p.f // ERROR p\.f undefined + p.f /* ERROR p\.f undefined */ = 0 + p.m /* ERROR type P has no field or method m */ () +} + +var _ = f3[PSfm] diff --git a/src/internal/types/testdata/fixedbugs/issue50426.go b/src/internal/types/testdata/fixedbugs/issue50426.go new file mode 100644 index 0000000..17ec0ce --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50426.go @@ -0,0 +1,44 @@ +// Copyright 2022 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. + +package p + +type A1 [2]uint64 +type A2 [2]uint64 + +func (a A1) m() A1 { return a } +func (a A2) m() A2 { return a } + +func f[B any, T interface { + A1 | A2 + m() T +}](v T) { +} + +func _() { + var v A2 + // Use function type inference to infer type A2 for T. + // Don't use constraint type inference before function + // type inference for typed arguments, otherwise it would + // infer type [2]uint64 for T which doesn't have method m + // (was the bug). + f[int](v) +} + +// Keep using constraint type inference before function type +// inference for untyped arguments so we infer type float64 +// for E below, and not int (which would not work). +func g[S ~[]E, E any](S, E) {} + +func _() { + var s []float64 + g[[]float64](s, 0) +} + +// Keep using constraint type inference after function +// type inference for untyped arguments so we infer +// missing type arguments for which we only have the +// untyped arguments as starting point. +func h[E any, R []E](v E) R { return R{v} } +func _() []int { return h(0) } diff --git a/src/internal/types/testdata/fixedbugs/issue50427.go b/src/internal/types/testdata/fixedbugs/issue50427.go new file mode 100644 index 0000000..d89d63e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50427.go @@ -0,0 +1,23 @@ +// Copyright 2022 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. + +package p + +// The parser no longer parses type parameters for methods. +// In the past, type checking the code below led to a crash (#50427). + +type T interface{ m[ /* ERROR "must have no type parameters" */ P any]() } + +func _(t T) { + var _ interface{ m[ /* ERROR "must have no type parameters" */ P any](); n() } = t /* ERROR "does not implement" */ +} + +type S struct{} + +func (S) m[ /* ERROR "must have no type parameters" */ P any]() {} + +func _(s S) { + var _ interface{ m[ /* ERROR "must have no type parameters" */ P any](); n() } = s /* ERROR "does not implement" */ + +} diff --git a/src/internal/types/testdata/fixedbugs/issue50450.go b/src/internal/types/testdata/fixedbugs/issue50450.go new file mode 100644 index 0000000..bae3111 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50450.go @@ -0,0 +1,11 @@ +// Copyright 2022 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. + +package p + +type S struct{} + +func f[P S]() {} + +var _ = f[S] diff --git a/src/internal/types/testdata/fixedbugs/issue50516.go b/src/internal/types/testdata/fixedbugs/issue50516.go new file mode 100644 index 0000000..f73015e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50516.go @@ -0,0 +1,13 @@ +// Copyright 2022 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. + +package p + +func _[P struct{ f int }](x P) { + _ = x.g // ERROR type P has no field or method g +} + +func _[P struct{ f int } | struct{ g int }](x P) { + _ = x.g // ERROR type P has no field or method g +} diff --git a/src/internal/types/testdata/fixedbugs/issue50646.go b/src/internal/types/testdata/fixedbugs/issue50646.go new file mode 100644 index 0000000..ed7261c --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50646.go @@ -0,0 +1,28 @@ +// -oldComparableSemantics + +// Copyright 2022 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. + +package p + +func f1[_ comparable]() {} +func f2[_ interface{ comparable }]() {} + +type T interface{ m() } + +func _[P comparable, Q ~int, R any]() { + _ = f1[int] + _ = f1[T /* ERROR T does not satisfy comparable */ ] + _ = f1[any /* ERROR any does not satisfy comparable */ ] + _ = f1[P] + _ = f1[Q] + _ = f1[R /* ERROR R does not satisfy comparable */] + + _ = f2[int] + _ = f2[T /* ERROR T does not satisfy comparable */ ] + _ = f2[any /* ERROR any does not satisfy comparable */ ] + _ = f2[P] + _ = f2[Q] + _ = f2[R /* ERROR R does not satisfy comparable */] +} diff --git a/src/internal/types/testdata/fixedbugs/issue50729.go b/src/internal/types/testdata/fixedbugs/issue50729.go new file mode 100644 index 0000000..fe19fdf --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50729.go @@ -0,0 +1,19 @@ +// Copyright 2022 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. + +package p + +// version 1 +var x1 T1[B1] + +type T1[_ any] struct{} +type A1 T1[B1] +type B1 = T1[A1] + +// version 2 +type T2[_ any] struct{} +type A2 T2[B2] +type B2 = T2[A2] + +var x2 T2[B2] diff --git a/src/internal/types/testdata/fixedbugs/issue50755.go b/src/internal/types/testdata/fixedbugs/issue50755.go new file mode 100644 index 0000000..afc7b24 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50755.go @@ -0,0 +1,47 @@ +// Copyright 2022 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. + +package p + +// The core type of M2 unifies with the type of m1 +// during function argument type inference. +// M2's constraint is unnamed. +func f1[K1 comparable, E1 any](m1 map[K1]E1) {} + +func f2[M2 map[string]int](m2 M2) { + f1(m2) +} + +// The core type of M3 unifies with the type of m1 +// during function argument type inference. +// M3's constraint is named. +type Map3 map[string]int + +func f3[M3 Map3](m3 M3) { + f1(m3) +} + +// The core type of M5 unifies with the core type of M4 +// during constraint type inference. +func f4[M4 map[K4]int, K4 comparable](m4 M4) {} + +func f5[M5 map[K5]int, K5 comparable](m5 M5) { + f4(m5) +} + +// test case from issue + +func Copy[MC ~map[KC]VC, KC comparable, VC any](dst, src MC) { + for k, v := range src { + dst[k] = v + } +} + +func Merge[MM ~map[KM]VM, KM comparable, VM any](ms ...MM) MM { + result := MM{} + for _, m := range ms { + Copy(result, m) + } + return result +} diff --git a/src/internal/types/testdata/fixedbugs/issue50779.go b/src/internal/types/testdata/fixedbugs/issue50779.go new file mode 100644 index 0000000..fe68c28 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50779.go @@ -0,0 +1,23 @@ +// Copyright 2022 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. + +package p + +type AC interface { + C +} + +type ST []int + +type R[S any, P any] struct{} + +type SR = R[SS, ST] + +type SS interface { + NSR(any) *SR // ERROR invalid use of type alias SR in recursive type +} + +type C interface { + NSR(any) *SR +} diff --git a/src/internal/types/testdata/fixedbugs/issue50782.go b/src/internal/types/testdata/fixedbugs/issue50782.go new file mode 100644 index 0000000..0e7b712 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50782.go @@ -0,0 +1,47 @@ +// Copyright 2022 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. + +// Field accesses through type parameters are disabled +// until we have a more thorough understanding of the +// implications on the spec. See issue #51576. + +package p + +// The first example from the issue. +type Numeric interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// numericAbs matches numeric types with an Abs method. +type numericAbs[T Numeric] interface { + ~struct{ Value T } + Abs() T +} + +// AbsDifference computes the absolute value of the difference of +// a and b, where the absolute value is determined by the Abs method. +func absDifference[T numericAbs[T /* ERROR T does not satisfy Numeric */]](a, b T) T { + // Field accesses are not permitted for now. Keep an error so + // we can find and fix this code once the situation changes. + return a.Value // ERROR a\.Value undefined + // TODO: The error below should probably be positioned on the '-'. + // d := a /* ERROR "invalid operation: operator - not defined" */ .Value - b.Value + // return d.Abs() +} + +// The second example from the issue. +type T[P int] struct{ f P } + +func _[P T[P /* ERROR "P does not satisfy int" */ ]]() {} + +// Additional tests +func _[P T[T /* ERROR "T\[P\] does not satisfy int" */ [P /* ERROR "P does not satisfy int" */ ]]]() {} +func _[P T[Q /* ERROR "Q does not satisfy int" */ ], Q T[P /* ERROR "P does not satisfy int" */ ]]() {} +func _[P T[Q], Q int]() {} + +type C[P comparable] struct{ f P } +func _[P C[C[P]]]() {} +func _[P C[C /* ERROR "C\[Q\] does not satisfy comparable" */ [Q /* ERROR "Q does not satisfy comparable" */]], Q func()]() {} +func _[P [10]C[P]]() {} +func _[P struct{ f C[C[P]]}]() {} diff --git a/src/internal/types/testdata/fixedbugs/issue50816.go b/src/internal/types/testdata/fixedbugs/issue50816.go new file mode 100644 index 0000000..e7e31d9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50816.go @@ -0,0 +1,23 @@ +// Copyright 2022 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. + +package pkg + +type I interface { + Foo() +} + +type T1 struct{} + +func (T1) foo() {} + +type T2 struct{} + +func (T2) foo() string { return "" } + +func _() { + var i I + _ = i /* ERROR impossible type assertion: i\.\(T1\)\n\tT1 does not implement I \(missing method Foo\)\n\t\thave foo\(\)\n\t\twant Foo\(\) */ .(T1) + _ = i /* ERROR impossible type assertion: i\.\(T2\)\n\tT2 does not implement I \(missing method Foo\)\n\t\thave foo\(\) string\n\t\twant Foo\(\) */ .(T2) +} diff --git a/src/internal/types/testdata/fixedbugs/issue50833.go b/src/internal/types/testdata/fixedbugs/issue50833.go new file mode 100644 index 0000000..e912e4d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50833.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +package p + +type ( + S struct{ f int } + PS *S +) + +func a() []*S { return []*S{{f: 1}} } +func b() []PS { return []PS{{f: 1}} } + +func c[P *S]() []P { return []P{{f: 1}} } +func d[P PS]() []P { return []P{{f: 1}} } diff --git a/src/internal/types/testdata/fixedbugs/issue50912.go b/src/internal/types/testdata/fixedbugs/issue50912.go new file mode 100644 index 0000000..f161925 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50912.go @@ -0,0 +1,19 @@ +// Copyright 2022 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. + +package p + +func Real[P ~complex128](x P) { + _ = real(x /* ERROR not supported */ ) +} + +func Imag[P ~complex128](x P) { + _ = imag(x /* ERROR not supported */ ) +} + +func Complex[P ~float64](x P) { + _ = complex(x /* ERROR not supported */ , 0) + _ = complex(0 /* ERROR not supported */ , x) + _ = complex(x /* ERROR not supported */ , x) +} diff --git a/src/internal/types/testdata/fixedbugs/issue50918.go b/src/internal/types/testdata/fixedbugs/issue50918.go new file mode 100644 index 0000000..41604b8 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50918.go @@ -0,0 +1,21 @@ +// Copyright 2022 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. + +package p + +type thing1 struct { + things []string +} + +type thing2 struct { + things []thing1 +} + +func _() { + var a1, b1 thing1 + _ = a1 /* ERROR struct containing \[\]string cannot be compared */ == b1 + + var a2, b2 thing2 + _ = a2 /* ERROR struct containing \[\]thing1 cannot be compared */ == b2 +} diff --git a/src/internal/types/testdata/fixedbugs/issue50929.go b/src/internal/types/testdata/fixedbugs/issue50929.go new file mode 100644 index 0000000..45e0751 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50929.go @@ -0,0 +1,68 @@ +// Copyright 2022 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 is tested when running "go test -run Manual" +// without source arguments. Use for one-off debugging. + +package p + +import "fmt" + +type F[A, B any] int + +func G[A, B any](F[A, B]) { +} + +func _() { + // TODO(gri) only report one error below (issue #50932) + var x F /* ERROR got 1 arguments but 2 type parameters */ [int] + G(x /* ERROR does not match */) +} + +// test case from issue +// (lots of errors but doesn't crash anymore) + +type RC[G any, RG any] interface { + ~[]RG +} + +type RG[G any] struct{} + +type RSC[G any] []*RG[G] + +type M[Rc RC[G, RG], G any, RG any] struct { + Fn func(Rc) +} + +type NFn[Rc RC[G, RG], G any, RG any] func(Rc) + +func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) { + var empty Rc + nFn(empty) +} + +func NSG[G any](c RSC[G]) { + fmt.Println(c) +} + +func MMD[Rc RC /* ERROR got 1 arguments */ [RG], RG any, G any]() M /* ERROR got 2 arguments */ [Rc, RG] { + + var nFn NFn /* ERROR got 2 arguments */ [Rc, RG] + + var empty Rc + switch any(empty).(type) { + case BC /* ERROR undefined: BC */ : + + case RSC[G]: + nFn = NSG /* ERROR cannot use NSG\[G\] */ [G] + } + + return M /* ERROR got 2 arguments */ [Rc, RG]{ + Fn: func(rc Rc) { + NC(nFn /* ERROR does not match */ ) + }, + } + + return M /* ERROR got 2 arguments */ [Rc, RG]{} +} diff --git a/src/internal/types/testdata/fixedbugs/issue50965.go b/src/internal/types/testdata/fixedbugs/issue50965.go new file mode 100644 index 0000000..bf2dcc9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue50965.go @@ -0,0 +1,17 @@ +// Copyright 2022 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. + +package p + +func _(x int, c string) { + switch x { + case c /* ERROR invalid case c in switch on x \(mismatched types string and int\) */ : + } +} + +func _(x, c []int) { + switch x { + case c /* ERROR invalid case c in switch on x \(slice can only be compared to nil\) */ : + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue51025.go b/src/internal/types/testdata/fixedbugs/issue51025.go new file mode 100644 index 0000000..207b06e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51025.go @@ -0,0 +1,38 @@ +// Copyright 2022 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. + +package p + +var _ interface{ m() } = struct /* ERROR m is a field, not a method */ { + m func() +}{} + +var _ interface{ m() } = & /* ERROR m is a field, not a method */ struct { + m func() +}{} + +var _ interface{ M() } = struct /* ERROR missing method M */ { + m func() +}{} + +var _ interface{ M() } = & /* ERROR missing method M */ struct { + m func() +}{} + +// test case from issue +type I interface{ m() } +type T struct{ m func() } +type M struct{} + +func (M) m() {} + +func _() { + var t T + var m M + var i I + + i = m + i = t // ERROR m is a field, not a method + _ = i +} diff --git a/src/internal/types/testdata/fixedbugs/issue51048.go b/src/internal/types/testdata/fixedbugs/issue51048.go new file mode 100644 index 0000000..5830837 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51048.go @@ -0,0 +1,11 @@ +// Copyright 2022 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. + +package p + +func _[P int]() { + _ = f[P] +} + +func f[T int]() {} diff --git a/src/internal/types/testdata/fixedbugs/issue51145.go b/src/internal/types/testdata/fixedbugs/issue51145.go new file mode 100644 index 0000000..b84391d --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51145.go @@ -0,0 +1,18 @@ +// Copyright 2022 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. + +package p + +import "fmt" + +type ( + _ [fmt /* ERROR invalid array length fmt */ ]int + _ [float64 /* ERROR invalid array length float64 */ ]int + _ [f /* ERROR invalid array length f */ ]int + _ [nil /* ERROR invalid array length nil */ ]int +) + +func f() + +var _ fmt.Stringer // use fmt diff --git a/src/internal/types/testdata/fixedbugs/issue51158.go b/src/internal/types/testdata/fixedbugs/issue51158.go new file mode 100644 index 0000000..3edc505 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51158.go @@ -0,0 +1,18 @@ +// Copyright 2022 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. + +package p + +// Type checking the following code should not cause an infinite recursion. +func f[M map[K]int, K comparable](m M) { + f(m) +} + +// Equivalent code using mutual recursion. +func f1[M map[K]int, K comparable](m M) { + f2(m) +} +func f2[M map[K]int, K comparable](m M) { + f1(m) +} diff --git a/src/internal/types/testdata/fixedbugs/issue51229.go b/src/internal/types/testdata/fixedbugs/issue51229.go new file mode 100644 index 0000000..808b647 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51229.go @@ -0,0 +1,164 @@ +// Copyright 2022 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. + +package p + +// Constraint type inference should be independent of the +// ordering of the type parameter declarations. Try all +// permutations in the test case below. +// Permutations produced by https://go.dev/play/p/PHcZNGJTEBZ. + +func f00[S1 ~[]E1, S2 ~[]E2, E1 ~byte, E2 ~byte](S1, S2) {} +func f01[S2 ~[]E2, S1 ~[]E1, E1 ~byte, E2 ~byte](S1, S2) {} +func f02[E1 ~byte, S1 ~[]E1, S2 ~[]E2, E2 ~byte](S1, S2) {} +func f03[S1 ~[]E1, E1 ~byte, S2 ~[]E2, E2 ~byte](S1, S2) {} +func f04[S2 ~[]E2, E1 ~byte, S1 ~[]E1, E2 ~byte](S1, S2) {} +func f05[E1 ~byte, S2 ~[]E2, S1 ~[]E1, E2 ~byte](S1, S2) {} +func f06[E2 ~byte, S2 ~[]E2, S1 ~[]E1, E1 ~byte](S1, S2) {} +func f07[S2 ~[]E2, E2 ~byte, S1 ~[]E1, E1 ~byte](S1, S2) {} +func f08[S1 ~[]E1, E2 ~byte, S2 ~[]E2, E1 ~byte](S1, S2) {} +func f09[E2 ~byte, S1 ~[]E1, S2 ~[]E2, E1 ~byte](S1, S2) {} +func f10[S2 ~[]E2, S1 ~[]E1, E2 ~byte, E1 ~byte](S1, S2) {} +func f11[S1 ~[]E1, S2 ~[]E2, E2 ~byte, E1 ~byte](S1, S2) {} +func f12[S1 ~[]E1, E1 ~byte, E2 ~byte, S2 ~[]E2](S1, S2) {} +func f13[E1 ~byte, S1 ~[]E1, E2 ~byte, S2 ~[]E2](S1, S2) {} +func f14[E2 ~byte, S1 ~[]E1, E1 ~byte, S2 ~[]E2](S1, S2) {} +func f15[S1 ~[]E1, E2 ~byte, E1 ~byte, S2 ~[]E2](S1, S2) {} +func f16[E1 ~byte, E2 ~byte, S1 ~[]E1, S2 ~[]E2](S1, S2) {} +func f17[E2 ~byte, E1 ~byte, S1 ~[]E1, S2 ~[]E2](S1, S2) {} +func f18[E2 ~byte, E1 ~byte, S2 ~[]E2, S1 ~[]E1](S1, S2) {} +func f19[E1 ~byte, E2 ~byte, S2 ~[]E2, S1 ~[]E1](S1, S2) {} +func f20[S2 ~[]E2, E2 ~byte, E1 ~byte, S1 ~[]E1](S1, S2) {} +func f21[E2 ~byte, S2 ~[]E2, E1 ~byte, S1 ~[]E1](S1, S2) {} +func f22[E1 ~byte, S2 ~[]E2, E2 ~byte, S1 ~[]E1](S1, S2) {} +func f23[S2 ~[]E2, E1 ~byte, E2 ~byte, S1 ~[]E1](S1, S2) {} + +type myByte byte + +func _(a []byte, b []myByte) { + f00(a, b) + f01(a, b) + f02(a, b) + f03(a, b) + f04(a, b) + f05(a, b) + f06(a, b) + f07(a, b) + f08(a, b) + f09(a, b) + f10(a, b) + f11(a, b) + f12(a, b) + f13(a, b) + f14(a, b) + f15(a, b) + f16(a, b) + f17(a, b) + f18(a, b) + f19(a, b) + f20(a, b) + f21(a, b) + f22(a, b) + f23(a, b) +} + +// Constraint type inference may have to iterate. +// Again, the order of the type parameters shouldn't matter. + +func g0[S ~[]E, M ~map[string]S, E any](m M) {} +func g1[M ~map[string]S, S ~[]E, E any](m M) {} +func g2[E any, S ~[]E, M ~map[string]S](m M) {} +func g3[S ~[]E, E any, M ~map[string]S](m M) {} +func g4[M ~map[string]S, E any, S ~[]E](m M) {} +func g5[E any, M ~map[string]S, S ~[]E](m M) {} + +func _(m map[string][]byte) { + g0(m) + g1(m) + g2(m) + g3(m) + g4(m) + g5(m) +} + +// Worst-case scenario. +// There are 10 unknown type parameters. In each iteration of +// constraint type inference we infer one more, from right to left. +// Each iteration looks repeatedly at all 11 type parameters, +// requiring a total of 10*11 = 110 iterations with the current +// implementation. Pathological case. + +func h[K any, J ~*K, I ~*J, H ~*I, G ~*H, F ~*G, E ~*F, D ~*E, C ~*D, B ~*C, A ~*B](x A) {} + +func _(x **********int) { + h(x) +} + +// Examples with channel constraints and tilde. + +func ch1[P chan<- int]() (_ P) { return } // core(P) == chan<- int (single type, no tilde) +func ch2[P ~chan int]() { return } // core(P) == ~chan<- int (tilde) +func ch3[P chan E, E any](E) { return } // core(P) == chan<- E (single type, no tilde) +func ch4[P chan E | ~chan<- E, E any](E) { return } // core(P) == ~chan<- E (tilde) +func ch5[P chan int | chan<- int]() { return } // core(P) == chan<- int (not a single type) + +func _() { + // P can be inferred as there's a single specific type and no tilde. + var _ chan int = ch1 /* ERROR cannot use ch1.*value of type chan<- int */ () + var _ chan<- int = ch1() + + // P cannot be inferred as there's a tilde. + ch2 /* ERROR cannot infer P */ () + type myChan chan int + ch2[myChan]() + + // P can be inferred as there's a single specific type and no tilde. + var e int + ch3(e) + + // P cannot be inferred as there's more than one specific type and a tilde. + ch4 /* ERROR cannot infer P */ (e) + _ = ch4[chan int] + + // P cannot be inferred as there's more than one specific type. + ch5 /* ERROR cannot infer P */ () + ch5[chan<- int]() +} + +// test case from issue + +func equal[M1 ~map[K1]V1, M2 ~map[K2]V2, K1, K2 ~uint32, V1, V2 ~string](m1 M1, m2 M2) bool { + if len(m1) != len(m2) { + return false + } + for k, v1 := range m1 { + if v2, ok := m2[K2(k)]; !ok || V2(v1) != v2 { + return false + } + } + return true +} + +func equalFixed[K1, K2 ~uint32, V1, V2 ~string](m1 map[K1]V1, m2 map[K2]V2) bool { + if len(m1) != len(m2) { + return false + } + for k, v1 := range m1 { + if v2, ok := m2[K2(k)]; !ok || v1 != V1(v2) { + return false + } + } + return true +} + +type ( + someNumericID uint32 + someStringID string +) + +func _() { + foo := map[uint32]string{10: "bar"} + bar := map[someNumericID]someStringID{10: "bar"} + equal(foo, bar) +} diff --git a/src/internal/types/testdata/fixedbugs/issue51232.go b/src/internal/types/testdata/fixedbugs/issue51232.go new file mode 100644 index 0000000..3fa6a05 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51232.go @@ -0,0 +1,30 @@ +// Copyright 2022 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. + +package p + +type RC[RG any] interface { + ~[]RG +} + +type Fn[RCT RC[RG], RG any] func(RCT) + +type F[RCT RC[RG], RG any] interface { + Fn() Fn /* ERROR got 1 arguments */ [RCT] +} + +type concreteF[RCT RC[RG], RG any] struct { + makeFn func() Fn /* ERROR got 1 arguments */ [RCT] +} + +func (c *concreteF[RCT, RG]) Fn() Fn /* ERROR got 1 arguments */ [RCT] { + return c.makeFn() +} + +func NewConcrete[RCT RC[RG], RG any](Rc RCT) F /* ERROR got 1 arguments */ [RCT] { + // TODO(rfindley): eliminate the duplicate error below. + return & /* ERROR cannot use .* as F\[RCT\] */ concreteF /* ERROR got 1 arguments */ [RCT]{ + makeFn: nil, + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue51233.go b/src/internal/types/testdata/fixedbugs/issue51233.go new file mode 100644 index 0000000..9c15028 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51233.go @@ -0,0 +1,27 @@ +// Copyright 2022 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. + +package p + +// As of issue #51527, type-type inference has been disabled. + +type RC[RG any] interface { + ~[]RG +} + +type Fn[RCT RC[RG], RG any] func(RCT) + +type FFn[RCT RC[RG], RG any] func() Fn /* ERROR got 1 arguments */ [RCT] + +type F[RCT RC[RG], RG any] interface { + Fn() Fn /* ERROR got 1 arguments */ [RCT] +} + +type concreteF[RCT RC[RG], RG any] struct { + makeFn FFn /* ERROR got 1 arguments */ [RCT] +} + +func (c *concreteF[RCT, RG]) Fn() Fn /* ERROR got 1 arguments */ [RCT] { + return c.makeFn() +} diff --git a/src/internal/types/testdata/fixedbugs/issue51257.go b/src/internal/types/testdata/fixedbugs/issue51257.go new file mode 100644 index 0000000..be4b81f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51257.go @@ -0,0 +1,48 @@ +// -oldComparableSemantics + +// Copyright 2022 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. + +package p + +func f[_ comparable]() {} + +type S1 struct{ x int } +type S2 struct{ x any } +type S3 struct{ x [10]interface{ m() } } + +func _[P1 comparable, P2 S2]() { + _ = f[S1] + _ = f[S2 /* ERROR S2 does not satisfy comparable */ ] + _ = f[S3 /* ERROR S3 does not satisfy comparable */ ] + + type L1 struct { x P1 } + type L2 struct { x P2 } + _ = f[L1] + _ = f[L2 /* ERROR L2 does not satisfy comparable */ ] +} + + +// example from issue + +type Set[T comparable] map[T]struct{} + +func NewSetFromSlice[T comparable](items []T) *Set[T] { + s := Set[T]{} + + for _, item := range items { + s[item] = struct{}{} + } + + return &s +} + +type T struct{ x any } + +func main() { + NewSetFromSlice /* ERROR T does not satisfy comparable */ ([]T{ + {"foo"}, + {5}, + }) +} diff --git a/src/internal/types/testdata/fixedbugs/issue51335.go b/src/internal/types/testdata/fixedbugs/issue51335.go new file mode 100644 index 0000000..35135cd --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51335.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +package p + +type S1 struct{} +type S2 struct{} + +func _[P *S1|*S2]() { + _= []P{{ /* ERROR invalid composite literal element type P \(no core type\) */ }} +} + +func _[P *S1|S1]() { + _= []P{{ /* ERROR invalid composite literal element type P \(no core type\) */ }} +} diff --git a/src/internal/types/testdata/fixedbugs/issue51339.go b/src/internal/types/testdata/fixedbugs/issue51339.go new file mode 100644 index 0000000..38f8610 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51339.go @@ -0,0 +1,18 @@ +// Copyright 2022 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 is tested when running "go test -run Manual" +// without source arguments. Use for one-off debugging. + +package p + +type T[P any, B *P] struct{} + +func (T /* ERROR cannot use generic type */ ) m0() {} + +// TODO(rfindley): eliminate the duplicate errors here. +func (/* ERROR got 1 type parameter, but receiver base type declares 2 */ T /* ERROR got 1 arguments but 2 type parameters */ [_]) m1() {} +func (T[_, _]) m2() {} +// TODO(gri) this error is unfortunate (issue #51343) +func (T /* ERROR got 3 arguments but 2 type parameters */ [_, _, _]) m3() {} diff --git a/src/internal/types/testdata/fixedbugs/issue51360.go b/src/internal/types/testdata/fixedbugs/issue51360.go new file mode 100644 index 0000000..fe3de04 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51360.go @@ -0,0 +1,13 @@ +// Copyright 2022 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. + +package p + +func _() { + len.Println /* ERROR cannot select on len */ + len.Println /* ERROR cannot select on len */ () + _ = len.Println /* ERROR cannot select on len */ + _ = len /* ERROR cannot index len */ [0] + _ = *len /* ERROR cannot indirect len */ +} diff --git a/src/internal/types/testdata/fixedbugs/issue51376.go b/src/internal/types/testdata/fixedbugs/issue51376.go new file mode 100644 index 0000000..3801d68 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51376.go @@ -0,0 +1,24 @@ +// Copyright 2022 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. + +package p + +type Map map[string]int + +func f[M ~map[K]V, K comparable, V any](M) {} +func g[M map[K]V, K comparable, V any](M) {} + +func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() { + var m1 M1 + f(m1) + g /* ERROR M1 does not satisfy map\[K\]V */ (m1) // M1 has tilde + + var m2 M2 + f(m2) + g(m2) // M1 does not have tilde + + var m3 Map + f(m3) + g /* ERROR Map does not satisfy map\[string\]int */ (m3) // M in g does not have tilde +} diff --git a/src/internal/types/testdata/fixedbugs/issue51386.go b/src/internal/types/testdata/fixedbugs/issue51386.go new file mode 100644 index 0000000..ef62239 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51386.go @@ -0,0 +1,17 @@ +// Copyright 2022 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. + +package p + +type myString string + +func _[P ~string | ~[]byte | ~[]rune]() { + _ = P("") + const s myString = "" + _ = P(s) +} + +func _[P myString]() { + _ = P("") +} diff --git a/src/internal/types/testdata/fixedbugs/issue51437.go b/src/internal/types/testdata/fixedbugs/issue51437.go new file mode 100644 index 0000000..3762615 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51437.go @@ -0,0 +1,17 @@ +// Copyright 2022 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. + +package p + +type T struct{} + +func (T) m() []int { return nil } + +func f(x T) { + for _, x := range func() []int { + return x.m() // x declared in parameter list of f + }() { + _ = x // x declared by range clause + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue51472.go b/src/internal/types/testdata/fixedbugs/issue51472.go new file mode 100644 index 0000000..a0f9e9c --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51472.go @@ -0,0 +1,54 @@ +// Copyright 2022 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. + +package p + +func _[T comparable](x T) { + _ = x == x +} + +func _[T interface{interface{comparable}}](x T) { + _ = x == x +} + +func _[T interface{comparable; interface{comparable}}](x T) { + _ = x == x +} + +func _[T interface{comparable; ~int}](x T) { + _ = x == x +} + +func _[T interface{comparable; ~[]byte}](x T) { + _ = x /* ERROR empty type set */ == x +} + +// TODO(gri) The error message here should be better. See issue #51525. +func _[T interface{comparable; ~int; ~string}](x T) { + _ = x /* ERROR empty type set */ == x +} + +// TODO(gri) The error message here should be better. See issue #51525. +func _[T interface{~int; ~string}](x T) { + _ = x /* ERROR empty type set */ == x +} + +func _[T interface{comparable; interface{~int}; interface{int|float64}}](x T) { + _ = x == x +} + +func _[T interface{interface{comparable; ~int}; interface{~float64; comparable; m()}}](x T) { + _ = x /* ERROR empty type set */ == x +} + +// test case from issue + +func f[T interface{comparable; []byte|string}](x T) { + _ = x == x +} + +func _(s []byte) { + f /* ERROR \[\]byte does not satisfy interface{comparable; \[\]byte \| string} */ (s) + _ = f[[ /* ERROR does not satisfy */ ]byte] +} diff --git a/src/internal/types/testdata/fixedbugs/issue51509.go b/src/internal/types/testdata/fixedbugs/issue51509.go new file mode 100644 index 0000000..64f5d7e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51509.go @@ -0,0 +1,7 @@ +// Copyright 2022 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. + +package p + +type T /* ERROR invalid recursive type */ T.x diff --git a/src/internal/types/testdata/fixedbugs/issue51525.go b/src/internal/types/testdata/fixedbugs/issue51525.go new file mode 100644 index 0000000..5856905 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51525.go @@ -0,0 +1,20 @@ +// Copyright 2022 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. + +package p + +func _[T interface { + int + string +}](x T) { + _ = x /* ERROR empty type set */ == x + _ = x /* ERROR empty type set */ + x + <-x /* ERROR empty type set */ + x <- /* ERROR empty type set */ 0 + close(x /* ERROR empty type set */) +} + +func _[T interface{ int | []byte }](x T) { + _ = x /* ERROR incomparable types in type set */ == x +} diff --git a/src/internal/types/testdata/fixedbugs/issue51533.go b/src/internal/types/testdata/fixedbugs/issue51533.go new file mode 100644 index 0000000..bf46f75 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51533.go @@ -0,0 +1,20 @@ +// Copyright 2022 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. + +package p + +func _(x any) { + switch x { + case 0: + fallthrough // ERROR fallthrough statement out of place + _ = x + default: + } + + switch x.(type) { + case int: + fallthrough // ERROR cannot fallthrough in type switch + default: + } +} diff --git a/src/internal/types/testdata/fixedbugs/issue51578.go b/src/internal/types/testdata/fixedbugs/issue51578.go new file mode 100644 index 0000000..5c204ba --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51578.go @@ -0,0 +1,17 @@ +// Copyright 2022 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. + +package p + +var _ = (*interface /* ERROR interface contains type constraints */ {int})(nil) + +// abbreviated test case from issue + +type TypeSet interface{ int | string } + +func _() { + f((*TypeSet /* ERROR interface contains type constraints */)(nil)) +} + +func f(any) {}
\ No newline at end of file diff --git a/src/internal/types/testdata/fixedbugs/issue51593.go b/src/internal/types/testdata/fixedbugs/issue51593.go new file mode 100644 index 0000000..e06c39f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51593.go @@ -0,0 +1,13 @@ +// Copyright 2022 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. + +package p + +func f[P interface{ m(R) }, R any]() {} + +type T = interface { m(int) } + +func _() { + _ = f /* ERROR cannot infer R */ [T] // don't crash in type inference +} diff --git a/src/internal/types/testdata/fixedbugs/issue51607.go b/src/internal/types/testdata/fixedbugs/issue51607.go new file mode 100644 index 0000000..d8df143 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51607.go @@ -0,0 +1,65 @@ +// Copyright 2022 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. + +package p + +// Interface types must be ignored during overlap test. + +type ( + T1 interface{int} + T2 interface{~int} + T3 interface{T1 | bool | string} + T4 interface{T2 | ~bool | ~string} +) + +type ( + // overlap errors for non-interface terms + // (like the interface terms, but explicitly inlined) + _ interface{int | int /* ERROR overlapping terms int and int */ } + _ interface{int | ~ /* ERROR overlapping terms ~int and int */ int} + _ interface{~int | int /* ERROR overlapping terms int and ~int */ } + _ interface{~int | ~ /* ERROR overlapping terms ~int and ~int */ int} + + _ interface{T1 | bool | string | T1 | bool /* ERROR overlapping terms bool and bool */ | string /* ERROR overlapping terms string and string */ } + _ interface{T1 | bool | string | T2 | ~ /* ERROR overlapping terms ~bool and bool */ bool | ~ /* ERROR overlapping terms ~string and string */ string} + + // no errors for interface terms + _ interface{T1 | T1} + _ interface{T1 | T2} + _ interface{T2 | T1} + _ interface{T2 | T2} + + _ interface{T3 | T3 | int} + _ interface{T3 | T4 | bool } + _ interface{T4 | T3 | string } + _ interface{T4 | T4 | float64 } +) + +func _[_ T1 | bool | string | T1 | bool /* ERROR overlapping terms */ ]() {} +func _[_ T1 | bool | string | T2 | ~ /* ERROR overlapping terms */ bool ]() {} +func _[_ T2 | ~bool | ~string | T1 | bool /* ERROR overlapping terms */ ]() {} +func _[_ T2 | ~bool | ~string | T2 | ~ /* ERROR overlapping terms */ bool ]() {} + +func _[_ T3 | T3 | int]() {} +func _[_ T3 | T4 | bool]() {} +func _[_ T4 | T3 | string]() {} +func _[_ T4 | T4 | float64]() {} + +// test cases from issue + +type _ interface { + interface {bool | int} | interface {bool | string} +} + +type _ interface { + interface {bool | int} ; interface {bool | string} +} + +type _ interface { + interface {bool; int} ; interface {bool; string} +} + +type _ interface { + interface {bool; int} | interface {bool; string} +}
\ No newline at end of file diff --git a/src/internal/types/testdata/fixedbugs/issue51610.go b/src/internal/types/testdata/fixedbugs/issue51610.go new file mode 100644 index 0000000..d10c788 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51610.go @@ -0,0 +1,9 @@ +// Copyright 2022 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. + +package p + +func _[P int | float64 | complex128]() { + _ = map[P]int{1: 1, 1.0 /* ERROR duplicate key 1 */ : 2, 1 /* ERROR duplicate key \(1 \+ 0i\) */ + 0i: 3} +} diff --git a/src/internal/types/testdata/fixedbugs/issue51616.go b/src/internal/types/testdata/fixedbugs/issue51616.go new file mode 100644 index 0000000..e0efc9e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51616.go @@ -0,0 +1,19 @@ +// Copyright 2022 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. + +package p + +type ( + C[T any] interface{~int; M() T} + + _ C[bool] + _ comparable + _ interface {~[]byte | ~string} + + // Alias type declarations may refer to "constraint" types + // like ordinary type declarations. + _ = C[bool] + _ = comparable + _ = interface {~[]byte | ~string} +) diff --git a/src/internal/types/testdata/fixedbugs/issue51658.go b/src/internal/types/testdata/fixedbugs/issue51658.go new file mode 100644 index 0000000..f32051c --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51658.go @@ -0,0 +1,43 @@ +// Copyright 2022 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 test checks syntax errors which differ between +// go/parser and the syntax package. +// TODO: consolidate eventually + +package p + +type F { // ERROR expected type|type declaration + float64 +} // ERROR expected declaration|non-declaration statement + +func _[T F | int](x T) { + _ = x == 0 // don't crash when recording type of 0 +} + +// test case from issue + +type FloatType { // ERROR expected type|type declaration + float32 | float64 +} // ERROR expected declaration|non-declaration statement + +type IntegerType interface { + int8 | int16 | int32 | int64 | int | + uint8 | uint16 | uint32 | uint64 | uint +} + +type ComplexType interface { + complex64 | complex128 +} + +type Number interface { + FloatType | IntegerType | ComplexType +} + +func GetDefaultNumber[T Number](value, defaultValue T) T { + if value == 0 { + return defaultValue + } + return value +} diff --git a/src/internal/types/testdata/fixedbugs/issue51877.go b/src/internal/types/testdata/fixedbugs/issue51877.go new file mode 100644 index 0000000..c93242a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue51877.go @@ -0,0 +1,18 @@ +// Copyright 2013 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. + +package p + +type S struct { + f1 int + f2 bool +} + +var ( + _ = S{0} /* ERROR too few values in struct literal */ + _ = struct{ f1, f2 int }{0} /* ERROR too few values in struct literal */ + + _ = S{0, true, "foo" /* ERROR too many values in struct literal */} + _ = struct{ f1, f2 int }{0, 1, 2 /* ERROR too many values in struct literal */} +) diff --git a/src/internal/types/testdata/fixedbugs/issue52031.go b/src/internal/types/testdata/fixedbugs/issue52031.go new file mode 100644 index 0000000..448a550 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue52031.go @@ -0,0 +1,33 @@ +// -lang=go1.12 + +// Copyright 2022 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. + +package p + +type resultFlags uint + +// Example from #52031. +// +// The following shifts should not produce errors on Go < 1.13, as their +// untyped constant operands are representable by type uint. +const ( + _ resultFlags = (1 << iota) / 2 + + reportEqual + reportUnequal + reportByIgnore + reportByMethod + reportByFunc + reportByCycle +) + +// Invalid cases. +var x int = 1 +var _ = (8 << x /* ERROR "signed shift count .* requires go1.13 or later" */) + +const _ = (1 << 1.2 /* ERROR "truncated to uint" */) + +var y float64 +var _ = (1 << y /* ERROR "must be integer" */) diff --git a/src/internal/types/testdata/fixedbugs/issue52401.go b/src/internal/types/testdata/fixedbugs/issue52401.go new file mode 100644 index 0000000..c7efd8c --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue52401.go @@ -0,0 +1,11 @@ +// Copyright 2022 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. + +package p + +func _() { + const x = 0 + x /* ERROR cannot assign to x */ += 1 + x /* ERROR cannot assign to x */ ++ +} diff --git a/src/internal/types/testdata/fixedbugs/issue52529.go b/src/internal/types/testdata/fixedbugs/issue52529.go new file mode 100644 index 0000000..de7b296 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue52529.go @@ -0,0 +1,15 @@ +// Copyright 2022 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. + +package p + +type Foo[P any] struct { + _ *Bar[P] +} + +type Bar[Q any] Foo[Q] + +func (v *Bar[R]) M() { + _ = (*Foo[R])(v) +} diff --git a/src/internal/types/testdata/fixedbugs/issue52698.go b/src/internal/types/testdata/fixedbugs/issue52698.go new file mode 100644 index 0000000..ca794f8 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue52698.go @@ -0,0 +1,62 @@ +// Copyright 2022 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. + +package p + +// correctness check: ensure that cycles through generic instantiations are detected +type T[P any] struct { + _ P +} + +type S /* ERROR invalid recursive type */ struct { + _ T[S] +} + +// simplified test 1 + +var _ A1[A1[string]] + +type A1[P any] struct { + _ B1[P] +} + +type B1[P any] struct { + _ P +} + +// simplified test 2 +var _ B2[A2] + +type A2 struct { + _ B2[string] +} + +type B2[P any] struct { + _ C2[P] +} + +type C2[P any] struct { + _ P +} + +// test case from issue +type T23 interface { + ~struct { + Field0 T13[T15] + } +} + +type T1[P1 interface { +}] struct { + Field2 P1 +} + +type T13[P2 interface { +}] struct { + Field2 T1[P2] +} + +type T15 struct { + Field0 T13[string] +} diff --git a/src/internal/types/testdata/fixedbugs/issue52915.go b/src/internal/types/testdata/fixedbugs/issue52915.go new file mode 100644 index 0000000..6c43386 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue52915.go @@ -0,0 +1,23 @@ +// Copyright 2022 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. + +package p + +import "unsafe" + +type T[P any] struct { + T /* ERROR invalid recursive type */ [P] +} + +func _[P any]() { + _ = unsafe.Sizeof(T[int]{}) + _ = unsafe.Sizeof(struct{ T[int] }{}) + + _ = unsafe.Sizeof(T[P]{}) + _ = unsafe.Sizeof(struct{ T[P] }{}) +} + +// TODO(gri) This is a follow-on error due to T[int] being invalid. +// We should try to avoid it. +const _ = unsafe /* ERROR not constant */ .Sizeof(T[int]{}) diff --git a/src/internal/types/testdata/fixedbugs/issue53358.go b/src/internal/types/testdata/fixedbugs/issue53358.go new file mode 100644 index 0000000..774136f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue53358.go @@ -0,0 +1,19 @@ +// Copyright 2022 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. + +package p + +type A struct{} + +func (*A) m() int { return 0 } + +var _ = A.m /* ERROR invalid method expression A\.m \(needs pointer receiver \(\*A\)\.m\) */ () +var _ = (*A).m(nil) + +type B struct{ A } + +var _ = B.m // ERROR invalid method expression B\.m \(needs pointer receiver \(\*B\)\.m\) +var _ = (*B).m + +var _ = struct{ A }.m // ERROR invalid method expression struct{A}\.m \(needs pointer receiver \(\*struct{A}\)\.m\) diff --git a/src/internal/types/testdata/fixedbugs/issue54280.go b/src/internal/types/testdata/fixedbugs/issue54280.go new file mode 100644 index 0000000..e83e1a1 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue54280.go @@ -0,0 +1,7 @@ +// Copyright 2022 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. + +package p + +const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR constant overflow diff --git a/src/internal/types/testdata/fixedbugs/issue54405.go b/src/internal/types/testdata/fixedbugs/issue54405.go new file mode 100644 index 0000000..611d830 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue54405.go @@ -0,0 +1,16 @@ +// Copyright 2022 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. + +// Test that we don't see spurious errors for == +// for values with invalid types due to prior errors. + +package p + +var x struct { + f *NotAType /* ERROR undefined */ +} +var _ = x.f == nil // no error expected here + +var y *NotAType /* ERROR undefined */ +var _ = y == nil // no error expected here diff --git a/src/internal/types/testdata/fixedbugs/issue56351.go b/src/internal/types/testdata/fixedbugs/issue56351.go new file mode 100644 index 0000000..d7d04b0 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue56351.go @@ -0,0 +1,11 @@ +// -lang=go1.20 + +// Copyright 2022 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. + +package p + +func _(s []int) { + clear /* ERROR clear requires go1\.21 or later */ (s) +} diff --git a/src/internal/types/testdata/fixedbugs/issue56425.go b/src/internal/types/testdata/fixedbugs/issue56425.go new file mode 100644 index 0000000..d85733f --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue56425.go @@ -0,0 +1,8 @@ +// Copyright 2022 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. + +package p + +const s float32 = 0 +var _ = 0 << s diff --git a/src/internal/types/testdata/fixedbugs/issue56665.go b/src/internal/types/testdata/fixedbugs/issue56665.go new file mode 100644 index 0000000..11786b9 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue56665.go @@ -0,0 +1,30 @@ +// Copyright 2022 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. + +package p + +// Example from the issue: +type A[T any] interface { + *T +} + +type B[T any] interface { + B /* ERROR invalid recursive type */ [*T] +} + +type C[T any, U B[U]] interface { + *T +} + +// Simplified reproducer: +type X[T any] interface { + X /* ERROR invalid recursive type */ [*T] +} + +var _ X[int] + +// A related example that doesn't go through interfaces. +type A2[P any] [10]A2 /* ERROR invalid recursive type */ [*P] + +var _ A2[int] diff --git a/src/internal/types/testdata/fixedbugs/issue57155.go b/src/internal/types/testdata/fixedbugs/issue57155.go new file mode 100644 index 0000000..ec9fb2b --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue57155.go @@ -0,0 +1,14 @@ +// Copyright 2022 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. + +package p + +func f[P *Q, Q any](p P, q Q) { + func() { + _ = f[P] + f(p, q) + f[P](p, q) + f[P, Q](p, q) + }() +} diff --git a/src/internal/types/testdata/fixedbugs/issue57160.go b/src/internal/types/testdata/fixedbugs/issue57160.go new file mode 100644 index 0000000..446d019 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue57160.go @@ -0,0 +1,10 @@ +// Copyright 2022 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. + +package p + +func _(x *int) { + _ = 0 < x // ERROR "invalid operation" + _ = x < 0 // ERROR "invalid operation" +} diff --git a/src/internal/types/testdata/fixedbugs/issue57486.go b/src/internal/types/testdata/fixedbugs/issue57486.go new file mode 100644 index 0000000..43ba1b0 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue57486.go @@ -0,0 +1,29 @@ +// Copyright 2022 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. + +package p + +type C1 interface { + comparable +} + +type C2 interface { + comparable + [2]any | int +} + +func G1[T C1](t T) { _ = t == t } +func G2[T C2](t T) { _ = t == t } + +func F1[V [2]any](v V) { + _ = G1[V /* ERROR "V does not satisfy comparable" */] + _ = G1[[2]any] + _ = G1[int] +} + +func F2[V [2]any](v V) { + _ = G2[V /* ERROR "V does not satisfy C2" */] + _ = G2[[ /* ERROR "\[2\]any does not satisfy C2 \(C2 mentions \[2\]any, but \[2\]any is not in the type set of C2\)" */ 2]any] + _ = G2[int] +} diff --git a/src/internal/types/testdata/fixedbugs/issue57500.go b/src/internal/types/testdata/fixedbugs/issue57500.go new file mode 100644 index 0000000..abdcb5e --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue57500.go @@ -0,0 +1,16 @@ +// Copyright 2023 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. + +package p + +type C interface { + comparable + [2]any | int +} + +func f[T C]() {} + +func _() { + _ = f[[ /* ERROR \[2\]any does not satisfy C \(C mentions \[2\]any, but \[2\]any is not in the type set of C\) */ 2]any] +} diff --git a/src/internal/types/testdata/fixedbugs/issue57522.go b/src/internal/types/testdata/fixedbugs/issue57522.go new file mode 100644 index 0000000..d83e5b2 --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue57522.go @@ -0,0 +1,24 @@ +// Copyright 2023 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. + +package p + +// A simplified version of the code in the original report. +type S[T any] struct{} +var V = S[any]{} +func (fs *S[T]) M(V.M /* ERROR "V.M is not a type" */) {} + +// Other minimal reproducers. +type S1[T any] V1.M /* ERROR "V1.M is not a type" */ +type V1 = S1[any] + +type S2[T any] struct{} +type V2 = S2[any] +func (fs *S2[T]) M(x V2.M /* ERROR "V2.M is not a type" */ ) {} + +// The following still panics, as the selector is reached from check.expr +// rather than check.typexpr. TODO(rfindley): fix this. +// type X[T any] int +// func (X[T]) M(x [X[int].M]int) {} + diff --git a/src/internal/types/testdata/fixedbugs/issue6977.go b/src/internal/types/testdata/fixedbugs/issue6977.go new file mode 100644 index 0000000..8f4e9ba --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue6977.go @@ -0,0 +1,82 @@ +// Copyright 2019 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. + +package p + +import "io" + +// Alan's initial report. + +type I interface { f(); String() string } +type J interface { g(); String() string } + +type IJ1 = interface { I; J } +type IJ2 = interface { f(); g(); String() string } + +var _ = (*IJ1)(nil) == (*IJ2)(nil) // static assert that IJ1 and IJ2 are identical types + +// The canonical example. + +type ReadWriteCloser interface { io.ReadCloser; io.WriteCloser } + +// Some more cases. + +type M interface { m() } +type M32 interface { m() int32 } +type M64 interface { m() int64 } + +type U1 interface { m() } +type U2 interface { m(); M } +type U3 interface { M; m() } +type U4 interface { M; M; M } +type U5 interface { U1; U2; U3; U4 } + +type U6 interface { m(); m /* ERROR duplicate method */ () } +type U7 interface { M32 /* ERROR duplicate method */ ; m() } +type U8 interface { m(); M32 /* ERROR duplicate method */ } +type U9 interface { M32; M64 /* ERROR duplicate method */ } + +// Verify that repeated embedding of the same interface(s) +// eliminates duplicate methods early (rather than at the +// end) to prevent exponential memory and time use. +// Without early elimination, computing T29 may take dozens +// of minutes. +type ( + T0 interface { m() } + T1 interface { T0; T0 } + T2 interface { T1; T1 } + T3 interface { T2; T2 } + T4 interface { T3; T3 } + T5 interface { T4; T4 } + T6 interface { T5; T5 } + T7 interface { T6; T6 } + T8 interface { T7; T7 } + T9 interface { T8; T8 } + + T10 interface { T9; T9 } + T11 interface { T10; T10 } + T12 interface { T11; T11 } + T13 interface { T12; T12 } + T14 interface { T13; T13 } + T15 interface { T14; T14 } + T16 interface { T15; T15 } + T17 interface { T16; T16 } + T18 interface { T17; T17 } + T19 interface { T18; T18 } + + T20 interface { T19; T19 } + T21 interface { T20; T20 } + T22 interface { T21; T21 } + T23 interface { T22; T22 } + T24 interface { T23; T23 } + T25 interface { T24; T24 } + T26 interface { T25; T25 } + T27 interface { T26; T26 } + T28 interface { T27; T27 } + T29 interface { T28; T28 } +) + +// Verify that m is present. +var x T29 +var _ = x.m diff --git a/src/internal/types/testdata/spec/assignability.go b/src/internal/types/testdata/spec/assignability.go new file mode 100644 index 0000000..0ab8eb3 --- /dev/null +++ b/src/internal/types/testdata/spec/assignability.go @@ -0,0 +1,264 @@ +// Copyright 2021 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. + +package assignability + +// See the end of this package for the declarations +// of the types and variables used in these tests. + +// "x's type is identical to T" +func _[TP any](X TP) { + b = b + a = a + l = l + s = s + p = p + f = f + i = i + m = m + c = c + d = d + + B = B + A = A + L = L + S = S + P = P + F = F + I = I + M = M + C = C + D = D + X = X +} + +// "x's type V and T have identical underlying types +// and at least one of V or T is not a named type." +// (here a named type is a type with a name) +func _[TP1, TP2 Interface](X1 TP1, X2 TP2) { + b = B // ERROR cannot use B .* as int value + a = A + l = L + s = S + p = P + f = F + i = I + m = M + c = C + d = D + + B = b // ERROR cannot use b .* as Basic value + A = a + L = l + S = s + P = p + F = f + I = i + M = m + C = c + D = d + X1 = i // ERROR cannot use i .* as TP1 value + X1 = X2 // ERROR cannot use X2 .* as TP1 value +} + +// "T is an interface type and x implements T and T is not a type parameter" +func _[TP Interface](X TP) { + i = d // ERROR missing method m + i = D + i = X + X = i // ERROR cannot use i .* as TP value +} + +// "x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type" +// (here a named type is a type with a name) +type ( + _SendChan = chan<- int + _RecvChan = <-chan int + + SendChan _SendChan + RecvChan _RecvChan +) + +func _[ + _CC ~_Chan, + _SC ~_SendChan, + _RC ~_RecvChan, + + CC Chan, + SC SendChan, + RC RecvChan, +]() { + var ( + _ _SendChan = c + _ _RecvChan = c + _ _Chan = c + + _ _SendChan = C + _ _RecvChan = C + _ _Chan = C + + _ SendChan = c + _ RecvChan = c + _ Chan = c + + _ SendChan = C // ERROR cannot use C .* as SendChan value + _ RecvChan = C // ERROR cannot use C .* as RecvChan value + _ Chan = C + _ Chan = make /* ERROR cannot use make\(chan Basic\) .* as Chan value */ (chan Basic) + ) + + var ( + _ _CC = C // ERROR cannot use C .* as _CC value + _ _SC = C // ERROR cannot use C .* as _SC value + _ _RC = C // ERROR cannot use C .* as _RC value + + _ CC = _CC /* ERROR cannot use _CC\(nil\) .* as CC value */ (nil) + _ SC = _CC /* ERROR cannot use _CC\(nil\) .* as SC value */ (nil) + _ RC = _CC /* ERROR cannot use _CC\(nil\) .* as RC value */ (nil) + + _ CC = C // ERROR cannot use C .* as CC value + _ SC = C // ERROR cannot use C .* as SC value + _ RC = C // ERROR cannot use C .* as RC value + ) +} + +// "x's type V is not a named type and T is a type parameter, and x is assignable to each specific type in T's type set." +func _[ + TP0 any, + TP1 ~_Chan, + TP2 ~chan int | ~chan byte, +]() { + var ( + _ TP0 = c // ERROR cannot use c .* as TP0 value + _ TP0 = C // ERROR cannot use C .* as TP0 value + _ TP1 = c + _ TP1 = C // ERROR cannot use C .* as TP1 value + _ TP2 = c // ERROR .* cannot assign chan int to chan byte + ) +} + +// "x's type V is a type parameter and T is not a named type, and values x' of each specific type in V's type set are assignable to T." +func _[ + TP0 Interface, + TP1 ~_Chan, + TP2 ~chan int | ~chan byte, +](X0 TP0, X1 TP1, X2 TP2) { + i = X0 + I = X0 + c = X1 + C = X1 // ERROR cannot use X1 .* as Chan value + c = X2 // ERROR .* cannot assign chan byte \(in TP2\) to chan int +} + +// "x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type" +func _[TP Interface](X TP) { + b = nil // ERROR cannot use nil + a = nil // ERROR cannot use nil + l = nil + s = nil // ERROR cannot use nil + p = nil + f = nil + i = nil + m = nil + c = nil + d = nil // ERROR cannot use nil + + B = nil // ERROR cannot use nil + A = nil // ERROR cannot use nil + L = nil + S = nil // ERROR cannot use nil + P = nil + F = nil + I = nil + M = nil + C = nil + D = nil // ERROR cannot use nil + X = nil // ERROR cannot use nil +} + +// "x is an untyped constant representable by a value of type T" +func _[ + Int8 ~int8, + Int16 ~int16, + Int32 ~int32, + Int64 ~int64, + Int8_16 ~int8 | ~int16, +]( + i8 Int8, + i16 Int16, + i32 Int32, + i64 Int64, + i8_16 Int8_16, +) { + b = 42 + b = 42.0 + // etc. + + i8 = -1 << 7 + i8 = 1<<7 - 1 + i16 = -1 << 15 + i16 = 1<<15 - 1 + i32 = -1 << 31 + i32 = 1<<31 - 1 + i64 = -1 << 63 + i64 = 1<<63 - 1 + + i8_16 = -1 << 7 + i8_16 = 1<<7 - 1 + i8_16 = - /* ERROR cannot use .* as Int8_16 */ 1 << 15 + i8_16 = 1 /* ERROR cannot use .* as Int8_16 */ <<15 - 1 +} + +// proto-types for tests + +type ( + _Basic = int + _Array = [10]int + _Slice = []int + _Struct = struct{ f int } + _Pointer = *int + _Func = func(x int) string + _Interface = interface{ m() int } + _Map = map[string]int + _Chan = chan int + + Basic _Basic + Array _Array + Slice _Slice + Struct _Struct + Pointer _Pointer + Func _Func + Interface _Interface + Map _Map + Chan _Chan + Defined _Struct +) + +func (Defined) m() int + +// proto-variables for tests + +var ( + b _Basic + a _Array + l _Slice + s _Struct + p _Pointer + f _Func + i _Interface + m _Map + c _Chan + d _Struct + + B Basic + A Array + L Slice + S Struct + P Pointer + F Func + I Interface + M Map + C Chan + D Defined +) diff --git a/src/internal/types/testdata/spec/comparable.go b/src/internal/types/testdata/spec/comparable.go new file mode 100644 index 0000000..f407c35 --- /dev/null +++ b/src/internal/types/testdata/spec/comparable.go @@ -0,0 +1,26 @@ +// Copyright 2022 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. + +package p + +func f1[_ comparable]() {} +func f2[_ interface{ comparable }]() {} + +type T interface{ m() } + +func _[P comparable, Q ~int, R any]() { + _ = f1[int] + _ = f1[T /* T does satisfy comparable */] + _ = f1[any /* any does satisfy comparable */] + _ = f1[P] + _ = f1[Q] + _ = f1[R /* ERROR R does not satisfy comparable */] + + _ = f2[int] + _ = f2[T /* T does satisfy comparable */] + _ = f2[any /* any does satisfy comparable */] + _ = f2[P] + _ = f2[Q] + _ = f2[R /* ERROR R does not satisfy comparable */] +} diff --git a/src/internal/types/testdata/spec/comparable1.19.go b/src/internal/types/testdata/spec/comparable1.19.go new file mode 100644 index 0000000..dc1c5fa --- /dev/null +++ b/src/internal/types/testdata/spec/comparable1.19.go @@ -0,0 +1,28 @@ +// -lang=go1.19 + +// Copyright 2022 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. + +package p + +func f1[_ comparable]() {} +func f2[_ interface{ comparable }]() {} + +type T interface{ m() } + +func _[P comparable, Q ~int, R any]() { + _ = f1[int] + _ = f1[T /* ERROR T to satisfy comparable requires go1\.20 or later */] + _ = f1[any /* ERROR any to satisfy comparable requires go1\.20 or later */] + _ = f1[P] + _ = f1[Q] + _ = f1[R /* ERROR R does not satisfy comparable */] + + _ = f2[int] + _ = f2[T /* ERROR T to satisfy comparable requires go1\.20 or later */] + _ = f2[any /* ERROR any to satisfy comparable requires go1\.20 or later */] + _ = f2[P] + _ = f2[Q] + _ = f2[R /* ERROR R does not satisfy comparable */] +} diff --git a/src/internal/types/testdata/spec/comparisons.go b/src/internal/types/testdata/spec/comparisons.go new file mode 100644 index 0000000..886e78c --- /dev/null +++ b/src/internal/types/testdata/spec/comparisons.go @@ -0,0 +1,120 @@ +// Copyright 2022 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. + +package comparisons + +type ( + B int // basic type representative + A [10]func() + L []byte + S struct{ f []byte } + P *S + F func() + I interface{} + M map[string]int + C chan int +) + +var ( + b B + a A + l L + s S + p P + f F + i I + m M + c C +) + +func _() { + _ = nil == nil // ERROR operator == not defined on untyped nil + _ = b == b + _ = a /* ERROR \[10\]func\(\) cannot be compared */ == a + _ = l /* ERROR slice can only be compared to nil */ == l + _ = s /* ERROR struct containing \[\]byte cannot be compared */ == s + _ = p == p + _ = f /* ERROR func can only be compared to nil */ == f + _ = i == i + _ = m /* ERROR map can only be compared to nil */ == m + _ = c == c + + _ = b == nil /* ERROR mismatched types */ + _ = a == nil /* ERROR mismatched types */ + _ = l == nil + _ = s == nil /* ERROR mismatched types */ + _ = p == nil + _ = f == nil + _ = i == nil + _ = m == nil + _ = c == nil + + _ = nil /* ERROR operator < not defined on untyped nil */ < nil + _ = b < b + _ = a /* ERROR operator < not defined on array */ < a + _ = l /* ERROR operator < not defined on slice */ < l + _ = s /* ERROR operator < not defined on struct */ < s + _ = p /* ERROR operator < not defined on pointer */ < p + _ = f /* ERROR operator < not defined on func */ < f + _ = i /* ERROR operator < not defined on interface */ < i + _ = m /* ERROR operator < not defined on map */ < m + _ = c /* ERROR operator < not defined on chan */ < c +} + +func _[ + B int, + A [10]func(), + L []byte, + S struct{ f []byte }, + P *S, + F func(), + I interface{}, + J comparable, + M map[string]int, + C chan int, +]( + b B, + a A, + l L, + s S, + p P, + f F, + i I, + j J, + m M, + c C, +) { + _ = b == b + _ = a /* ERROR incomparable types in type set */ == a + _ = l /* ERROR incomparable types in type set */ == l + _ = s /* ERROR incomparable types in type set */ == s + _ = p == p + _ = f /* ERROR incomparable types in type set */ == f + _ = i /* ERROR incomparable types in type set */ == i + _ = j == j + _ = m /* ERROR incomparable types in type set */ == m + _ = c == c + + _ = b == nil /* ERROR mismatched types */ + _ = a == nil /* ERROR mismatched types */ + _ = l == nil + _ = s == nil /* ERROR mismatched types */ + _ = p == nil + _ = f == nil + _ = i == nil /* ERROR mismatched types */ + _ = j == nil /* ERROR mismatched types */ + _ = m == nil + _ = c == nil + + _ = b < b + _ = a /* ERROR type parameter A is not comparable with < */ < a + _ = l /* ERROR type parameter L is not comparable with < */ < l + _ = s /* ERROR type parameter S is not comparable with < */ < s + _ = p /* ERROR type parameter P is not comparable with < */ < p + _ = f /* ERROR type parameter F is not comparable with < */ < f + _ = i /* ERROR type parameter I is not comparable with < */ < i + _ = j /* ERROR type parameter J is not comparable with < */ < j + _ = m /* ERROR type parameter M is not comparable with < */ < m + _ = c /* ERROR type parameter C is not comparable with < */ < c +} diff --git a/src/internal/types/testdata/spec/conversions.go b/src/internal/types/testdata/spec/conversions.go new file mode 100644 index 0000000..fc014fc --- /dev/null +++ b/src/internal/types/testdata/spec/conversions.go @@ -0,0 +1,208 @@ +// Copyright 2021 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. + +package conversions + +import "unsafe" + +// constant conversions + +func _[T ~byte]() T { return 255 } +func _[T ~byte]() T { return 256 /* ERROR cannot use 256 .* as T value */ } + +func _[T ~byte]() { + const _ = T /* ERROR T\(0\) .* is not constant */ (0) + var _ T = 255 + var _ T = 256 // ERROR cannot use 256 .* as T value +} + +func _[T ~string]() T { return T('a') } +func _[T ~int | ~string]() T { return T('a') } +func _[T ~byte | ~int | ~string]() T { return T(256 /* ERROR cannot convert 256 .* to type T */) } + +// implicit conversions never convert to string +func _[T ~string]() { + var _ string = 0 // ERROR cannot use .* as string value + var _ T = 0 // ERROR cannot use .* as T value +} + +// failing const conversions of constants to type parameters report a cause +func _[ + T1 any, + T2 interface{ m() }, + T3 ~int | ~float64 | ~bool, + T4 ~int | ~string, +]() { + _ = T1(0 /* ERROR cannot convert 0 .* to type T1: T1 does not contain specific types */) + _ = T2(1 /* ERROR cannot convert 1 .* to type T2: T2 does not contain specific types */) + _ = T3(2 /* ERROR cannot convert 2 .* to type T3: cannot convert 2 .* to type bool \(in T3\) */) + _ = T4(3.14 /* ERROR cannot convert 3.14 .* to type T4: cannot convert 3.14 .* to type int \(in T4\) */) +} + +// "x is assignable to T" +// - tested via assignability tests + +// "x's type and T have identical underlying types if tags are ignored" + +func _[X ~int, T ~int](x X) T { return T(x) } +func _[X struct { + f int "foo" +}, T struct { + f int "bar" +}](x X) T { + return T(x) +} + +type Foo struct { + f int "foo" +} +type Bar struct { + f int "bar" +} +type Far struct{ f float64 } + +func _[X Foo, T Bar](x X) T { return T(x) } +func _[X Foo | Bar, T Bar](x X) T { return T(x) } +func _[X Foo, T Foo | Bar](x X) T { return T(x) } +func _[X Foo, T Far](x X) T { + return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to type T: cannot convert Foo \(in X\) to type Far \(in T\) */) +} + +// "x's type and T are unnamed pointer types and their pointer base types +// have identical underlying types if tags are ignored" + +func _[X ~*Foo, T ~*Bar](x X) T { return T(x) } +func _[X ~*Foo | ~*Bar, T ~*Bar](x X) T { return T(x) } +func _[X ~*Foo, T ~*Foo | ~*Bar](x X) T { return T(x) } +func _[X ~*Foo, T ~*Far](x X) T { + return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to type T: cannot convert \*Foo \(in X\) to type \*Far \(in T\) */) +} + +// Verify that the defined types in constraints are considered for the rule above. + +type ( + B int + C int + X0 *B + T0 *C +) + +func _(x X0) T0 { return T0(x /* ERROR cannot convert */) } // non-generic reference +func _[X X0, T T0](x X) T { return T(x /* ERROR cannot convert */) } +func _[T T0](x X0) T { return T(x /* ERROR cannot convert */) } +func _[X X0](x X) T0 { return T0(x /* ERROR cannot convert */) } + +// "x's type and T are both integer or floating point types" + +func _[X Integer, T Integer](x X) T { return T(x) } +func _[X Unsigned, T Integer](x X) T { return T(x) } +func _[X Float, T Integer](x X) T { return T(x) } + +func _[X Integer, T Unsigned](x X) T { return T(x) } +func _[X Unsigned, T Unsigned](x X) T { return T(x) } +func _[X Float, T Unsigned](x X) T { return T(x) } + +func _[X Integer, T Float](x X) T { return T(x) } +func _[X Unsigned, T Float](x X) T { return T(x) } +func _[X Float, T Float](x X) T { return T(x) } + +func _[X, T Integer | Unsigned | Float](x X) T { return T(x) } +func _[X, T Integer | ~string](x X) T { + return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~string\) to type T: cannot convert string \(in X\) to type int \(in T\) */) +} + +// "x's type and T are both complex types" + +func _[X, T Complex](x X) T { return T(x) } +func _[X, T Float | Complex](x X) T { + return T(x /* ERROR cannot convert x \(variable of type X constrained by Float \| Complex\) to type T: cannot convert float32 \(in X\) to type complex64 \(in T\) */) +} + +// "x is an integer or a slice of bytes or runes and T is a string type" + +type myInt int +type myString string + +func _[T ~string](x int) T { return T(x) } +func _[T ~string](x myInt) T { return T(x) } +func _[X Integer](x X) string { return string(x) } +func _[X Integer](x X) myString { return myString(x) } +func _[X Integer](x X) *string { + return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to type \*string: cannot convert int \(in X\) to type \*string */) +} + +func _[T ~string](x []byte) T { return T(x) } +func _[T ~string](x []rune) T { return T(x) } +func _[X ~[]byte, T ~string](x X) T { return T(x) } +func _[X ~[]rune, T ~string](x X) T { return T(x) } +func _[X Integer | ~[]byte | ~[]rune, T ~string](x X) T { return T(x) } +func _[X Integer | ~[]byte | ~[]rune, T ~*string](x X) T { + return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~\[\]byte \| ~\[\]rune\) to type T: cannot convert int \(in X\) to type \*string \(in T\) */) +} + +// "x is a string and T is a slice of bytes or runes" + +func _[T ~[]byte](x string) T { return T(x) } +func _[T ~[]rune](x string) T { return T(x) } +func _[T ~[]rune](x *string) T { + return T(x /* ERROR cannot convert x \(variable of type \*string\) to type T: cannot convert \*string to type \[\]rune \(in T\) */) +} + +func _[X ~string, T ~[]byte](x X) T { return T(x) } +func _[X ~string, T ~[]rune](x X) T { return T(x) } +func _[X ~string, T ~[]byte | ~[]rune](x X) T { return T(x) } +func _[X ~*string, T ~[]byte | ~[]rune](x X) T { + return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to type T: cannot convert \*string \(in X\) to type \[\]byte \(in T\) */) +} + +// package unsafe: +// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer" + +type myUintptr uintptr + +func _[X ~uintptr](x X) unsafe.Pointer { return unsafe.Pointer(x) } +func _[T unsafe.Pointer](x myUintptr) T { return T(x) } +func _[T unsafe.Pointer](x int64) T { + return T(x /* ERROR cannot convert x \(variable of type int64\) to type T: cannot convert int64 to type unsafe\.Pointer \(in T\) */) +} + +// "and vice versa" + +func _[T ~uintptr](x unsafe.Pointer) T { return T(x) } +func _[X unsafe.Pointer](x X) uintptr { return uintptr(x) } +func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) } +func _[X unsafe.Pointer](x X) int64 { + return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to type int64: cannot convert unsafe\.Pointer \(in X\) to type int64 */) +} + +// "x is a slice, T is an array or pointer-to-array type, +// and the slice and array types have identical element types." + +func _[X ~[]E, T ~[10]E, E any](x X) T { return T(x) } +func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) } + +// ---------------------------------------------------------------------------- +// The following declarations can be replaced by the exported types of the +// constraints package once all builders support importing interfaces with +// type constraints. + +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +type Integer interface { + Signed | Unsigned +} + +type Float interface { + ~float32 | ~float64 +} + +type Complex interface { + ~complex64 | ~complex128 +} diff --git a/src/internal/types/testdata/spec/oldcomparable.go b/src/internal/types/testdata/spec/oldcomparable.go new file mode 100644 index 0000000..081d972 --- /dev/null +++ b/src/internal/types/testdata/spec/oldcomparable.go @@ -0,0 +1,28 @@ +// -oldComparableSemantics + +// Copyright 2022 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. + +package p + +func f1[_ comparable]() {} +func f2[_ interface{ comparable }]() {} + +type T interface{ m() } + +func _[P comparable, Q ~int, R any]() { + _ = f1[int] + _ = f1[T /* ERROR T does not satisfy comparable */] + _ = f1[any /* ERROR any does not satisfy comparable */] + _ = f1[P] + _ = f1[Q] + _ = f1[R /* ERROR R does not satisfy comparable */] + + _ = f2[int] + _ = f2[T /* ERROR T does not satisfy comparable */] + _ = f2[any /* ERROR any does not satisfy comparable */] + _ = f2[P] + _ = f2[Q] + _ = f2[R /* ERROR R does not satisfy comparable */] +} |