From 117297cf42c5fd96fc1392e600c8d62d3bba7c5f Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 7 Feb 2020 16:01:01 -0800 Subject: [PATCH] go/types: simplify method set computation After fixing #37081 we don't need to explicitly keep track of field collisions in the method set computation anymore; we only need to know which field (names) exists at each embedding level. Simplify the code by removing the dedicated fieldSet data type in favor of a simple string set. Follow-up on https://golang.org/cl/218617; separate CL to make it easier to identify a problem with these two changes, should there be one. Updates #37081. Change-Id: I5c259c63c75a148a42d5c3e1e4860e1ffe5631bd Reviewed-on: https://go-review.googlesource.com/c/go/+/218618 Reviewed-by: Alan Donovan --- src/go/types/methodset.go | 40 +++++++++------------------------------ 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/src/go/types/methodset.go b/src/go/types/methodset.go index aacbb0f82a3..c34d732b7ac 100644 --- a/src/go/types/methodset.go +++ b/src/go/types/methodset.go @@ -99,8 +99,8 @@ func NewMethodSet(T Type) *MethodSet { for len(current) > 0 { var next []embeddedType // embedded types found at current depth - // field and method sets at current depth, allocated lazily - var fset fieldSet + // field and method sets at current depth, indexed by names (Id's), and allocated lazily + var fset map[string]bool // we only care about the field names var mset methodSet for _, e := range current { @@ -131,7 +131,10 @@ func NewMethodSet(T Type) *MethodSet { switch t := typ.(type) { case *Struct: for i, f := range t.fields { - fset = fset.add(f, e.multiples) + if fset == nil { + fset = make(map[string]bool) + } + fset[f.Id()] = true // Embedded fields are always of the form T or *T where // T is a type name. If typ appeared multiple times at @@ -156,7 +159,7 @@ func NewMethodSet(T Type) *MethodSet { for k, m := range mset { if _, found := base[k]; !found { // Fields collide with methods of the same name at this depth. - if _, found := fset[k]; found { + if fset[k] { m = nil // collision } if base == nil { @@ -166,9 +169,8 @@ func NewMethodSet(T Type) *MethodSet { } } - // Add all fields at this depth as collisions (since they will hide any - // method further down) to base if no entries with matching names exist - // already. + // Add all (remaining) fields at this depth as collisions (since they will + // hide any method further down) if no entries with matching names exist already. for k := range fset { if _, found := base[k]; !found { if base == nil { @@ -205,30 +207,6 @@ func NewMethodSet(T Type) *MethodSet { return &MethodSet{list} } -// A fieldSet is a set of fields and name collisions. -// A collision indicates that multiple fields with the -// same unique id appeared. -type fieldSet map[string]*Var // a nil entry indicates a name collision - -// Add adds field f to the field set s. -// If multiples is set, f appears multiple times -// and is treated as a collision. -func (s fieldSet) add(f *Var, multiples bool) fieldSet { - if s == nil { - s = make(fieldSet) - } - key := f.Id() - // if f is not in the set, add it - if !multiples { - if _, found := s[key]; !found { - s[key] = f - return s - } - } - s[key] = nil // collision - return s -} - // A methodSet is a set of methods and name collisions. // A collision indicates that multiple methods with the // same unique id, or a field with that id appeared.