Commit e2b5e603 authored by Robert Griesemer's avatar Robert Griesemer

go/types: fix incorrect context when type-checking interfaces

Regression, introduced by https://go-review.googlesource.com/c/go/+/79575
which meant to be more conservative but ended up destroying an important
context.

Fixes #24140.

Change-Id: Id428dbb295ce9f11ab7cd54ec5ab51ef4291ac3f
Reviewed-on: https://go-review.googlesource.com/97535Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 91a05b92
...@@ -229,3 +229,14 @@ func issue24026() { ...@@ -229,3 +229,14 @@ func issue24026() {
} }
func f(int) {} // for issue24026 func f(int) {} // for issue24026
// Test that we don't report a "missing return statement" error
// (due to incorrect context when type-checking interfaces).
func issue24140(x interface{}) int {
switch x.(type) {
case interface{}:
return 0
default:
panic(0)
}
}
...@@ -480,10 +480,12 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d ...@@ -480,10 +480,12 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
// collect embedded interfaces // collect embedded interfaces
// Only needed for printing and API. Delay collection // Only needed for printing and API. Delay collection
// to end of type-checking when all types are complete. // to end of type-checking (for package-global interfaces)
// when all types are complete. Local interfaces are handled
// after each statement (as each statement processes delayed
// functions).
interfaceContext := check.context // capture for use in closure below interfaceContext := check.context // capture for use in closure below
check.later(func() { check.later(func() {
check.context = interfaceContext
if trace { if trace {
check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %s", iface) check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %s", iface)
check.indent++ check.indent++
...@@ -491,6 +493,15 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d ...@@ -491,6 +493,15 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
check.indent-- check.indent--
}() }()
} }
// The context must be restored since for local interfaces
// delayed functions are processed after each statement
// (was issue #24140).
defer func(ctxt context) {
check.context = ctxt
}(check.context)
check.context = interfaceContext
for _, f := range iface.Methods.List { for _, f := range iface.Methods.List {
if len(f.Names) == 0 { if len(f.Names) == 0 {
typ := check.typ(f.Type) typ := check.typ(f.Type)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment