diff options
| author | Robert Griesemer <gri@golang.org> | 2017-11-20 21:54:41 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2017-11-27 16:47:51 +0000 |
| commit | 3c7e491ba82e713129665fcff98a2fd796f968aa (patch) | |
| tree | 12600d2a7ed1fb0d364bc4f25b2b5907de4a319d /src | |
| parent | 4aac23cc512f661657e0785544dfdd19b6b517b0 (diff) | |
| download | go-3c7e491ba82e713129665fcff98a2fd796f968aa.tar.xz | |
go/types: add debugging code to detect use of incomplete interfaces
The comment for phase 2 of checker.interfaceType (typexpr.go:517)
requires that embedded interfaces be complete for correctness of
the algorithm.
Yet, the very next comment (typexpr.go:530) states that underlying
embedded interfaces may in fact be incomplete.
This is in fact the case and the underlying bug in issue #18395.
This change makes sure that new interface types are marked complete
when finished (per the implicit definition in Interface.Complete,
type.go:302). It also adds a check, enabled in debug mode only, to
detect the use of incomplete embedded interfaces during construction
of a new interface. In debug mode, this check fails for the testcase
in the issue (and several others).
This change has no noticeable impact with debug mode disabled.
For #18395.
Change-Id: Ibb81e47257651282fb3755a80a36ab5d392e636d
Reviewed-on: https://go-review.googlesource.com/78955
Reviewed-by: Alan Donovan <adonovan@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/go/types/typexpr.go | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 2272ac0645..d48dcbffc3 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -540,6 +540,10 @@ func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, d } iface.embeddeds = append(iface.embeddeds, named) // collect embedded methods + if debug && embed.allMethods == nil { + check.dump("%s: incomplete embedded interface %s", pos, named) + unreachable() + } for _, m := range embed.allMethods { if check.declareInSet(&mset, pos, m) { iface.allMethods = append(iface.allMethods, m) @@ -579,7 +583,11 @@ func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, d // claim source order in the future. Revisit. sort.Sort(byUniqueTypeName(iface.embeddeds)) - sort.Sort(byUniqueMethodName(iface.allMethods)) + if iface.allMethods == nil { + iface.allMethods = make([]*Func, 0) // mark interface as complete + } else { + sort.Sort(byUniqueMethodName(iface.allMethods)) + } } // byUniqueTypeName named type lists can be sorted by their unique type names. |
