diff --git a/src/go/types/testdata/issues.src b/src/go/types/testdata/issues.src index a346ab169aaa31c48eba847559d129df9c6a2026..4ecec508db5aee7be5c823a183b69a310fb80459 100644 --- a/src/go/types/testdata/issues.src +++ b/src/go/types/testdata/issues.src @@ -229,3 +229,14 @@ func 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) + } +} diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 1a82b613cb1a0e5cc42f2e869246e795c6559652..7ba5fd4389c1efd0f865338d34750b6644441032 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -480,10 +480,12 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d // collect embedded interfaces // 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 check.later(func() { - check.context = interfaceContext if trace { check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %s", iface) check.indent++ @@ -491,6 +493,15 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d 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 { if len(f.Names) == 0 { typ := check.typ(f.Type)