]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/go/types/interface.go
go/types, types2: introduce _Alias type node
[gostls13.git] / src / go / types / interface.go
index 2fb8e40119b569da0faf012da6ad6b4ec83713dd..01bbb08e0efe5573f205756b2c1d450913b4d066 100644 (file)
@@ -26,7 +26,7 @@ type Interface struct {
 }
 
 // typeSet returns the type set for interface t.
-func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, token.NoPos, t) }
+func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, nopos, t) }
 
 // emptyInterface represents the empty (completed) interface
 var emptyInterface = Interface{complete: true, tset: &topTypeSet}
@@ -94,17 +94,17 @@ func (t *Interface) MarkImplicit() {
 func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
 
 // ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
-// The methods are ordered by their unique Id.
+// The methods are ordered by their unique [Id].
 func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
 
 // NumEmbeddeds returns the number of embedded types in interface t.
 func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
 
-// Embedded returns the i'th embedded defined (*Named) type of interface t for 0 <= i < t.NumEmbeddeds().
+// Embedded returns the i'th embedded defined (*[Named]) type of interface t for 0 <= i < t.NumEmbeddeds().
 // The result is nil if the i'th embedded type is not a defined type.
 //
-// Deprecated: Use EmbeddedType which is not restricted to defined (*Named) types.
-func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname }
+// Deprecated: Use [Interface.EmbeddedType] which is not restricted to defined (*[Named]) types.
+func (t *Interface) Embedded(i int) *Named { return asNamed(t.embeddeds[i]) }
 
 // EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
 func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
@@ -130,7 +130,7 @@ func (t *Interface) IsMethodSet() bool { return t.typeSet().IsMethodSet() }
 func (t *Interface) IsImplicit() bool { return t.implicit }
 
 // Complete computes the interface's type set. It must be called by users of
-// NewInterfaceType and NewInterface after the interface's embedded types are
+// [NewInterfaceType] and [NewInterface] after the interface's embedded types are
 // fully defined and before using the interface type in any way other than to
 // form other types. The interface must not contain duplicate methods or a
 // panic occurs. Complete returns the receiver.
@@ -151,11 +151,12 @@ func (t *Interface) String() string   { return TypeString(t, nil) }
 // Implementation
 
 func (t *Interface) cleanup() {
+       t.typeSet() // any interface that escapes type checking must be safe for concurrent use
        t.check = nil
        t.embedPos = nil
 }
 
-func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
+func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *TypeName) {
        addEmbedded := func(pos token.Pos, typ Type) {
                ityp.embeddeds = append(ityp.embeddeds, typ)
                if ityp.embedPos == nil {
@@ -181,27 +182,27 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
                typ := check.typ(f.Type)
                sig, _ := typ.(*Signature)
                if sig == nil {
-                       if typ != Typ[Invalid] {
-                               check.errorf(f.Type, InvalidSyntaxTree, invalidAST+"%s is not a method signature", typ)
+                       if isValid(typ) {
+                               check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ)
                        }
                        continue // ignore
                }
 
-               // Always type-check method type parameters but complain if they are not enabled.
-               // (This extra check is needed here because interface method signatures don't have
-               // a receiver specification.)
+               // The go/parser doesn't accept method type parameters but an ast.FuncType may have them.
                if sig.tparams != nil {
                        var at positioner = f.Type
                        if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil {
                                at = ftyp.TypeParams
                        }
-                       check.error(at, InvalidMethodTypeParams, "methods cannot have type parameters")
+                       check.error(at, InvalidSyntaxTree, "methods cannot have type parameters")
                }
 
                // use named receiver type if available (for better error messages)
                var recvTyp Type = ityp
                if def != nil {
-                       recvTyp = def
+                       if named := asNamed(def.typ); named != nil {
+                               recvTyp = named
+                       }
                }
                sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp)