Skip to content

Commit 03bd43e

Browse files
Mark Freemangopherbot
authored andcommitted
go/types, types2: rename Named.resolve to unpack
Named.resolve normalizes a named type's representation so that type operations have a uniform surface to work with, regardless of how the type was created. This often gives the type a heavier footprint, such as when filling in a lazy-loaded type from UIR, or expanding the RHS of an instantiated type. For that reason, it seems more appropriate to call this "unpacking" the type, as it hints to this heavier form. The term "resolving" is used in many contexts, and generally suggests that we are trying to figure out what a name means. Change-Id: Ia733fd68656380b2be4f7433b7b971b7c1422783 Reviewed-on: https://go-review.googlesource.com/c/go/+/713285 Auto-Submit: Mark Freeman <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 9fcdc81 commit 03bd43e

File tree

8 files changed

+110
-106
lines changed

8 files changed

+110
-106
lines changed

src/cmd/compile/internal/types2/decl.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *TypeN
536536
assert(rhs != nil)
537537

538538
alias.fromRHS = rhs
539-
unalias(alias) // resolve alias.actual
539+
unalias(alias) // populate alias.actual
540540
} else {
541541
if !versionErr && tparam0 != nil {
542542
check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1 or unset")
@@ -561,9 +561,9 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *TypeN
561561
// The RHS of a named N can be nil if, for example, N is defined as a cycle of aliases with
562562
// gotypesalias=0. Consider:
563563
//
564-
// type D N // N.resolve() will panic
564+
// type D N // N.unpack() will panic
565565
// type N A
566-
// type A = N // N.fromRHS is not set before N.resolve(), since A does not call setDefType
566+
// type A = N // N.fromRHS is not set before N.unpack(), since A does not call setDefType
567567
//
568568
// There is likely a better way to detect such cases, but it may not be worth the effort.
569569
// Instead, we briefly permit a nil N.fromRHS while type-checking D.

src/cmd/compile/internal/types2/named.go

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
// In cases 1, 3, and 4, it is possible that the underlying type or methods of
3434
// N may not be immediately available.
3535
// - During type-checking, we allocate N before type-checking its underlying
36-
// type or methods, so that we may resolve recursive references.
36+
// type or methods, so that we can create recursive references.
3737
// - When loading from export data, we may load its methods and underlying
3838
// type lazily using a provided load function.
3939
// - After instantiating, we lazily expand the underlying type and methods
@@ -57,12 +57,14 @@ import (
5757
// declaration in the source. Instantiated named types correspond to a type
5858
// instantiation in the source, not a declaration. But their Origin type is
5959
// a declared type.
60-
// - We say that a Named type is "resolved" if its RHS information has been
61-
// loaded or fully type-checked. For Named types constructed from export
62-
// data, this may involve invoking a loader function to extract information
63-
// from export data. For instantiated Named types this involves reading
64-
// information from their origin and substituting type arguments into a
65-
// "synthetic" RHS; this process is called "expanding" the RHS (see below).
60+
// - We say that a Named type is "unpacked" if its RHS information has been
61+
// populated, normalizing its representation for use in type-checking
62+
// operations and abstracting away how it was created:
63+
// - For a Named type constructed from unified IR, this involves invoking
64+
// a lazy loader function to extract details from UIR as needed.
65+
// - For an instantiated Named type, this involves extracting information
66+
// from its origin and substituting type arguments into a "synthetic"
67+
// RHS; this process is called "expanding" the RHS (see below).
6668
// - We say that a Named type is "expanded" if it is an instantiated type and
6769
// type parameters in its RHS and methods have been substituted with the type
6870
// arguments from the instantiation. A type may be partially expanded if some
@@ -138,16 +140,16 @@ type instance struct {
138140

139141
// stateMask represents each state in the lifecycle of a named type.
140142
//
141-
// Each named type begins in the unresolved state. A named type may transition to a new state
143+
// Each named type begins in the initial state. A named type may transition to a new state
142144
// according to the below diagram:
143145
//
144-
// unresolved
146+
// initial
145147
// lazyLoaded
146-
// resolved
148+
// unpacked
147149
// └── hasMethods
148150
// └── hasUnder
149151
//
150-
// That is, descent down the tree is mostly linear (unresolved through resolved), except upon
152+
// That is, descent down the tree is mostly linear (initial through unpacked), except upon
151153
// reaching the leaves (hasMethods and hasUnder). A type may occupy any combination of the
152154
// leaf states at once (they are independent states).
153155
//
@@ -157,20 +159,20 @@ type instance struct {
157159
// The above constraints significantly narrow the possible bit sets for a named type. With bits
158160
// set left-to-right, they are:
159161
//
160-
// 0000 | unresolved
162+
// 0000 | initial
161163
// 1000 | lazyLoaded
162-
// 1100 | resolved, which implies lazyLoaded
163-
// 1110 | hasMethods, which implies resolved (which in turn implies lazyLoaded)
164-
// 1101 | hasUnder, which implies resolved ...
165-
// 1111 | both hasMethods and hasUnder which implies resolved ...
164+
// 1100 | unpacked, which implies lazyLoaded
165+
// 1110 | hasMethods, which implies unpacked (which in turn implies lazyLoaded)
166+
// 1101 | hasUnder, which implies unpacked ...
167+
// 1111 | both hasMethods and hasUnder which implies unpacked ...
166168
//
167169
// To read the state of a named type, use [Named.stateHas]; to write, use [Named.setState].
168170
type stateMask uint32
169171

170172
const (
171-
// before resolved, type parameters, RHS, underlying, and methods might be unavailable
173+
// initially, type parameters, RHS, underlying, and methods might be unavailable
172174
lazyLoaded stateMask = 1 << iota // methods are available, but constraints might be unexpanded (for generic types)
173-
resolved // methods might be unexpanded (for instances)
175+
unpacked // methods might be unexpanded (for instances)
174176
hasMethods // methods are all expanded (for instances)
175177
hasUnder // underlying type is available
176178
)
@@ -193,27 +195,27 @@ func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
193195

194196
}
195197

196-
// resolve resolves the type parameters, methods, and RHS of n.
198+
// unpack populates the type parameters, methods, and RHS of n.
197199
//
198-
// For the purposes of resolution, there are three categories of named types:
199-
// 1. Instantiated Types
200-
// 2. Lazy Loaded Types
201-
// 3. All Others
200+
// For the purposes of unpacking, there are three categories of named types:
201+
// 1. Lazy loaded types
202+
// 2. Instantiated types
203+
// 3. All others
202204
//
203205
// Note that the above form a partition.
204206
//
205-
// Instantiated types:
206-
// Type parameters, methods, and RHS of n become accessible, though methods
207-
// are lazily populated as needed.
208-
//
209207
// Lazy loaded types:
210208
// Type parameters, methods, and RHS of n become accessible and are fully
211209
// expanded.
212210
//
211+
// Instantiated types:
212+
// Type parameters, methods, and RHS of n become accessible, though methods
213+
// are lazily populated as needed.
214+
//
213215
// All others:
214216
// Effectively, nothing happens.
215-
func (n *Named) resolve() *Named {
216-
if n.stateHas(resolved | lazyLoaded) { // avoid locking below
217+
func (n *Named) unpack() *Named {
218+
if n.stateHas(unpacked | lazyLoaded) { // avoid locking below
217219
return n
218220
}
219221

@@ -223,28 +225,28 @@ func (n *Named) resolve() *Named {
223225
defer n.mu.Unlock()
224226

225227
// only atomic for consistency; we are holding the mutex
226-
if n.stateHas(resolved | lazyLoaded) {
228+
if n.stateHas(unpacked | lazyLoaded) {
227229
return n
228230
}
229231

230-
// underlying comes after resolving, do not set it
232+
// underlying comes after unpacking, do not set it
231233
defer (func() { assert(!n.stateHas(hasUnder)) })()
232234

233235
if n.inst != nil {
234236
assert(n.fromRHS == nil) // instantiated types are not declared types
235237
assert(n.loader == nil) // cannot import an instantiation
236238

237239
orig := n.inst.orig
238-
orig.resolve()
240+
orig.unpack()
239241

240242
n.fromRHS = n.expandRHS()
241243
n.tparams = orig.tparams
242244

243245
if len(orig.methods) == 0 {
244-
n.setState(resolved | hasMethods) // nothing further to do
246+
n.setState(unpacked | hasMethods) // nothing further to do
245247
n.inst.ctxt = nil
246248
} else {
247-
n.setState(resolved)
249+
n.setState(unpacked)
248250
}
249251
return n
250252
}
@@ -273,7 +275,7 @@ func (n *Named) resolve() *Named {
273275
}
274276
}
275277

276-
n.setState(resolved | hasMethods)
278+
n.setState(unpacked | hasMethods)
277279
return n
278280
}
279281

@@ -359,13 +361,13 @@ func (t *Named) Origin() *Named {
359361

360362
// TypeParams returns the type parameters of the named type t, or nil.
361363
// The result is non-nil for an (originally) generic type even if it is instantiated.
362-
func (t *Named) TypeParams() *TypeParamList { return t.resolve().tparams }
364+
func (t *Named) TypeParams() *TypeParamList { return t.unpack().tparams }
363365

364366
// SetTypeParams sets the type parameters of the named type t.
365367
// t must not have type arguments.
366368
func (t *Named) SetTypeParams(tparams []*TypeParam) {
367369
assert(t.inst == nil)
368-
t.resolve().tparams = bindTParams(tparams)
370+
t.unpack().tparams = bindTParams(tparams)
369371
}
370372

371373
// TypeArgs returns the type arguments used to instantiate the named type t.
@@ -378,7 +380,7 @@ func (t *Named) TypeArgs() *TypeList {
378380

379381
// NumMethods returns the number of explicit methods defined for t.
380382
func (t *Named) NumMethods() int {
381-
return len(t.Origin().resolve().methods)
383+
return len(t.Origin().unpack().methods)
382384
}
383385

384386
// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
@@ -393,7 +395,7 @@ func (t *Named) NumMethods() int {
393395
// But the specific ordering is not specified and must not be relied on as it may
394396
// change in the future.
395397
func (t *Named) Method(i int) *Func {
396-
t.resolve()
398+
t.unpack()
397399

398400
if t.stateHas(hasMethods) {
399401
return t.methods[i]
@@ -501,7 +503,7 @@ func (t *Named) SetUnderlying(u Type) {
501503

502504
t.fromRHS = u
503505
t.allowNilRHS = false
504-
t.setState(resolved | hasMethods) // TODO(markfreeman): Why hasMethods?
506+
t.setState(unpacked | hasMethods) // TODO(markfreeman): Why hasMethods?
505507

506508
t.underlying = u
507509
t.allowNilUnderlying = false
@@ -514,7 +516,7 @@ func (t *Named) SetUnderlying(u Type) {
514516
func (t *Named) AddMethod(m *Func) {
515517
assert(samePkg(t.obj.pkg, m.pkg))
516518
assert(t.inst == nil)
517-
t.resolve()
519+
t.unpack()
518520
if t.methodIndex(m.name, false) < 0 {
519521
t.methods = append(t.methods, m)
520522
}
@@ -549,7 +551,7 @@ func (t *Named) methodIndex(name string, foldCase bool) int {
549551
//
550552
// [underlying type]: https://go.dev/ref/spec#Underlying_types.
551553
func (n *Named) Underlying() Type {
552-
n.resolve()
554+
n.unpack()
553555

554556
// The gccimporter depends on writing a nil underlying via NewNamed and
555557
// immediately reading it back. Rather than putting that in Named.under
@@ -583,12 +585,12 @@ func (t *Named) String() string { return TypeString(t, nil) }
583585
// skipped because their underlying type is not memoized.
584586
//
585587
// This function also checks for instantiated layout cycles, which are
586-
// reachable only in the case where resolve() expanded an instantiated
588+
// reachable only in the case where unpack() expanded an instantiated
587589
// type which became self-referencing without indirection.
588590
// If such a cycle is found, the underlying type is set to Typ[Invalid]
589591
// and a cycle is reported.
590592
func (n *Named) resolveUnderlying() {
591-
assert(n.stateHas(resolved))
593+
assert(n.stateHas(unpacked))
592594

593595
var seen map[*Named]int // allocated lazily
594596
var u Type
@@ -626,7 +628,7 @@ func (n *Named) resolveUnderlying() {
626628
}
627629
seen[t] = len(seen)
628630

629-
t.resolve()
631+
t.unpack()
630632
t.mu.Lock()
631633
defer t.mu.Unlock()
632634

@@ -652,7 +654,7 @@ func (n *Named) resolveUnderlying() {
652654
}
653655

654656
func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
655-
n.resolve()
657+
n.unpack()
656658
if samePkg(n.obj.pkg, pkg) || isExported(name) || foldCase {
657659
// If n is an instance, we may not have yet instantiated all of its methods.
658660
// Look up the method index in orig, and only instantiate method at the
@@ -715,8 +717,8 @@ func (n *Named) expandRHS() (rhs Type) {
715717
}()
716718
}
717719

718-
assert(!n.stateHas(resolved))
719-
assert(n.inst.orig.stateHas(resolved | lazyLoaded))
720+
assert(!n.stateHas(unpacked))
721+
assert(n.inst.orig.stateHas(unpacked | lazyLoaded))
720722

721723
if n.inst.ctxt == nil {
722724
n.inst.ctxt = NewContext()

src/cmd/compile/internal/types2/object.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ func NewTypeName(pos syntax.Pos, pkg *Package, name string, typ Type) *TypeName
292292
}
293293

294294
// NewTypeNameLazy returns a new defined type like NewTypeName, but it
295-
// lazily calls resolve to finish constructing the Named object.
295+
// lazily calls unpack to finish constructing the Named object.
296296
func NewTypeNameLazy(pos syntax.Pos, pkg *Package, name string, load func(*Named) ([]*TypeParam, Type, []*Func, []func())) *TypeName {
297297
obj := NewTypeName(pos, pkg, name, nil)
298298
n := (*Checker)(nil).newNamed(obj, nil, nil)

src/cmd/compile/internal/types2/validtype.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func (check *Checker) validType0(pos syntax.Pos, typ Type, nest, path []*Named)
119119
assert(t.obj.pkg == check.pkg)
120120
assert(t.Origin().obj.pkg == check.pkg)
121121

122-
// let t become invalid when it resolves
122+
// let t become invalid when it is unpacked
123123
t.Origin().fromRHS = Typ[Invalid]
124124

125125
// Find the starting point of the cycle and report it.

src/go/types/decl.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *TypeName
611611
assert(rhs != nil)
612612

613613
alias.fromRHS = rhs
614-
unalias(alias) // resolve alias.actual
614+
unalias(alias) // populate alias.actual
615615
} else {
616616
// With Go1.23, the default behavior is to use Alias nodes,
617617
// reflected by check.enableAlias. Signal non-default behavior.
@@ -643,9 +643,9 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *TypeName
643643
// The RHS of a named N can be nil if, for example, N is defined as a cycle of aliases with
644644
// gotypesalias=0. Consider:
645645
//
646-
// type D N // N.resolve() will panic
646+
// type D N // N.unpack() will panic
647647
// type N A
648-
// type A = N // N.fromRHS is not set before N.resolve(), since A does not call setDefType
648+
// type A = N // N.fromRHS is not set before N.unpack(), since A does not call setDefType
649649
//
650650
// There is likely a better way to detect such cases, but it may not be worth the effort.
651651
// Instead, we briefly permit a nil N.fromRHS while type-checking D.

0 commit comments

Comments
 (0)