Skip to content

Commit

Permalink
go/internal/gcimporter: call Interface.Complete in unified importer
Browse files Browse the repository at this point in the history
To support concurrent use of the go/types API, importers need to call
Interface.Complete on constructed interfaces before returning.

There's an issue that the interfaces may contain embedded defined
types, whose underlying type isn't known yet. This issue will
eventually go away once CL 424876 lands, but that CL needs to wait for
CL 424854 to re-land, which needs to wait for CL 421879 to land...

In the mean time, this CL implements the same solution used by the
indexed importer: maintaining a list of constructed interfaces, and
calling Interface.Complete on them after the SetUnderlying loop and
just before returning the imported package.

Updates golang#54653.

Change-Id: I0f42c915a4b7d28c628bbab7ac2eab2415c7858f
Reviewed-on: https://go-review.googlesource.com/c/go/+/425360
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
  • Loading branch information
mdempsky committed Aug 24, 2022
1 parent 8188bf6 commit bdf2db7
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/go/internal/gcimporter/ureader.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ type pkgReader struct {
laterFns []func()
// laterFors is used in case of 'type A B' to ensure that B is processed before A.
laterFors map[types.Type]int

// ifaces holds a list of constructed Interfaces, which need to have
// Complete called after importing is done.
ifaces []*types.Interface
}

// later adds a function to be invoked at the end of import reading.
Expand Down Expand Up @@ -86,6 +90,10 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st
fn()
}

for _, iface := range pr.ifaces {
iface.Complete()
}

pkg.MarkComplete()
return pkg
}
Expand Down Expand Up @@ -386,6 +394,16 @@ func (r *reader) interfaceType() *types.Interface {
if implicit {
iface.MarkImplicit()
}

// We need to call iface.Complete(), but if there are any embedded
// defined types, then we may not have set their underlying
// interface type yet. So we need to defer calling Complete until
// after we've called SetUnderlying everywhere.
//
// TODO(mdempsky): After CL 424876 lands, it should be safe to call
// iface.Complete() immediately.
r.p.ifaces = append(r.p.ifaces, iface)

return iface
}

Expand Down

0 comments on commit bdf2db7

Please sign in to comment.