// Two types are correspond if they are identical except for defined types, // which must correspond. // // Two defined types correspond if they can be interchanged in the old and new APIs, // possibly after a renaming. // // This is not a pure function. If we come across named types while traversing, // we establish correspondence. func (d *differ) correspond(old, new types.Type) bool { … } // corr determines whether old and new correspond. The argument p is a list of // known interface identities, to avoid infinite recursion. // // corr calls itself recursively as much as possible, to establish more // correspondences and so check more of the API. E.g. if the new function has more // parameters than the old, compare all the old ones before returning false. // // Compare this to the implementation of go/types.Identical. func (d *differ) corr(old, new types.Type, p *ifacePair) bool { … } // Compare old and new field names. We are determining correspondence across packages, // so just compare names, not packages. For an unexported, embedded field of named // type (non-named embedded fields are possible with aliases), we check that the type // names correspond. We check the types for correspondence before this is called, so // we've established correspondence. func (d *differ) corrFieldNames(of, nf *types.Var) bool { … } // Establish that old corresponds with new if it does not already // correspond to something else. func (d *differ) establishCorrespondence(old *types.Named, new types.Type) bool { … } func (d *differ) sortedMethods(iface *types.Interface) []*types.Func { … } func (d *differ) methodID(m *types.Func) string { … } type ifacePair … func (p *ifacePair) identical(q *ifacePair) bool { … }