summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/apidiff/testdata/tests.go
diff options
context:
space:
mode:
Diffstat (limited to 'dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/apidiff/testdata/tests.go')
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/apidiff/testdata/tests.go969
1 files changed, 969 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/apidiff/testdata/tests.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/apidiff/testdata/tests.go
new file mode 100644
index 0000000..92823b2
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/apidiff/testdata/tests.go
@@ -0,0 +1,969 @@
+// This file is split into two packages, old and new.
+// It is syntactically valid Go so that gofmt can process it.
+//
+// If a comment begins with: Then:
+// old write subsequent lines to the "old" package
+// new write subsequent lines to the "new" package
+// both write subsequent lines to both packages
+// c expect a compatible error with the following text
+// i expect an incompatible error with the following text
+package ignore
+
+// both
+import "io"
+
+//////////////// Basics
+
+// Same type in both: OK.
+// both
+type A int
+
+// Changing the type is an incompatible change.
+// old
+type B int
+
+// new
+// i B: changed from int to string
+type B string
+
+// Adding a new type, whether alias or not, is a compatible change.
+// new
+// c AA: added
+type AA = A
+
+// c B1: added
+type B1 bool
+
+// Change of type for an unexported name doesn't matter...
+// old
+type t int
+
+// new
+type t string // OK: t isn't part of the API
+
+// ...unless it is exposed.
+// both
+var V2 u
+
+// old
+type u string
+
+// new
+// i u: changed from string to int
+type u int
+
+// An exposed, unexported type can be renamed.
+// both
+type u2 int
+
+// old
+type u1 int
+
+var V5 u1
+
+// new
+var V5 u2 // OK: V5 has changed type, but old u1 corresopnds to new u2
+
+// Splitting a single type into two is an incompatible change.
+// both
+type u3 int
+
+// old
+type (
+ Split1 = u1
+ Split2 = u1
+)
+
+// new
+type (
+ Split1 = u2 // OK, since old u1 corresponds to new u2
+
+ // This tries to make u1 correspond to u3
+ // i Split2: changed from u1 to u3
+ Split2 = u3
+)
+
+// Merging two types into one is OK.
+// old
+type (
+ GoodMerge1 = u2
+ GoodMerge2 = u3
+)
+
+// new
+type (
+ GoodMerge1 = u3
+ GoodMerge2 = u3
+)
+
+// Merging isn't OK here because a method is lost.
+// both
+type u4 int
+
+func (u4) M() {}
+
+// old
+type (
+ BadMerge1 = u3
+ BadMerge2 = u4
+)
+
+// new
+type (
+ BadMerge1 = u3
+ // i u4.M: removed
+ // What's really happening here is that old u4 corresponds to new u3,
+ // and new u3's method set is not a superset of old u4's.
+ BadMerge2 = u3
+)
+
+// old
+type Rem int
+
+// new
+// i Rem: removed
+
+//////////////// Constants
+
+// type changes
+// old
+const (
+ C1 = 1
+ C2 int = 2
+ C3 = 3
+ C4 u1 = 4
+)
+
+var V8 int
+
+// new
+const (
+ // i C1: changed from untyped int to untyped string
+ C1 = "1"
+ // i C2: changed from int to untyped int
+ C2 = -1
+ // i C3: changed from untyped int to int
+ C3 int = 3
+ // i V8: changed from var to const
+ V8 int = 1
+ C4 u2 = 4 // OK: u1 corresponds to u2
+)
+
+// value change
+// old
+const (
+ Cr1 = 1
+ Cr2 = "2"
+ Cr3 = 3.5
+ Cr4 = complex(0, 4.1)
+)
+
+// new
+const (
+ // i Cr1: value changed from 1 to -1
+ Cr1 = -1
+ // i Cr2: value changed from "2" to "3"
+ Cr2 = "3"
+ // i Cr3: value changed from 3.5 to 3.8
+ Cr3 = 3.8
+ // i Cr4: value changed from (0 + 4.1i) to (4.1 + 0i)
+ Cr4 = complex(4.1, 0)
+)
+
+//////////////// Variables
+
+// simple type changes
+// old
+var (
+ V1 string
+ V3 A
+ V7 <-chan int
+)
+
+// new
+var (
+ // i V1: changed from string to []string
+ V1 []string
+ V3 A // OK: same
+ // i V7: changed from <-chan int to chan int
+ V7 chan int
+)
+
+// interface type changes
+// old
+var (
+ V9 interface{ M() }
+ V10 interface{ M() }
+ V11 interface{ M() }
+)
+
+// new
+var (
+ // i V9: changed from interface{M()} to interface{}
+ V9 interface{}
+ // i V10: changed from interface{M()} to interface{M(); M2()}
+ V10 interface {
+ M2()
+ M()
+ }
+ // i V11: changed from interface{M()} to interface{M(int)}
+ V11 interface{ M(int) }
+)
+
+// struct type changes
+// old
+var (
+ VS1 struct{ A, B int }
+ VS2 struct{ A, B int }
+ VS3 struct{ A, B int }
+ VS4 struct {
+ A int
+ u1
+ }
+)
+
+// new
+var (
+ // i VS1: changed from struct{A int; B int} to struct{B int; A int}
+ VS1 struct{ B, A int }
+ // i VS2: changed from struct{A int; B int} to struct{A int}
+ VS2 struct{ A int }
+ // i VS3: changed from struct{A int; B int} to struct{A int; B int; C int}
+ VS3 struct{ A, B, C int }
+ VS4 struct {
+ A int
+ u2
+ }
+)
+
+//////////////// Types
+
+// old
+const C5 = 3
+
+type (
+ A1 [1]int
+ A2 [2]int
+ A3 [C5]int
+)
+
+// new
+// i C5: value changed from 3 to 4
+const C5 = 4
+
+type (
+ A1 [1]int
+ // i A2: changed from [2]int to [2]bool
+ A2 [2]bool
+ // i A3: changed from [3]int to [4]int
+ A3 [C5]int
+)
+
+// old
+type (
+ Sl []int
+ P1 *int
+ P2 *u1
+)
+
+// new
+type (
+ // i Sl: changed from []int to []string
+ Sl []string
+ // i P1: changed from *int to **bool
+ P1 **bool
+ P2 *u2 // OK: u1 corresponds to u2
+)
+
+// old
+type Bc1 int32
+type Bc2 uint
+type Bc3 float32
+type Bc4 complex64
+
+// new
+// c Bc1: changed from int32 to int
+type Bc1 int
+
+// c Bc2: changed from uint to uint64
+type Bc2 uint64
+
+// c Bc3: changed from float32 to float64
+type Bc3 float64
+
+// c Bc4: changed from complex64 to complex128
+type Bc4 complex128
+
+// old
+type Bi1 int32
+type Bi2 uint
+type Bi3 float64
+type Bi4 complex128
+
+// new
+// i Bi1: changed from int32 to int16
+type Bi1 int16
+
+// i Bi2: changed from uint to uint32
+type Bi2 uint32
+
+// i Bi3: changed from float64 to float32
+type Bi3 float32
+
+// i Bi4: changed from complex128 to complex64
+type Bi4 complex64
+
+// old
+type (
+ M1 map[string]int
+ M2 map[string]int
+ M3 map[string]int
+)
+
+// new
+type (
+ M1 map[string]int
+ // i M2: changed from map[string]int to map[int]int
+ M2 map[int]int
+ // i M3: changed from map[string]int to map[string]string
+ M3 map[string]string
+)
+
+// old
+type (
+ Ch1 chan int
+ Ch2 <-chan int
+ Ch3 chan int
+ Ch4 <-chan int
+)
+
+// new
+type (
+ // i Ch1, element type: changed from int to bool
+ Ch1 chan bool
+ // i Ch2: changed direction
+ Ch2 chan<- int
+ // i Ch3: changed direction
+ Ch3 <-chan int
+ // c Ch4: removed direction
+ Ch4 chan int
+)
+
+// old
+type I1 interface {
+ M1()
+ M2()
+}
+
+// new
+type I1 interface {
+ // M1()
+ // i I1.M1: removed
+ M2(int)
+ // i I1.M2: changed from func() to func(int)
+ M3()
+ // i I1.M3: added
+ m()
+ // i I1.m: added unexported method
+}
+
+// old
+type I2 interface {
+ M1()
+ m()
+}
+
+// new
+type I2 interface {
+ M1()
+ // m() Removing an unexported method is OK.
+ m2() // OK, because old already had an unexported method
+ // c I2.M2: added
+ M2()
+}
+
+// old
+type I3 interface {
+ io.Reader
+ M()
+}
+
+// new
+// OK: what matters is the method set; the name of the embedded
+// interface isn't important.
+type I3 interface {
+ M()
+ Read([]byte) (int, error)
+}
+
+// old
+type I4 io.Writer
+
+// new
+// OK: in both, I4 is a distinct type from io.Writer, and
+// the old and new I4s have the same method set.
+type I4 interface {
+ Write([]byte) (int, error)
+}
+
+// old
+type I5 = io.Writer
+
+// new
+// i I5: changed from io.Writer to I5
+// In old, I5 and io.Writer are the same type; in new,
+// they are different. That can break something like:
+//
+// var _ func(io.Writer) = func(pkg.I6) {}
+type I5 io.Writer
+
+// old
+type I6 interface{ Write([]byte) (int, error) }
+
+// new
+// i I6: changed from I6 to io.Writer
+// Similar to the above.
+type I6 = io.Writer
+
+//// correspondence with a basic type
+// Basic types are technically defined types, but they aren't
+// represented that way in go/types, so the cases below are special.
+
+// both
+type T1 int
+
+// old
+var VT1 T1
+
+// new
+// i VT1: changed from T1 to int
+// This fails because old T1 corresponds to both int and new T1.
+var VT1 int
+
+// old
+type t2 int
+
+var VT2 t2
+
+// new
+// OK: t2 corresponds to int. It's fine that old t2
+// doesn't exist in new.
+var VT2 int
+
+// both
+type t3 int
+
+func (t3) M() {}
+
+// old
+var VT3 t3
+
+// new
+// i t3.M: removed
+// Here the change from t3 to int is incompatible
+// because old t3 has an exported method.
+var VT3 int
+
+// old
+var VT4 int
+
+// new
+type t4 int
+
+// i VT4: changed from int to t4
+// This is incompatible because of code like
+//
+// VT4 + int(1)
+//
+// which works in old but fails in new.
+// The difference from the above cases is that
+// in those, we were merging two types into one;
+// here, we are splitting int into t4 and int.
+var VT4 t4
+
+//////////////// Functions
+
+// old
+func F1(a int, b string) map[u1]A { return nil }
+func F2(int) {}
+func F3(int) {}
+func F4(int) int { return 0 }
+func F5(int) int { return 0 }
+func F6(int) {}
+func F7(interface{}) {}
+
+// new
+func F1(c int, d string) map[u2]AA { return nil } //OK: same (since u1 corresponds to u2)
+
+// i F2: changed from func(int) to func(int) bool
+func F2(int) bool { return true }
+
+// i F3: changed from func(int) to func(int, int)
+func F3(int, int) {}
+
+// i F4: changed from func(int) int to func(bool) int
+func F4(bool) int { return 0 }
+
+// i F5: changed from func(int) int to func(int) string
+func F5(int) string { return "" }
+
+// i F6: changed from func(int) to func(...int)
+func F6(...int) {}
+
+// i F7: changed from func(interface{}) to func(interface{x()})
+func F7(a interface{ x() }) {}
+
+// old
+func F8(bool) {}
+
+// new
+// c F8: changed from func to var
+var F8 func(bool)
+
+// old
+var F9 func(int)
+
+// new
+// i F9: changed from var to func
+func F9(int) {}
+
+// both
+// OK, even though new S1 is incompatible with old S1 (see below)
+func F10(S1) {}
+
+//////////////// Structs
+
+// old
+type S1 struct {
+ A int
+ B string
+ C bool
+ d float32
+}
+
+// new
+type S1 = s1
+
+type s1 struct {
+ C chan int
+ // i S1.C: changed from bool to chan int
+ A int
+ // i S1.B: removed
+ // i S1: old is comparable, new is not
+ x []int
+ d float32
+ E bool
+ // c S1.E: added
+}
+
+// old
+type embed struct {
+ E string
+}
+
+type S2 struct {
+ A int
+ embed
+}
+
+// new
+type embedx struct {
+ E string
+}
+
+type S2 struct {
+ embedx // OK: the unexported embedded field changed names, but the exported field didn't
+ A int
+}
+
+// both
+type F int
+
+// old
+type S3 struct {
+ A int
+ embed
+}
+
+// new
+type embed struct{ F int }
+
+type S3 struct {
+ // i S3.E: removed
+ embed
+ // c S3.F: added
+ A int
+}
+
+// old
+type embed2 struct {
+ embed3
+ F // shadows embed3.F
+}
+
+type embed3 struct {
+ F bool
+}
+
+type alias = struct{ D bool }
+
+type S4 struct {
+ int
+ *embed2
+ embed
+ E int // shadows embed.E
+ alias
+ A1
+ *S4
+}
+
+// new
+type S4 struct {
+ // OK: removed unexported fields
+ // D and F marked as added because they are now part of the immediate fields
+ D bool
+ // c S4.D: added
+ E int // OK: same as in old
+ F F
+ // c S4.F: added
+ A1 // OK: same
+ *S4 // OK: same (recursive embedding)
+}
+
+// Difference between exported selectable fields and exported immediate fields.
+// both
+type S5 struct{ A int }
+
+// old
+// Exported immediate fields: A, S5
+// Exported selectable fields: A int, S5 S5
+type S6 struct {
+ S5 S5
+ A int
+}
+
+// new
+// Exported immediate fields: S5
+// Exported selectable fields: A int, S5 S5.
+
+// i S6.A: removed
+type S6 struct {
+ S5
+}
+
+// Ambiguous fields can exist; they just can't be selected.
+// both
+type (
+ embed7a struct{ E int }
+ embed7b struct{ E bool }
+)
+
+// old
+type S7 struct { // legal, but no selectable fields
+ embed7a
+ embed7b
+}
+
+// new
+type S7 struct {
+ embed7a
+ embed7b
+ // c S7.E: added
+ E string
+}
+
+//// Method sets
+
+// old
+type SM struct {
+ embedm
+ Embedm
+}
+
+func (SM) V1() {}
+func (SM) V2() {}
+func (SM) V3() {}
+func (SM) V4() {}
+func (SM) v() {}
+
+func (*SM) P1() {}
+func (*SM) P2() {}
+func (*SM) P3() {}
+func (*SM) P4() {}
+func (*SM) p() {}
+
+type embedm int
+
+func (embedm) EV1() {}
+func (embedm) EV2() {}
+func (embedm) EV3() {}
+func (*embedm) EP1() {}
+func (*embedm) EP2() {}
+func (*embedm) EP3() {}
+
+type Embedm struct {
+ A int
+}
+
+func (Embedm) FV() {}
+func (*Embedm) FP() {}
+
+type RepeatEmbedm struct {
+ Embedm
+}
+
+// new
+type SM struct {
+ embedm2
+ embedm3
+ Embedm
+ // i SM.A: changed from int to bool
+}
+
+// c SMa: added
+type SMa = SM
+
+func (SM) V1() {} // OK: same
+
+// func (SM) V2() {}
+// i SM.V2: removed
+
+// i SM.V3: changed from func() to func(int)
+func (SM) V3(int) {}
+
+// c SM.V5: added
+func (SM) V5() {}
+
+func (SM) v(int) {} // OK: unexported method change
+func (SM) v2() {} // OK: unexported method added
+
+func (*SM) P1() {} // OK: same
+//func (*SM) P2() {}
+// i (*SM).P2: removed
+
+// i (*SM).P3: changed from func() to func(int)
+func (*SMa) P3(int) {}
+
+// c (*SM).P5: added
+func (*SM) P5() {}
+
+// func (*SM) p() {} // OK: unexported method removed
+
+// Changing from a value to a pointer receiver or vice versa
+// just looks like adding and removing a method.
+
+// i SM.V4: removed
+// i (*SM).V4: changed from func() to func(int)
+func (*SM) V4(int) {}
+
+// c SM.P4: added
+// P4 is not removed from (*SM) because value methods
+// are in the pointer method set.
+func (SM) P4() {}
+
+type embedm2 int
+
+// i embedm.EV1: changed from func() to func(int)
+func (embedm2) EV1(int) {}
+
+// i embedm.EV2, method set of SM: removed
+// i embedm.EV2, method set of *SM: removed
+
+// i (*embedm).EP2, method set of *SM: removed
+func (*embedm2) EP1() {}
+
+type embedm3 int
+
+func (embedm3) EV3() {} // OK: compatible with old embedm.EV3
+func (*embedm3) EP3() {} // OK: compatible with old (*embedm).EP3
+
+type Embedm struct {
+ // i Embedm.A: changed from int to bool
+ A bool
+}
+
+// i Embedm.FV: changed from func() to func(int)
+func (Embedm) FV(int) {}
+func (*Embedm) FP() {}
+
+type RepeatEmbedm struct {
+ // i RepeatEmbedm.A: changed from int to bool
+ Embedm
+}
+
+//////////////// Whole-package interface satisfaction
+
+// old
+type WI1 interface {
+ M1()
+ m1()
+}
+
+type WI2 interface {
+ M2()
+ m2()
+}
+
+type WS1 int
+
+func (WS1) M1() {}
+func (WS1) m1() {}
+
+type WS2 int
+
+func (WS2) M2() {}
+func (WS2) m2() {}
+
+// new
+type WI1 interface {
+ M1()
+ m()
+}
+
+type WS1 int
+
+func (WS1) M1() {}
+
+// i WS1: no longer implements WI1
+//func (WS1) m1() {}
+
+type WI2 interface {
+ M2()
+ m2()
+ // i WS2: no longer implements WI2
+ m3()
+}
+
+type WS2 int
+
+func (WS2) M2() {}
+func (WS2) m2() {}
+
+//////////////// Miscellany
+
+// This verifies that the code works even through
+// multiple levels of unexported typed.
+
+// old
+var Z w
+
+type w []x
+type x []z
+type z int
+
+// new
+var Z w
+
+type w []x
+type x []z
+
+// i z: changed from int to bool
+type z bool
+
+// old
+type H struct{}
+
+func (H) M() {}
+
+// new
+// i H: changed from struct{} to interface{M()}
+type H interface {
+ M()
+}
+
+//// Splitting types
+
+// OK: in both old and new, {J1, K1, L1} name the same type.
+// old
+type (
+ J1 = K1
+ K1 = L1
+ L1 int
+)
+
+// new
+type (
+ J1 = K1
+ K1 int
+ L1 = J1
+)
+
+// Old has one type, K2; new has J2 and K2.
+// both
+type K2 int
+
+// old
+type J2 = K2
+
+// new
+// i K2: changed from K2 to K2
+type J2 K2 // old K2 corresponds with new J2
+// old K2 also corresponds with new K2: problem
+
+// both
+type k3 int
+
+var Vj3 j3 // expose j3
+
+// old
+type j3 = k3
+
+// new
+// OK: k3 isn't exposed
+type j3 k3
+
+// both
+type k4 int
+
+var Vj4 j4 // expose j4
+var VK4 k4 // expose k4
+
+// old
+type j4 = k4
+
+// new
+// i Vj4: changed from k4 to j4
+// e.g. p.Vj4 = p.Vk4
+type j4 k4
+
+//// Generics
+
+// old
+type G[T any] []T
+
+// new
+// OK: param name change
+type G[A any] []A
+
+// old
+type GM[A, B comparable] map[A]B
+
+// new
+// i GM: changed from map[A]B to map[B]A
+type GM[A, B comparable] map[B]A
+
+// old
+type GT[V any] struct {
+}
+
+func (GT[V]) M(*GT[V]) {}
+
+// new
+// OK
+type GT[V any] struct {
+}
+
+func (GT[V]) M(*GT[V]) {}
+
+// old
+type GT2[V any] struct {
+}
+
+func (GT2[V]) M(*GT2[V]) {}
+
+// new
+// i GT2: changed from GT2[V any] to GT2[V comparable]
+type GT2[V comparable] struct {
+}
+
+func (GT2[V]) M(*GT2[V]) {}