1 // This file is split into two packages, old and new.
2 // It is syntactically valid Go so that gofmt can process it.
4 // If a comment begins with: Then:
5 // old write subsequent lines to the "old" package
6 // new write subsequent lines to the "new" package
7 // both write subsequent lines to both packages
8 // c expect a compatible error with the following text
9 // i expect an incompatible error with the following text
15 //////////////// Basics
17 //// Same type in both: OK.
21 //// Changing the type is an incompatible change.
26 // i B: changed from int to string
29 //// Adding a new type, whether alias or not, is a compatible change.
37 //// Change of type for an unexported name doesn't matter...
42 type t string // OK: t isn't part of the API
44 //// ...unless it is exposed.
52 // i u: changed from string to int
55 //// An exposed, unexported type can be renamed.
65 var V5 u2 // OK: V5 has changed type, but old u1 corresopnds to new u2
67 //// Splitting a single type into two is an incompatible change.
79 Split1 = u2 // OK, since old u1 corresponds to new u2
81 // This tries to make u1 correspond to u3
82 // i Split2: changed from u1 to u3
86 //// Merging two types into one is OK.
99 //// Merging isn't OK here because a method is lost.
115 // What's really happening here is that old u4 corresponds to new u3,
116 // and new u3's method set is not a superset of old u4's.
126 //////////////// Constants
141 // i C1: changed from untyped int to untyped string
143 // i C2: changed from int to untyped int
145 // i C3: changed from untyped int to int
147 // i V8: changed from var to const
149 C4 u2 = 4 // OK: u1 corresponds to u2
158 Cr4 = complex(0, 4.1)
163 // i Cr1: value changed from 1 to -1
165 // i Cr2: value changed from "2" to "3"
167 // i Cr3: value changed from 3.5 to 3.8
169 // i Cr4: value changed from (0 + 4.1i) to (4.1 + 0i)
170 Cr4 = complex(4.1, 0)
173 //////////////// Variables
175 //// simple type changes
185 // i V1: changed from string to []string
188 // i V7: changed from <-chan int to chan int
192 //// interface type changes
202 // i V9: changed from interface{M()} to interface{}
204 // i V10: changed from interface{M()} to interface{M(); M2()}
209 // i V11: changed from interface{M()} to interface{M(int)}
210 V11 interface{ M(int) }
213 //// struct type changes
216 VS1 struct{ A, B int }
217 VS2 struct{ A, B int }
218 VS3 struct{ A, B int }
227 // i VS1: changed from struct{A int; B int} to struct{B int; A int}
228 VS1 struct{ B, A int }
229 // i VS2: changed from struct{A int; B int} to struct{A int}
231 // i VS3: changed from struct{A int; B int} to struct{A int; B int; C int}
232 VS3 struct{ A, B, C int }
239 //////////////// Types
251 // i C5: value changed from 3 to 4
256 // i A2: changed from [2]int to [2]bool
258 // i A3: changed from [3]int to [4]int
271 // i Sl: changed from []int to []string
273 // i P1: changed from *int to **bool
275 P2 *u2 // OK: u1 corresponds to u2
285 // c Bc1: changed from int32 to int
288 // c Bc2: changed from uint to uint64
291 // c Bc3: changed from float32 to float64
294 // c Bc4: changed from complex64 to complex128
304 // i Bi1: changed from int32 to int16
307 // i Bi2: changed from uint to uint32
310 // i Bi3: changed from float64 to float32
313 // i Bi4: changed from complex128 to complex64
326 // i M2: changed from map[string]int to map[int]int
328 // i M3: changed from map[string]int to map[string]string
342 // i Ch1, element type: changed from int to bool
344 // i Ch2: changed direction
346 // i Ch3: changed direction
348 // c Ch4: removed direction
363 // i I1.M2: changed from func() to func(int)
367 // i I1.m: added unexported method
379 // m() Removing an unexported method is OK.
380 m2() // OK, because old already had an unexported method
392 // OK: what matters is the method set; the name of the embedded
393 // interface isn't important.
396 Read([]byte) (int, error)
403 // OK: in both, I4 is a distinct type from io.Writer, and
404 // the old and new I4s have the same method set.
406 Write([]byte) (int, error)
413 // i I5: changed from io.Writer to I5
414 // In old, I5 and io.Writer are the same type; in new,
415 // they are different. That can break something like:
416 // var _ func(io.Writer) = func(pkg.I6) {}
420 type I6 interface{ Write([]byte) (int, error) }
423 // i I6: changed from I6 to io.Writer
424 // Similar to the above.
427 //// correspondence with a basic type
428 // Basic types are technically defined types, but they aren't
429 // represented that way in go/types, so the cases below are special.
438 // i VT1: changed from T1 to int
439 // This fails because old T1 corresponds to both int and new T1.
448 // OK: t2 corresponds to int. It's fine that old t2
449 // doesn't exist in new.
462 // Here the change from t3 to int is incompatible
463 // because old t3 has an exported method.
472 // i VT4: changed from int to t4
473 // This is incompatible because of code like
475 // which works in old but fails in new.
476 // The difference from the above cases is that
477 // in those, we were merging two types into one;
478 // here, we are splitting int into t4 and int.
481 //////////////// Functions
484 func F1(a int, b string) map[u1]A { return nil }
487 func F4(int) int { return 0 }
488 func F5(int) int { return 0 }
490 func F7(interface{}) {}
493 func F1(c int, d string) map[u2]AA { return nil } //OK: same (since u1 corresponds to u2)
495 // i F2: changed from func(int) to func(int) bool
496 func F2(int) bool { return true }
498 // i F3: changed from func(int) to func(int, int)
501 // i F4: changed from func(int) int to func(bool) int
502 func F4(bool) int { return 0 }
504 // i F5: changed from func(int) int to func(int) string
505 func F5(int) string { return "" }
507 // i F6: changed from func(int) to func(...int)
510 // i F7: changed from func(interface{}) to func(interface{x()})
511 func F7(a interface{ x() }) {}
517 // c F8: changed from func to var
524 // i F9: changed from var to func
528 // OK, even though new S1 is incompatible with old S1 (see below)
531 //////////////// Structs
546 // i S1.C: changed from bool to chan int
549 // i S1: old is comparable, new is not
572 embedx // OK: the unexported embedded field changed names, but the exported field didn't
586 type embed struct{ F int }
598 F // shadows embed3.F
605 type alias = struct{ D bool }
611 E int // shadows embed.E
619 // OK: removed unexported fields
620 // D and F marked as added because they are now part of the immediate fields
623 E int // OK: same as in old
627 *S4 // OK: same (recursive embedding)
630 //// Difference between exported selectable fields and exported immediate fields.
632 type S5 struct{ A int }
635 // Exported immediate fields: A, S5
636 // Exported selectable fields: A int, S5 S5
643 // Exported immediate fields: S5
644 // Exported selectable fields: A int, S5 S5.
651 //// Ambiguous fields can exist; they just can't be selected.
654 embed7a struct{ E int }
655 embed7b struct{ E bool }
659 type S7 struct { // legal, but no selectable fields
672 //////////////// Method sets
694 func (embedm) EV1() {}
695 func (embedm) EV2() {}
696 func (embedm) EV3() {}
697 func (*embedm) EP1() {}
698 func (*embedm) EP2() {}
699 func (*embedm) EP3() {}
705 func (Embedm) FV() {}
706 func (*Embedm) FP() {}
708 type RepeatEmbedm struct {
717 // i SM.A: changed from int to bool
723 func (SM) V1() {} // OK: same
728 // i SM.V3: changed from func() to func(int)
734 func (SM) v(int) {} // OK: unexported method change
735 func (SM) v2() {} // OK: unexported method added
737 func (*SM) P1() {} // OK: same
739 // i (*SM).P2: removed
741 // i (*SM).P3: changed from func() to func(int)
742 func (*SMa) P3(int) {}
747 // func (*SM) p() {} // OK: unexported method removed
749 // Changing from a value to a pointer receiver or vice versa
750 // just looks like adding and removing a method.
753 // i (*SM).V4: changed from func() to func(int)
754 func (*SM) V4(int) {}
757 // P4 is not removed from (*SM) because value methods
758 // are in the pointer method set.
763 // i embedm.EV1: changed from func() to func(int)
764 func (embedm2) EV1(int) {}
766 // i embedm.EV2, method set of SM: removed
767 // i embedm.EV2, method set of *SM: removed
769 // i (*embedm).EP2, method set of *SM: removed
770 func (*embedm2) EP1() {}
774 func (embedm3) EV3() {} // OK: compatible with old embedm.EV3
775 func (*embedm3) EP3() {} // OK: compatible with old (*embedm).EP3
778 // i Embedm.A: changed from int to bool
782 // i Embedm.FV: changed from func() to func(int)
783 func (Embedm) FV(int) {}
784 func (*Embedm) FP() {}
786 type RepeatEmbedm struct {
787 // i RepeatEmbedm.A: changed from int to bool
791 //////////////// Whole-package interface satisfaction
824 // i WS1: no longer implements WI1
830 // i WS2: no longer implements WI2
839 //////////////// Miscellany
841 // This verifies that the code works even through
842 // multiple levels of unexported typed.
857 // i z: changed from int to bool
866 // i H: changed from struct{} to interface{M()}
873 //// OK: in both old and new, {J1, K1, L1} name the same type.
888 //// Old has one type, K2; new has J2 and K2.
896 // i K2: changed from K2 to K2
897 type J2 K2 // old K2 corresponds with new J2
898 // old K2 also corresponds with new K2: problem
903 var Vj3 j3 // expose j3
909 // OK: k3 isn't exposed
915 var Vj4 j4 // expose j4
916 var VK4 k4 // expose k4
922 // i Vj4: changed from k4 to j4
923 // e.g. p.Vj4 = p.Vk4