1
0
mirror of https://github.com/golang/go synced 2024-11-22 20:40:03 -07:00

go/types: check if the interface is already complete in Complete

Once Interfaces have been completed they must never be written again,
as they may be used concurrently.

Avoid writing Interface.complete unnecessarily in Complete. Also, update
documentation to reflect that Complete must be called before the
Interface may be considered safe for concurrent use.

For #47726

Change-Id: Ic9fd1395ab0dd6d3499f7a698dadf315abcddab8
Reviewed-on: https://go-review.googlesource.com/c/go/+/342749
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>
This commit is contained in:
Robert Findley 2021-08-16 20:13:25 -04:00
parent 91a935ea0f
commit 29ec74fb82

View File

@ -43,9 +43,12 @@ func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
return NewInterfaceType(methods, tnames) return NewInterfaceType(methods, tnames)
} }
// NewInterfaceType returns a new interface for the given methods and embedded types. // NewInterfaceType returns a new interface for the given methods and embedded
// NewInterfaceType takes ownership of the provided methods and may modify their types // types. NewInterfaceType takes ownership of the provided methods and may
// by setting missing receivers. // modify their types by setting missing receivers.
//
// To avoid race conditions, the interface's type set should be computed before
// concurrent use of the interface, by explicitly calling Complete.
func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface { func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
if len(methods) == 0 && len(embeddeds) == 0 { if len(methods) == 0 && len(embeddeds) == 0 {
return &emptyInterface return &emptyInterface
@ -110,16 +113,12 @@ func (t *Interface) IsConstraint() bool { return !t.typeSet().IsMethodSet() }
// form other types. The interface must not contain duplicate methods or a // form other types. The interface must not contain duplicate methods or a
// panic occurs. Complete returns the receiver. // panic occurs. Complete returns the receiver.
// //
// Deprecated: Type sets are now computed lazily, on demand; this function // Interface types that have been completed are safe for concurrent use.
// is only here for backward-compatibility. It does not have to
// be called explicitly anymore.
func (t *Interface) Complete() *Interface { func (t *Interface) Complete() *Interface {
// Some tests are still depending on the state change if !t.complete {
// (string representation of an Interface not containing an t.complete = true
// /* incomplete */ marker) caused by the explicit Complete }
// call, so we compute the type set eagerly here. t.typeSet() // checks if t.tset is already set
t.complete = true
t.typeSet()
return t return t
} }