Skip to content

Commit e2b5e60

Browse files
committed
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/97535 Reviewed-by: Alan Donovan <[email protected]>
1 parent 91a05b9 commit e2b5e60

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/go/types/testdata/issues.src

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,14 @@ func issue24026() {
229229
}
230230

231231
func f(int) {} // for issue24026
232+
233+
// Test that we don't report a "missing return statement" error
234+
// (due to incorrect context when type-checking interfaces).
235+
func issue24140(x interface{}) int {
236+
switch x.(type) {
237+
case interface{}:
238+
return 0
239+
default:
240+
panic(0)
241+
}
242+
}

src/go/types/typexpr.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,17 +480,28 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
480480

481481
// collect embedded interfaces
482482
// Only needed for printing and API. Delay collection
483-
// to end of type-checking when all types are complete.
483+
// to end of type-checking (for package-global interfaces)
484+
// when all types are complete. Local interfaces are handled
485+
// after each statement (as each statement processes delayed
486+
// functions).
484487
interfaceContext := check.context // capture for use in closure below
485488
check.later(func() {
486-
check.context = interfaceContext
487489
if trace {
488490
check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %s", iface)
489491
check.indent++
490492
defer func() {
491493
check.indent--
492494
}()
493495
}
496+
497+
// The context must be restored since for local interfaces
498+
// delayed functions are processed after each statement
499+
// (was issue #24140).
500+
defer func(ctxt context) {
501+
check.context = ctxt
502+
}(check.context)
503+
check.context = interfaceContext
504+
494505
for _, f := range iface.Methods.List {
495506
if len(f.Names) == 0 {
496507
typ := check.typ(f.Type)

0 commit comments

Comments
 (0)