...

Package p

import "golang.org/x/exp/apidiff/testdata"
Overview
Index

Overview ▾

These tests demonstrate the correct handling of symbols in packages other than two being compared. See the lines in establishCorrespondence beginning

if newn, ok := new.(*types.Named); ok

Constants

const (
    C1     = 1
    C2 int = 2
    C3     = 3
    C4 u1  = 4
)

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)
)

old

const C5 = 3

new i C5: value changed from 3 to 4

const C5 = 4

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
        // contains filtered or unexported fields
    }
)

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
        // contains filtered or unexported fields
    }
)

new c F8: changed from func to var

var F8 func(bool)

old

var F9 func(int)

old

var V io.Writer

new i V: changed from io.Writer to text/tabwriter.Writer

var V tabwriter.Writer

...unless it is exposed. both

var V2 u
var V5 u1

new

var V5 u2 // OK: V5 has changed type, but old u1 corresopnds to new u2
var V8 int

new i VT1: changed from T1 to int This fails because old T1 corresponds to both int and new T1.

var VT1 int
var VT2 t2

new OK: t2 corresponds to int. It's fine that old t2 doesn't exist in new.

var VT2 int

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

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
var Vg g // expose g
var Vh h // expose h
var Vj j // expose j

old

var Z w

new

var Z w

func F1

func F1(a int, b string) map[u1]A

old

func F10

func F10(S)

both OK, even though new S is incompatible with old S (see below)

func F2

func F2(int) bool

i F2: changed from func(int) to func(int) bool

func F3

func F3(int, int)

i F3: changed from func(int) to func(int, int)

func F4

func F4(bool) int

i F4: changed from func(int) int to func(bool) int

func F5

func F5(int) string

i F5: changed from func(int) int to func(int) string

func F6

func F6(...int)

i F6: changed from func(int) to func(...int)

func F7

func F7(a interface{ x() })

i F7: changed from func(interface{}) to func(interface{x()})

func F8

func F8(bool)

old

func F9

func F9(int)

new i F9: changed from var to func

type A

both

type A int

type A1

type A1 [1]int

type A2

i A2: changed from [2]int to [2]bool

type A2 [2]bool

type A3

i A3: changed from [3]int to [4]int

type A3 [C5]int

type AA

new c AA: added

type AA = A

type B

new

type B int

type B1

c B1: added

type B1 bool

type BadMerge1

new

type BadMerge1 = u3

type BadMerge2

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.

type BadMerge2 = u3

type Bc1

new c Bc1: changed from int32 to int

type Bc1 int

type Bc2

c Bc2: changed from uint to uint64

type Bc2 uint64

type Bc3

c Bc3: changed from float32 to float64

type Bc3 float64

type Bc4

c Bc4: changed from complex64 to complex128

type Bc4 complex128

type Bi1

new i Bi1: changed from int32 to int16

type Bi1 int16

type Bi2

i Bi2: changed from uint to uint32

type Bi2 uint32

type Bi3

i Bi3: changed from float64 to float32

type Bi3 float32

type Bi4

i Bi4: changed from complex128 to complex64

type Bi4 complex64

type C

new

type C = A

type Ch1

i Ch1, element type: changed from int to bool

type Ch1 chan bool

type Ch2

i Ch2: changed direction

type Ch2 chan<- int

type Ch3

i Ch3: changed direction

type Ch3 <-chan int

type Ch4

c Ch4: removed direction

type Ch4 chan int

type D

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

type D int

type E

new i E: changed from D to E

type E D // old D corresponds with new E

type Embedm

type Embedm struct {
    // i Embedm.A: changed from int to bool
    A bool
}

func (*Embedm) FP

func (*Embedm) FP()

func (Embedm) FV

func (Embedm) FV(int)

i Embedm.FV: changed from func() to func(int)

type F

both

type F int

type G

new OK: param name change

type G[A any] []A

type GM

new i GM: changed from map[A]B to map[B]A

type GM[A, B comparable] map[B]A

type GT

new OK

type GT[V any] struct {
}

func (GT[V]) M

func (GT[V]) M(*GT[V])

type GT2

new i GT2: changed from GT2[V any] to GT2[V comparable]

type GT2[V comparable] struct {
}

func (GT2[V]) M

func (GT2[V]) M(*GT2[V])

type GT3

type GT3[E custom] map[E]int

type GoodMerge1

new

type GoodMerge1 = u3

type GoodMerge2

new

type GoodMerge2 = u3

type H

new i H: changed from struct{} to interface{M()}

type H interface {
    M()
}

old

var V1 H[int]

new i V1: changed from H[int] to H[bool]

var V1 H[bool]
var V2 H[T]

OK: we reported on T, so we don't need to here.

var V2 H[T]

both

var V3 H[t]

func (H) M

func (H) M()

type I1

new

type I1 interface {
    // M1()
    // i I1.M1: removed
    M2(int)
    // i I1.M2: changed from func() to func(int)
    M3()
    // contains filtered or unexported methods
}

type I2

new

type I2 interface {
    M1()

    // c I2.M2: added
    M2()
    // contains filtered or unexported methods
}

type I3

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)
}

type I4

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)
}

type I5

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

type I6

new i I6: changed from I6 to io.Writer Similar to the above.

type I6 = io.Writer

type M1

new

type M1 map[string]int

type M2

i M2: changed from map[string]int to map[int]int

type M2 map[int]int

type M3

i M3: changed from map[string]int to map[string]string

type M3 map[string]string

type P1

i P1: changed from *int to **bool

type P1 **bool

type P2

new

type P2 *u2 // OK: u1 corresponds to u2

type Rem

old

type Rem int

type RepeatEmbedm

type RepeatEmbedm struct {
    // i RepeatEmbedm.A: changed from int to bool
    Embedm
}

type S

new

type S struct {
    // i S.A: changed from int to bool
    A bool
}

type S1

new

type S1 = s1

type S2

type S2 struct {
    A int
    // contains filtered or unexported fields
}

type S3

type S3 struct {

    // c S3.F: added
    A int
    // contains filtered or unexported fields
}

type 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)
}

type S5

Difference between exported selectable fields and exported immediate fields. both

type S5 struct{ A int }

type S6

i S6.A: removed

type S6 struct {
    S5
}

type S7

new

type S7 struct {

    // c S7.E: added
    E string
    // contains filtered or unexported fields
}

type SM

new

type SM struct {
    Embedm
    // contains filtered or unexported fields
}

func (*SM) EP2

func (*SM) EP2()

func (SM) EV2

func (SM) EV2()

func (*SM) P1

func (*SM) P1()

func (*SM) P2

func (*SM) P2()

func (*SM) P3

func (*SM) P3()

func (SM) P4

func (SM) P4()

c SM.P4: added P4 is not removed from (*SM) because value methods are in the pointer method set.

func (*SM) P5

func (*SM) P5()

c (*SM).P5: added

func (SM) V1

func (SM) V1()

func (SM) V2

func (SM) V2()

func (SM) V3

func (SM) V3(int)

i SM.V3: changed from func() to func(int)

func (*SM) V4

func (*SM) V4(int)

i SM.V4: removed i (*SM).V4: changed from func() to func(int)

func (SM) V5

func (SM) V5()

c SM.V5: added

type SMa

c SMa: added

type SMa = SM

func (*SMa) P3

func (*SMa) P3(int)

i (*SM).P3: changed from func() to func(int)

type Sl

i Sl: changed from []int to []string

type Sl []string

type Split1

new

type Split1 = u2 // OK, since old u1 corresponds to new u2

type Split2

This tries to make u1 correspond to u3 i Split2: changed from u1 to u3

type Split2 = u3

type T

both

type T int

type T1

both

type T1 int

old

var VT1 T1

type U

new i U: changed from T to U

type U T

type WI1

new

type WI1 interface {
    M1()
    // contains filtered or unexported methods
}

type WI2

type WI2 interface {
    M2()
    // contains filtered or unexported methods
}

type WS1

type WS1 int

func (WS1) M1

func (WS1) M1()

type WS2

type WS2 int

func (WS2) M2

func (WS2) M2()