]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: eliminate methodList in favor of just using Named.mu
authorRobert Findley <rfindley@google.com>
Sat, 7 May 2022 22:59:14 +0000 (18:59 -0400)
committerRobert Findley <rfindley@google.com>
Mon, 6 Jun 2022 15:18:33 +0000 (15:18 +0000)
In order to clean up context after fully expanding a type (in subsequent
CLs), we must use a common mutex. Eliminate the lazy methodList type,
which keeps a sync.Once per method, in favor of Named.mu.

Updates #52728

Change-Id: I2d13319276df1330ee53046ef1823b0167a258d8
Reviewed-on: https://go-review.googlesource.com/c/go/+/404883
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/methodlist.go [deleted file]
src/cmd/compile/internal/types2/methodlist_test.go [deleted file]
src/cmd/compile/internal/types2/named.go
src/cmd/compile/internal/types2/sizeof_test.go
src/go/types/decl.go
src/go/types/methodlist.go [deleted file]
src/go/types/methodlist_test.go [deleted file]
src/go/types/named.go
src/go/types/sizeof_test.go

index 008d3698b7e94aad8af1af14f03a7afbbcbd070a..a5d29765c65d19bcfdc51c656e67871656cd2ed1 100644 (file)
@@ -646,8 +646,8 @@ func (check *Checker) collectMethods(obj *TypeName) {
                // Checker.Files may be called multiple times; additional package files
                // may add methods to already type-checked types. Add pre-existing methods
                // so that we can detect redeclarations.
-               for i := 0; i < base.methods.Len(); i++ {
-                       m := base.methods.At(i, nil)
+               for i := 0; i < base.NumMethods(); i++ {
+                       m := base.Method(i)
                        assert(m.name != "_")
                        assert(mset.insert(m) == nil)
                }
@@ -679,8 +679,8 @@ func (check *Checker) collectMethods(obj *TypeName) {
 func (check *Checker) checkFieldUniqueness(base *Named) {
        if t, _ := base.under().(*Struct); t != nil {
                var mset objset
-               for i := 0; i < base.methods.Len(); i++ {
-                       m := base.methods.At(i, nil)
+               for i := 0; i < base.NumMethods(); i++ {
+                       m := base.Method(i)
                        assert(m.name != "_")
                        assert(mset.insert(m) == nil)
                }
diff --git a/src/cmd/compile/internal/types2/methodlist.go b/src/cmd/compile/internal/types2/methodlist.go
deleted file mode 100644 (file)
index cd6c06c..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package types2
-
-import "sync"
-
-// methodList holds a list of methods that may be lazily resolved by a provided
-// resolution method.
-type methodList struct {
-       methods []*Func
-
-       // guards synchronizes the instantiation of lazy methods. For lazy method
-       // lists, guards is non-nil and of the length passed to newLazyMethodList.
-       // For non-lazy method lists, guards is nil.
-       guards *[]sync.Once
-}
-
-// newMethodList creates a non-lazy method list holding the given methods.
-func newMethodList(methods []*Func) *methodList {
-       return &methodList{methods: methods}
-}
-
-// newLazyMethodList creates a lazy method list of the given length. Methods
-// may be resolved lazily for a given index by providing a resolver function.
-func newLazyMethodList(length int) *methodList {
-       guards := make([]sync.Once, length)
-       return &methodList{
-               methods: make([]*Func, length),
-               guards:  &guards,
-       }
-}
-
-// isLazy reports whether the receiver is a lazy method list.
-func (l *methodList) isLazy() bool {
-       return l != nil && l.guards != nil
-}
-
-// Add appends a method to the method list if not not already present. Add
-// panics if the receiver is lazy.
-func (l *methodList) Add(m *Func) {
-       assert(!l.isLazy())
-       if i, _ := lookupMethod(l.methods, m.pkg, m.name, false); i < 0 {
-               l.methods = append(l.methods, m)
-       }
-}
-
-// Lookup looks up the method identified by pkg and name in the receiver.
-// Lookup panics if the receiver is lazy. If foldCase is true, method names
-// are considered equal if they are equal with case folding.
-func (l *methodList) Lookup(pkg *Package, name string, foldCase bool) (int, *Func) {
-       assert(!l.isLazy())
-       if l == nil {
-               return -1, nil
-       }
-       return lookupMethod(l.methods, pkg, name, foldCase)
-}
-
-// Len returns the length of the method list.
-func (l *methodList) Len() int {
-       if l == nil {
-               return 0
-       }
-       return len(l.methods)
-}
-
-// At returns the i'th method of the method list. At panics if i is out of
-// bounds, or if the receiver is lazy and resolve is nil.
-func (l *methodList) At(i int, resolve func() *Func) *Func {
-       if !l.isLazy() {
-               return l.methods[i]
-       }
-       assert(resolve != nil)
-       (*l.guards)[i].Do(func() {
-               l.methods[i] = resolve()
-       })
-       return l.methods[i]
-}
diff --git a/src/cmd/compile/internal/types2/methodlist_test.go b/src/cmd/compile/internal/types2/methodlist_test.go
deleted file mode 100644 (file)
index 7a183ac..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package types2
-
-import (
-       "testing"
-)
-
-func TestLazyMethodList(t *testing.T) {
-       l := newLazyMethodList(2)
-
-       if got := l.Len(); got != 2 {
-               t.Fatalf("Len() = %d, want 2", got)
-       }
-
-       f0 := NewFunc(nopos, nil, "f0", nil)
-       f1 := NewFunc(nopos, nil, "f1", nil)
-
-       // Verify that methodList.At is idempotent, by calling it repeatedly with a
-       // resolve func that returns different pointer values (f0 or f1).
-       steps := []struct {
-               index   int
-               resolve *Func // the *Func returned by the resolver
-               want    *Func // the actual *Func returned by methodList.At
-       }{
-               {0, f0, f0},
-               {0, f1, f0},
-               {1, f1, f1},
-               {1, f0, f1},
-       }
-
-       for i, step := range steps {
-               got := l.At(step.index, func() *Func { return step.resolve })
-               if got != step.want {
-                       t.Errorf("step %d: At(%d, ...) = %s, want %s", i, step.index, got.Name(), step.want.Name())
-               }
-       }
-}
index 0a2b2aa6b10d6ed351b2ec9596280f1e674e1253..77655bc821b0a16eaae7c2249f990f41c3814a43 100644 (file)
@@ -96,14 +96,16 @@ type Named struct {
        underlying Type           // possibly a *Named during setup; never a *Named once set up completely
        tparams    *TypeParamList // type parameters, or nil
 
-       // methods declared for this type (not the method set of this type).
+       // methods declared for this type (not the method set of this type)
        // Signatures are type-checked lazily.
        // For non-instantiated types, this is a fully populated list of methods. For
-       // instantiated types, this is a 'lazy' list, and methods are individually
-       // expanded when they are first accessed.
-       methods *methodList
+       // instantiated types, methods are individually expanded when they are first
+       // accessed.
+       methods []*Func
+       // number of expanded methods (only valid for instantiated named types)
+       expandedMethods int // expandedMethods <= len(orig.methods)
 
-       // loader may be provided to lazily load type parameters, underlying, and methods.
+       // loader may be provided to lazily load type parameters, underlying type, and methods.
        loader func(*Named) (tparams []*TypeParam, underlying Type, methods []*Func)
 }
 
@@ -112,7 +114,8 @@ type namedState uint32
 
 const (
        unresolved namedState = iota // tparams, underlying type and methods might be unavailable
-       resolved
+       resolved                     // resolve has run; methods might be incomplete (for instances)
+       complete                     // all data is known
 )
 
 // NewNamed returns a new named type for the given type name, underlying type, and associated methods.
@@ -122,7 +125,7 @@ func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
        if _, ok := underlying.(*Named); ok {
                panic("underlying type must not be *Named")
        }
-       return (*Checker)(nil).newNamed(obj, nil, underlying, newMethodList(methods))
+       return (*Checker)(nil).newNamed(obj, nil, underlying, methods)
 }
 
 // resolve resolves the type parameters, methods, and underlying type of n.
@@ -156,8 +159,12 @@ func (n *Named) resolve(ctxt *Context) *Named {
                n.tparams = n.orig.tparams
                n.underlying = underlying
                n.fromRHS = n.orig.fromRHS // for cycle detection
-               n.methods = newLazyMethodList(n.orig.methods.Len())
-               n.setState(resolved)
+
+               if len(n.orig.methods) == 0 {
+                       n.setState(complete)
+               } else {
+                       n.setState(resolved)
+               }
                return n
        }
 
@@ -170,17 +177,18 @@ func (n *Named) resolve(ctxt *Context) *Named {
        // also make the API more future-proof towards further extensions.
        if n.loader != nil {
                assert(n.underlying == nil)
+               assert(n.TypeArgs().Len() == 0) // instances are created by instantiation, in which case n.loader is nil
 
                tparams, underlying, methods := n.loader(n)
 
                n.tparams = bindTParams(tparams)
                n.underlying = underlying
                n.fromRHS = underlying // for cycle detection
-               n.methods = newMethodList(methods)
+               n.methods = methods
                n.loader = nil
        }
 
-       n.setState(resolved)
+       n.setState(complete)
        return n
 }
 
@@ -196,7 +204,7 @@ func (n *Named) setState(state namedState) {
 }
 
 // newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
-func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, methods *methodList) *Named {
+func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, methods []*Func) *Named {
        typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, methods: methods}
        if typ.orig == nil {
                typ.orig = typ
@@ -262,14 +270,38 @@ func (t *Named) TypeArgs() *TypeList { return t.targs }
 // For an ordinary or instantiated type t, the receiver base type of these
 // methods will be the named type t. For an uninstantiated generic type t, each
 // method receiver will be instantiated with its receiver type parameters.
-func (t *Named) NumMethods() int { return t.resolve(nil).methods.Len() }
+func (t *Named) NumMethods() int { return len(t.orig.resolve(nil).methods) }
 
 // Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
 func (t *Named) Method(i int) *Func {
        t.resolve(nil)
-       return t.methods.At(i, func() *Func {
-               return t.expandMethod(i)
-       })
+
+       if t.state() >= complete {
+               return t.methods[i]
+       }
+
+       assert(t.TypeArgs().Len() > 0) // only instances should have incomplete methods
+
+       t.mu.Lock()
+       defer t.mu.Unlock()
+
+       if len(t.methods) != len(t.orig.methods) {
+               assert(len(t.methods) == 0)
+               t.methods = make([]*Func, len(t.orig.methods))
+       }
+
+       if t.methods[i] == nil {
+               t.methods[i] = t.expandMethod(i)
+               t.expandedMethods++
+
+               // Check if we've created all methods at this point. If we have, mark the
+               // type as fully expanded.
+               if t.expandedMethods == len(t.orig.methods) {
+                       t.setState(complete)
+               }
+       }
+
+       return t.methods[i]
 }
 
 // expandMethod substitutes type arguments in the i'th method for an
@@ -351,10 +383,9 @@ func (t *Named) SetUnderlying(underlying Type) {
 func (t *Named) AddMethod(m *Func) {
        assert(t.targs.Len() == 0)
        t.resolve(nil)
-       if t.methods == nil {
-               t.methods = newMethodList(nil)
+       if i, _ := lookupMethod(t.methods, m.pkg, m.name, false); i < 0 {
+               t.methods = append(t.methods, m)
        }
-       t.methods.Add(m)
 }
 
 func (t *Named) Underlying() Type { return t.resolve(nil).underlying }
@@ -462,7 +493,7 @@ func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Fu
        // If n is an instance, we may not have yet instantiated all of its methods.
        // Look up the method index in orig, and only instantiate method at the
        // matching index (if any).
-       i, _ := n.orig.methods.Lookup(pkg, name, foldCase)
+       i, _ := lookupMethod(n.orig.methods, pkg, name, foldCase)
        if i < 0 {
                return -1, nil
        }
index 7ab7abb317ed4f2e29768bef31a764588406ae29..3f0bf8f3c50f077872b208f538ab22e5b5a4cd95 100644 (file)
@@ -31,7 +31,7 @@ func TestSizeof(t *testing.T) {
                {Interface{}, 40, 80},
                {Map{}, 16, 32},
                {Chan{}, 12, 24},
-               {Named{}, 56, 104},
+               {Named{}, 68, 128},
                {TypeParam{}, 28, 48},
                {term{}, 12, 24},
 
index 61c9696948fd61c6e278ae1ea0b432ac5d011b75..b5ff1214dd548158311dad47ba230e1ec6a83e0f 100644 (file)
@@ -722,8 +722,8 @@ func (check *Checker) collectMethods(obj *TypeName) {
                // Checker.Files may be called multiple times; additional package files
                // may add methods to already type-checked types. Add pre-existing methods
                // so that we can detect redeclarations.
-               for i := 0; i < base.methods.Len(); i++ {
-                       m := base.methods.At(i, nil)
+               for i := 0; i < base.NumMethods(); i++ {
+                       m := base.Method(i)
                        assert(m.name != "_")
                        assert(mset.insert(m) == nil)
                }
@@ -749,8 +749,8 @@ func (check *Checker) collectMethods(obj *TypeName) {
 func (check *Checker) checkFieldUniqueness(base *Named) {
        if t, _ := base.under().(*Struct); t != nil {
                var mset objset
-               for i := 0; i < base.methods.Len(); i++ {
-                       m := base.methods.At(i, nil)
+               for i := 0; i < base.NumMethods(); i++ {
+                       m := base.Method(i)
                        assert(m.name != "_")
                        assert(mset.insert(m) == nil)
                }
diff --git a/src/go/types/methodlist.go b/src/go/types/methodlist.go
deleted file mode 100644 (file)
index afe9190..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package types
-
-import "sync"
-
-// methodList holds a list of methods that may be lazily resolved by a provided
-// resolution method.
-type methodList struct {
-       methods []*Func
-
-       // guards synchronizes the instantiation of lazy methods. For lazy method
-       // lists, guards is non-nil and of the length passed to newLazyMethodList.
-       // For non-lazy method lists, guards is nil.
-       guards *[]sync.Once
-}
-
-// newMethodList creates a non-lazy method list holding the given methods.
-func newMethodList(methods []*Func) *methodList {
-       return &methodList{methods: methods}
-}
-
-// newLazyMethodList creates a lazy method list of the given length. Methods
-// may be resolved lazily for a given index by providing a resolver function.
-func newLazyMethodList(length int) *methodList {
-       guards := make([]sync.Once, length)
-       return &methodList{
-               methods: make([]*Func, length),
-               guards:  &guards,
-       }
-}
-
-// isLazy reports whether the receiver is a lazy method list.
-func (l *methodList) isLazy() bool {
-       return l != nil && l.guards != nil
-}
-
-// Add appends a method to the method list if not not already present. Add
-// panics if the receiver is lazy.
-func (l *methodList) Add(m *Func) {
-       assert(!l.isLazy())
-       if i, _ := lookupMethod(l.methods, m.pkg, m.name, false); i < 0 {
-               l.methods = append(l.methods, m)
-       }
-}
-
-// Lookup looks up the method identified by pkg and name in the receiver.
-// Lookup panics if the receiver is lazy. If foldCase is true, method names
-// are considered equal if they are equal with case folding.
-func (l *methodList) Lookup(pkg *Package, name string, foldCase bool) (int, *Func) {
-       assert(!l.isLazy())
-       if l == nil {
-               return -1, nil
-       }
-       return lookupMethod(l.methods, pkg, name, foldCase)
-}
-
-// Len returns the length of the method list.
-func (l *methodList) Len() int {
-       if l == nil {
-               return 0
-       }
-       return len(l.methods)
-}
-
-// At returns the i'th method of the method list. At panics if i is out of
-// bounds, or if the receiver is lazy and resolve is nil.
-func (l *methodList) At(i int, resolve func() *Func) *Func {
-       if !l.isLazy() {
-               return l.methods[i]
-       }
-       assert(resolve != nil)
-       (*l.guards)[i].Do(func() {
-               l.methods[i] = resolve()
-       })
-       return l.methods[i]
-}
diff --git a/src/go/types/methodlist_test.go b/src/go/types/methodlist_test.go
deleted file mode 100644 (file)
index e628bce..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package types
-
-import (
-       "go/token"
-       "testing"
-)
-
-func TestLazyMethodList(t *testing.T) {
-       l := newLazyMethodList(2)
-
-       if got := l.Len(); got != 2 {
-               t.Fatalf("Len() = %d, want 2", got)
-       }
-
-       f0 := NewFunc(token.NoPos, nil, "f0", nil)
-       f1 := NewFunc(token.NoPos, nil, "f1", nil)
-
-       // Verify that methodList.At is idempotent, by calling it repeatedly with a
-       // resolve func that returns different pointer values (f0 or f1).
-       steps := []struct {
-               index   int
-               resolve *Func // the *Func returned by the resolver
-               want    *Func // the actual *Func returned by methodList.At
-       }{
-               {0, f0, f0},
-               {0, f1, f0},
-               {1, f1, f1},
-               {1, f0, f1},
-       }
-
-       for i, step := range steps {
-               got := l.At(step.index, func() *Func { return step.resolve })
-               if got != step.want {
-                       t.Errorf("step %d: At(%d, ...) = %s, want %s", i, step.index, got.Name(), step.want.Name())
-               }
-       }
-}
index bfb4a11da72ed0499d17ff0f280483f2cc5a22ad..f1c5dd4f81963c14b391471e5546656b753e6613 100644 (file)
@@ -96,14 +96,16 @@ type Named struct {
        underlying Type           // possibly a *Named during setup; never a *Named once set up completely
        tparams    *TypeParamList // type parameters, or nil
 
-       // methods declared for this type (not the method set of this type).
+       // methods declared for this type (not the method set of this type)
        // Signatures are type-checked lazily.
        // For non-instantiated types, this is a fully populated list of methods. For
-       // instantiated types, this is a 'lazy' list, and methods are individually
-       // expanded when they are first accessed.
-       methods *methodList
+       // instantiated types, methods are individually expanded when they are first
+       // accessed.
+       methods []*Func
+       // number of expanded methods (only valid for instantiated named types)
+       expandedMethods int // expandedMethods <= len(orig.methods)
 
-       // loader may be provided to lazily load type parameters, underlying, and methods.
+       // loader may be provided to lazily load type parameters, underlying type, and methods.
        loader func(*Named) (tparams []*TypeParam, underlying Type, methods []*Func)
 }
 
@@ -112,7 +114,8 @@ type namedState uint32
 
 const (
        unresolved namedState = iota // tparams, underlying type and methods might be unavailable
-       resolved
+       resolved                     // resolve has run; methods might be incomplete (for instances)
+       complete                     // all data is known
 )
 
 // NewNamed returns a new named type for the given type name, underlying type, and associated methods.
@@ -122,7 +125,7 @@ func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
        if _, ok := underlying.(*Named); ok {
                panic("underlying type must not be *Named")
        }
-       return (*Checker)(nil).newNamed(obj, nil, underlying, newMethodList(methods))
+       return (*Checker)(nil).newNamed(obj, nil, underlying, methods)
 }
 
 // resolve resolves the type parameters, methods, and underlying type of n.
@@ -156,8 +159,12 @@ func (n *Named) resolve(ctxt *Context) *Named {
                n.tparams = n.orig.tparams
                n.underlying = underlying
                n.fromRHS = n.orig.fromRHS // for cycle detection
-               n.methods = newLazyMethodList(n.orig.methods.Len())
-               n.setState(resolved)
+
+               if len(n.orig.methods) == 0 {
+                       n.setState(complete)
+               } else {
+                       n.setState(resolved)
+               }
                return n
        }
 
@@ -170,17 +177,18 @@ func (n *Named) resolve(ctxt *Context) *Named {
        // also make the API more future-proof towards further extensions.
        if n.loader != nil {
                assert(n.underlying == nil)
+               assert(n.TypeArgs().Len() == 0) // instances are created by instantiation, in which case n.loader is nil
 
                tparams, underlying, methods := n.loader(n)
 
                n.tparams = bindTParams(tparams)
                n.underlying = underlying
                n.fromRHS = underlying // for cycle detection
-               n.methods = newMethodList(methods)
+               n.methods = methods
                n.loader = nil
        }
 
-       n.setState(resolved)
+       n.setState(complete)
        return n
 }
 
@@ -196,7 +204,7 @@ func (n *Named) setState(state namedState) {
 }
 
 // newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
-func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, methods *methodList) *Named {
+func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, methods []*Func) *Named {
        typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, methods: methods}
        if typ.orig == nil {
                typ.orig = typ
@@ -264,14 +272,38 @@ func (t *Named) TypeArgs() *TypeList { return t.targs }
 // For an ordinary or instantiated type t, the receiver base type of these
 // methods will be the named type t. For an uninstantiated generic type t, each
 // method receiver will be instantiated with its receiver type parameters.
-func (t *Named) NumMethods() int { return t.resolve(nil).methods.Len() }
+func (t *Named) NumMethods() int { return len(t.orig.resolve(nil).methods) }
 
 // Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
 func (t *Named) Method(i int) *Func {
        t.resolve(nil)
-       return t.methods.At(i, func() *Func {
-               return t.expandMethod(i)
-       })
+
+       if t.state() >= complete {
+               return t.methods[i]
+       }
+
+       assert(t.TypeArgs().Len() > 0) // only instances should have incomplete methods
+
+       t.mu.Lock()
+       defer t.mu.Unlock()
+
+       if len(t.methods) != len(t.orig.methods) {
+               assert(len(t.methods) == 0)
+               t.methods = make([]*Func, len(t.orig.methods))
+       }
+
+       if t.methods[i] == nil {
+               t.methods[i] = t.expandMethod(i)
+               t.expandedMethods++
+
+               // Check if we've created all methods at this point. If we have, mark the
+               // type as fully expanded.
+               if t.expandedMethods == len(t.orig.methods) {
+                       t.setState(complete)
+               }
+       }
+
+       return t.methods[i]
 }
 
 // expandMethod substitutes type arguments in the i'th method for an
@@ -353,10 +385,9 @@ func (t *Named) SetUnderlying(underlying Type) {
 func (t *Named) AddMethod(m *Func) {
        assert(t.targs.Len() == 0)
        t.resolve(nil)
-       if t.methods == nil {
-               t.methods = newMethodList(nil)
+       if i, _ := lookupMethod(t.methods, m.pkg, m.name, false); i < 0 {
+               t.methods = append(t.methods, m)
        }
-       t.methods.Add(m)
 }
 
 func (t *Named) Underlying() Type { return t.resolve(nil).underlying }
@@ -464,7 +495,7 @@ func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Fu
        // If n is an instance, we may not have yet instantiated all of its methods.
        // Look up the method index in orig, and only instantiate method at the
        // matching index (if any).
-       i, _ := n.orig.methods.Lookup(pkg, name, foldCase)
+       i, _ := lookupMethod(n.orig.methods, pkg, name, foldCase)
        if i < 0 {
                return -1, nil
        }
index 3428eb919110c247555c39d871720c14b9826f09..66a69521d2894a9348b57ba33e48eed4f7002de2 100644 (file)
@@ -30,7 +30,7 @@ func TestSizeof(t *testing.T) {
                {Interface{}, 40, 80},
                {Map{}, 16, 32},
                {Chan{}, 12, 24},
-               {Named{}, 56, 104},
+               {Named{}, 68, 128},
                {TypeParam{}, 28, 48},
                {term{}, 12, 24},