aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/lookup.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-05-29 15:35:18 -0700
committerMatthew Dempsky <mdempsky@google.com>2021-06-04 04:28:10 +0000
commit2175e2f57331cbcd32bccc47fa7fe7a6874a69a3 (patch)
treed16af47d239c050c58628a3f485622400ba2fb8d /src/cmd/compile/internal/types2/lookup.go
parent4d2b528795fe2534398d1b1a978e1037d4a9d2f0 (diff)
downloadgo-2175e2f57331cbcd32bccc47fa7fe7a6874a69a3.tar.gz
go-2175e2f57331cbcd32bccc47fa7fe7a6874a69a3.zip
[dev.typeparams] cmd/compile: lazy import resolution for types2
This CL adds three new functions to the types2 API to support lazy import resolution: 1. A new Scope.InsertLazy method to allow recording that Objects exist in a particular Scope (in particular, package scopes) without having to yet fully construct those objects. Instead, types2 will call the provided `resolve` function if/when the object is actually needed. 2. Similarly, a new NewTypeNameLazy function to create TypeName objects without yet instantiating their underlying Named instance. 3. Finally, an InstantiateLazy method, that allows creating type instances without requiring any of the types to be expanded right away. Importantly, this requires providing a types2.Checker argument to handle recursive types correctly. The APIs as-is are a bit clumsy (esp. NewTypeNameLazy), but seem to work well for cmd/compile's needs. In particular, they simplify some of the complexities of handling recursive type definitions within the importer. Also, the current prototype is a bit fragile. It uses sync.Once to manage concurrent lazy resolution, which is frustrating to debug in the presence of reentrancy issues. It also means the importer needs to deal with concurrency as well. These aren't issues for types2 though as cmd/compile only walks the type-checked AST sequentially. Finally, it looks like some of the details of lazy type names are similar to the lazy "instance" stuff used for generics, so maybe there's opportunity for unifying them under a more general (but still internal) lazy type mechanism. I had originally intended for this CL to also update the types2 importer, but (1) it doesn't have access to the types2.Checker instance needed to call InstantiateLazy, and (2) it creates a new TypeName/TypeParam at each use rather than reusing them, which evidently works with types2.Instantiate but not types2.(*Checker).instantiate (i.e., InstantiateLazy). I spent a while trying to fix these issues, but kept running into more subtle issues. Instead, I've included my WIP "unified IR" CL as a followup CL that demonstrates these Lazy methods (see noder/reader2.go). Updates #46449. Change-Id: I4d1e8e649f6325a11790d25fd90c39fa07c8d41d Reviewed-on: https://go-review.googlesource.com/c/go/+/323569 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Trust: Matthew Dempsky <mdempsky@google.com> Trust: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/types2/lookup.go')
-rw-r--r--src/cmd/compile/internal/types2/lookup.go5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go
index eb2b17dd4d..93ed620449 100644
--- a/src/cmd/compile/internal/types2/lookup.go
+++ b/src/cmd/compile/internal/types2/lookup.go
@@ -54,7 +54,7 @@ func (check *Checker) lookupFieldOrMethod(T Type, addressable bool, pkg *Package
// pointer type but discard the result if it is a method since we would
// not have found it for T (see also issue 8590).
if t := asNamed(T); t != nil {
- if p, _ := t.underlying.(*Pointer); p != nil {
+ if p, _ := t.Underlying().(*Pointer); p != nil {
obj, index, indirect = check.rawLookupFieldOrMethod(p, false, pkg, name)
if _, ok := obj.(*Func); ok {
return nil, nil, false
@@ -126,6 +126,7 @@ func (check *Checker) rawLookupFieldOrMethod(T Type, addressable bool, pkg *Pack
seen[named] = true
// look for a matching attached method
+ named.expand()
if i, m := lookupMethod(named.methods, pkg, name); m != nil {
// potential match
// caution: method may not have a proper signature yet
@@ -400,7 +401,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
// In order to compare the signatures, substitute the receiver
// type parameters of ftyp with V's instantiation type arguments.
// This lazily instantiates the signature of method f.
- if Vn != nil && len(Vn.tparams) > 0 {
+ if Vn != nil && len(Vn.TParams()) > 0 {
// Be careful: The number of type arguments may not match
// the number of receiver parameters. If so, an error was
// reported earlier but the length discrepancy is still