Skip to content

Commit fe4f134

Browse files
committed
[dev.typeparams] go/types: move embedding positions from Checker to Interface
This is a straightforward port of CL 331514 to go/types, with minor adjustments for the different position API. Change-Id: I714b3f1cd5a0e8d249912bb589d456885a87e167 Reviewed-on: https://go-review.googlesource.com/c/go/+/335030 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
1 parent b98b8b9 commit fe4f134

File tree

5 files changed

+30
-45
lines changed

5 files changed

+30
-45
lines changed

src/go/types/check.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,11 @@ type Checker struct {
8585
fset *token.FileSet
8686
pkg *Package
8787
*Info
88-
version version // accepted language version
89-
nextID uint64 // unique Id for type parameters (first valid Id is 1)
90-
objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
91-
impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
92-
posMap map[*Interface][]token.Pos // maps interface types to lists of embedded interface positions
93-
typMap map[string]*Named // maps an instantiated named type hash to a *Named type
88+
version version // accepted language version
89+
nextID uint64 // unique Id for type parameters (first valid Id is 1)
90+
objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
91+
impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
92+
typMap map[string]*Named // maps an instantiated named type hash to a *Named type
9493

9594
// pkgPathMap maps package names to the set of distinct import paths we've
9695
// seen for that name, anywhere in the import graph. It is used for
@@ -193,7 +192,6 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch
193192
version: version,
194193
objMap: make(map[Object]*declInfo),
195194
impMap: make(map[importKey]*Package),
196-
posMap: make(map[*Interface][]token.Pos),
197195
typMap: make(map[string]*Named),
198196
}
199197
}

src/go/types/interface.go

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
1616
var tlist []ast.Expr
1717
var tname *ast.Ident // "type" name of first entry in a type list declaration
1818

19+
addEmbedded := func(pos token.Pos, typ Type) {
20+
ityp.embeddeds = append(ityp.embeddeds, typ)
21+
if ityp.embedPos == nil {
22+
ityp.embedPos = new([]token.Pos)
23+
}
24+
*ityp.embedPos = append(*ityp.embedPos, pos)
25+
}
26+
1927
for _, f := range iface.Methods.List {
2028
if len(f.Names) == 0 {
2129
// We have an embedded type; possibly a union of types.
22-
ityp.embeddeds = append(ityp.embeddeds, parseUnion(check, flattenUnion(nil, f.Type)))
23-
check.posMap[ityp] = append(check.posMap[ityp], f.Type.Pos())
30+
addEmbedded(f.Type.Pos(), parseUnion(check, flattenUnion(nil, f.Type)))
2431
continue
2532
}
2633

@@ -92,10 +99,9 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
9299

93100
// type constraints
94101
if tlist != nil {
95-
ityp.embeddeds = append(ityp.embeddeds, parseUnion(check, tlist))
96-
// Types T in a type list are added as ~T expressions but we don't
97-
// have the position of the '~'. Use the first type position instead.
98-
check.posMap[ityp] = append(check.posMap[ityp], tlist[0].(*ast.UnaryExpr).X.Pos())
102+
// TODO(rfindley): this differs from types2 due to the use of Pos() below,
103+
// which should actually be on the ~. Confirm that this position is correct.
104+
addEmbedded(tlist[0].Pos(), parseUnion(check, tlist))
99105
}
100106

101107
// All methods and embedded elements for this interface are collected;
@@ -110,7 +116,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
110116

111117
// sort for API stability
112118
sortMethods(ityp.methods)
113-
sortTypes(ityp.embeddeds)
119+
// (don't sort embeddeds: they must correspond to *embedPos entries)
114120

115121
// Compute type set with a non-nil *Checker as soon as possible
116122
// to report any errors. Subsequent uses of type sets should be
@@ -226,14 +232,13 @@ func newTypeSet(check *Checker, pos token.Pos, ityp *Interface) *TypeSet {
226232

227233
// collect embedded elements
228234
var allTypes Type
229-
var posList []token.Pos
230-
if check != nil {
231-
posList = check.posMap[ityp]
232-
}
233235
for i, typ := range ityp.embeddeds {
236+
// The embedding position is nil for imported interfaces
237+
// and also for interface copies after substitution (but
238+
// in that case we don't need to report errors again).
234239
var pos token.Pos // embedding position
235-
if posList != nil {
236-
pos = posList[i]
240+
if ityp.embedPos != nil {
241+
pos = (*ityp.embedPos)[i]
237242
}
238243
var types Type
239244
switch t := under(typ).(type) {
@@ -268,6 +273,7 @@ func newTypeSet(check *Checker, pos token.Pos, ityp *Interface) *TypeSet {
268273
}
269274
allTypes = intersect(allTypes, types)
270275
}
276+
ityp.embedPos = nil // not needed anymore (errors have been reported)
271277

272278
// process todo's (this only happens if check == nil)
273279
for i := 0; i < len(todo); i += 2 {
@@ -287,24 +293,6 @@ func newTypeSet(check *Checker, pos token.Pos, ityp *Interface) *TypeSet {
287293
return ityp.tset
288294
}
289295

290-
func sortTypes(list []Type) {
291-
sort.Stable(byUniqueTypeName(list))
292-
}
293-
294-
// byUniqueTypeName named type lists can be sorted by their unique type names.
295-
type byUniqueTypeName []Type
296-
297-
func (a byUniqueTypeName) Len() int { return len(a) }
298-
func (a byUniqueTypeName) Less(i, j int) bool { return sortName(a[i]) < sortName(a[j]) }
299-
func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
300-
301-
func sortName(t Type) string {
302-
if named := asNamed(t); named != nil {
303-
return named.obj.Id()
304-
}
305-
return ""
306-
}
307-
308296
func sortMethods(list []*Func) {
309297
sort.Sort(byUniqueMethodName(list))
310298
}

src/go/types/sizeof_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func TestSizeof(t *testing.T) {
2727
{Tuple{}, 12, 24},
2828
{Signature{}, 44, 88},
2929
{Union{}, 24, 48},
30-
{Interface{}, 40, 80},
30+
{Interface{}, 44, 88},
3131
{Map{}, 16, 32},
3232
{Chan{}, 12, 24},
3333
{Named{}, 84, 160},

src/go/types/subst.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ func (subst *subster) typ(typ Type) Type {
320320
if subst.check == nil {
321321
panic("internal error: cannot instantiate interfaces yet")
322322
}
323-
subst.check.posMap[iface] = subst.check.posMap[t] // satisfy completeInterface requirement
324323
return iface
325324
}
326325

src/go/types/type.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,11 @@ func (s *Signature) Variadic() bool { return s.variadic }
258258

259259
// An Interface represents an interface type.
260260
type Interface struct {
261-
obj Object // type name object defining this interface; or nil (for better error messages)
262-
methods []*Func // ordered list of explicitly declared methods
263-
embeddeds []Type // ordered list of explicitly embedded elements
264-
complete bool // indicates that obj, methods, and embeddeds are set and type set can be computed
261+
obj Object // type name object defining this interface; or nil (for better error messages)
262+
methods []*Func // ordered list of explicitly declared methods
263+
embeddeds []Type // ordered list of explicitly embedded elements
264+
embedPos *[]token.Pos // positions of embedded elements; or nil (for error messages) - use pointer to save space
265+
complete bool // indicates that obj, methods, and embeddeds are set and type set can be computed
265266

266267
tset *TypeSet // type set described by this interface, computed lazily
267268
}
@@ -326,7 +327,6 @@ func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
326327

327328
// sort for API stability
328329
sortMethods(methods)
329-
sortTypes(embeddeds)
330330

331331
typ.methods = methods
332332
typ.embeddeds = embeddeds

0 commit comments

Comments
 (0)