]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix incorrect context when type-checking interfaces
authorRobert Griesemer <gri@golang.org>
Tue, 27 Feb 2018 22:02:09 +0000 (14:02 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 28 Feb 2018 18:22:16 +0000 (18:22 +0000)
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/97535
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/testdata/issues.src
src/go/types/typexpr.go

index a346ab169aaa31c48eba847559d129df9c6a2026..4ecec508db5aee7be5c823a183b69a310fb80459 100644 (file)
@@ -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)
+        }
+}
index 1a82b613cb1a0e5cc42f2e869246e795c6559652..7ba5fd4389c1efd0f865338d34750b6644441032 100644 (file)
@@ -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)