Skip to content

Commit

Permalink
apidiff: clarify and add tests
Browse files Browse the repository at this point in the history
Explain the type-splitting cases better.

Add a test where an alias changes incompatibly.

Change-Id: Ib7ce4c8dd7a827e72bf50ea29bd480996f06ff8e
Reviewed-on: https://go-review.googlesource.com/c/exp/+/513135
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
jba committed Jul 28, 2023
1 parent 515e97e commit b0cb94b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 25 deletions.
15 changes: 15 additions & 0 deletions apidiff/testdata/aliases.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package p

// Here the same alias refers to different types in old and new.
// We correctly detect the problem, but the message is poor.

// both
type t1 int
type t2 bool

// old
type A = t1

// new
// i t1: changed from int to bool
type A = t2
71 changes: 46 additions & 25 deletions apidiff/testdata/splitting.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,77 @@
package p

// Splitting types
//
// In the old world, there is one type with two names, one of which is an alias.
// In the new world, there are two distinct types.
//
// That is an incompatible change, because client code like
//
// var v *T1 = new(T2)
//
// will succeed in the old world, where T1 and T2 name the same type,
// but fail in the new world.

// OK: in both old and new, {J1, K1, L1} name the same type.
// OK: in both old and new, A, B, and C all name the same type.
// old
type (
J1 = K1
K1 = L1
L1 int
A = B
B = C
C int
)

// new
type (
J1 = K1
K1 int
L1 = J1
A = B
B int
C = A
)

// Old has one type, K2; new has J2 and K2.
// An example of splitting:

// Old has one type, D; new has E and D.
// both
type K2 int
type D int

// old
type J2 = K2
type E = D

// 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
// i E: changed from D to E
type E D // old D corresponds with new E
// old D also corresponds with new D: problem

// Here we have a benign split.
// f and g are the same type in old and different types in new.
// But clients have no way of constructing an expression of type f,
// so they cannot write code that breaks.

// both
type k3 int
type f int

var Vj3 j3 // expose j3
var Vg g // expose g

// old
type j3 = k3
type g = f

// new
// OK: k3 isn't exposed
type j3 k3
// OK: f isn't exposed
type g f

// Here we have another incompatible split, even
// though the type names are unexported. The problem
// is that both names are exposed via exported variables.

// both
type k4 int
type h int

var Vj4 j4 // expose j4
var VK4 k4 // expose k4
var Vj j // expose j
var Vh h // expose h

// old
type j4 = k4
type j = h

// new
// i Vj4: changed from k4 to j4
// e.g. p.Vj4 = p.Vk4
type j4 k4
// i Vj: changed from h to j
// e.g. p.Vj = p.Vh
type j h

0 comments on commit b0cb94b

Please sign in to comment.