Skip to content

Commit ce04ca3

Browse files
committed
go/internal/gcimporter: normalize implicit interfaces in export tests
The export data format does not yet support capturing whether interfaces are implicit, so normalize them for the purposes of comparing type parameter constraints. Change-Id: I678fb5f5fe6481b9a1479176ca056a31d17bbd77 Reviewed-on: https://go-review.googlesource.com/c/tools/+/355971 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 3a269dc commit ce04ca3

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

go/internal/gcimporter/bexport_test.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ func equalType(x, y types.Type) error {
200200
return fmt.Errorf("mismatched %s method: %s", xm.Name(), err)
201201
}
202202
}
203+
// Constraints are handled explicitly in the *TypeParam case below, so we
204+
// don't yet need to consider embeddeds here.
205+
// TODO(rfindley): consider the type set here.
203206
case *types.Array:
204207
y := y.(*types.Array)
205208
if x.Len() != y.Len() {
@@ -315,9 +318,12 @@ func equalType(x, y types.Type) error {
315318
return fmt.Errorf("unequal named types: %s vs %s", x, y)
316319
}
317320
// For now, just compare constraints by type string to short-circuit
318-
// cycles.
319-
xc := sanitizeName(x.Constraint().String())
320-
yc := sanitizeName(y.Constraint().String())
321+
// cycles. We have to make interfaces explicit as export data currently
322+
// doesn't support marking interfaces as implicit.
323+
// TODO(rfindley): remove makeExplicit once export data contains an
324+
// implicit bit.
325+
xc := sanitizeName(makeExplicit(x.Constraint()).String())
326+
yc := sanitizeName(makeExplicit(y.Constraint()).String())
321327
if xc != yc {
322328
return fmt.Errorf("unequal constraints: %s vs %s", xc, yc)
323329
}
@@ -328,6 +334,23 @@ func equalType(x, y types.Type) error {
328334
return nil
329335
}
330336

337+
// makeExplicit returns an explicit version of typ, if typ is an implicit
338+
// interface. Otherwise it returns typ unmodified.
339+
func makeExplicit(typ types.Type) types.Type {
340+
if iface, _ := typ.(*types.Interface); iface != nil && typeparams.IsImplicit(iface) {
341+
var methods []*types.Func
342+
for i := 0; i < iface.NumExplicitMethods(); i++ {
343+
methods = append(methods, iface.Method(i))
344+
}
345+
var embeddeds []types.Type
346+
for i := 0; i < iface.NumEmbeddeds(); i++ {
347+
embeddeds = append(embeddeds, iface.EmbeddedType(i))
348+
}
349+
return types.NewInterfaceType(methods, embeddeds)
350+
}
351+
return typ
352+
}
353+
331354
func equalTypeArgs(x, y *typeparams.TypeList) error {
332355
if x.Len() != y.Len() {
333356
return fmt.Errorf("unequal lengths: %d vs %d", x.Len(), y.Len())

go/internal/gcimporter/iexport_go118_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ func ToInt[P interface{ ~int }](p P) int { return int(p) }
3636
var IntID = ToInt[int]
3737
3838
type G[C comparable] int
39+
40+
func ImplicitFunc[T ~int]() {}
41+
42+
type ImplicitType[T ~int] int
3943
`
4044
testExportSrc(t, []byte(src))
4145
}

internal/typeparams/typeparams_go117.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ func IsMethodSet(*types.Interface) bool {
132132
return true
133133
}
134134

135+
// IsImplicit returns false, as no interfaces are implicit at this Go version.
136+
func IsImplicit(*types.Interface) bool {
137+
return false
138+
}
139+
135140
// ForNamed returns an empty type parameter list, as type parameters are not
136141
// supported at this Go version.
137142
func ForNamed(*types.Named) *TypeParamList {

internal/typeparams/typeparams_go118.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ func IsMethodSet(iface *types.Interface) bool {
125125
return iface.IsMethodSet()
126126
}
127127

128+
// IsImplicit calls iface.IsImplicit().
129+
func IsImplicit(iface *types.Interface) bool {
130+
return iface.IsImplicit()
131+
}
132+
128133
// ForNamed extracts the (possibly empty) type parameter object list from
129134
// named.
130135
func ForNamed(named *types.Named) *TypeParamList {

0 commit comments

Comments
 (0)