mirror of
https://github.com/golang/go
synced 2024-11-27 00:31:23 -07:00
go/types: use correct (file) scopes when computing interface method sets
This was already partially fixed by commit 99843e22e8
(https://go-review.googlesource.com/c/go/+/96376); but
we missed a couple of places where we also need to
propagate the scope.
Fixes #25008.
Change-Id: I041fa74d1f6d3b5a8edb922efa126ff1dacd7900
Reviewed-on: https://go-review.googlesource.com/109139
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
f2df0ec7dd
commit
73becbf9e2
@ -90,6 +90,7 @@ var tests = [][]string{
|
||||
{"testdata/labels.src"},
|
||||
{"testdata/issues.src"},
|
||||
{"testdata/blank.src"},
|
||||
{"testdata/issue25008b.src", "testdata/issue25008a.src"}, // order (b before a) is crucial!
|
||||
}
|
||||
|
||||
var fset = token.NewFileSet()
|
||||
|
@ -221,9 +221,9 @@ func (check *Checker) infoFromTypeLit(scope *Scope, iface *ast.InterfaceType, tn
|
||||
var e *ifaceInfo
|
||||
switch ename := f.Type.(type) {
|
||||
case *ast.Ident:
|
||||
e = check.infoFromTypeName(ename, path)
|
||||
e = check.infoFromTypeName(scope, ename, path)
|
||||
case *ast.SelectorExpr:
|
||||
e = check.infoFromQualifiedTypeName(ename)
|
||||
e = check.infoFromQualifiedTypeName(scope, ename)
|
||||
default:
|
||||
// The parser makes sure we only see one of the above.
|
||||
// Constructed ASTs may contain other (invalid) nodes;
|
||||
@ -262,7 +262,7 @@ func (check *Checker) infoFromTypeLit(scope *Scope, iface *ast.InterfaceType, tn
|
||||
// which must denote a type whose underlying type is an interface.
|
||||
// The same result qualifications apply as for infoFromTypeLit.
|
||||
// infoFromTypeName should only be called from infoFromTypeLit.
|
||||
func (check *Checker) infoFromTypeName(name *ast.Ident, path []*TypeName) *ifaceInfo {
|
||||
func (check *Checker) infoFromTypeName(scope *Scope, name *ast.Ident, path []*TypeName) *ifaceInfo {
|
||||
// A single call of infoFromTypeName handles a sequence of (possibly
|
||||
// recursive) type declarations connected via unqualified type names.
|
||||
// Each type declaration leading to another typename causes a "tail call"
|
||||
@ -291,7 +291,7 @@ func (check *Checker) infoFromTypeName(name *ast.Ident, path []*TypeName) *iface
|
||||
|
||||
typenameLoop:
|
||||
// name must be a type name denoting a type whose underlying type is an interface
|
||||
obj := check.lookup(name.Name)
|
||||
_, obj := scope.LookupParent(name.Name, check.pos)
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
@ -333,7 +333,7 @@ typenameLoop:
|
||||
goto typenameLoop
|
||||
case *ast.SelectorExpr:
|
||||
// type tname p.T
|
||||
return check.infoFromQualifiedTypeName(typ)
|
||||
return check.infoFromQualifiedTypeName(decl.file, typ)
|
||||
case *ast.InterfaceType:
|
||||
// type tname interface{...}
|
||||
return check.infoFromTypeLit(decl.file, typ, tname, path)
|
||||
@ -360,13 +360,13 @@ typenameLoop:
|
||||
}
|
||||
|
||||
// infoFromQualifiedTypeName computes the method set for the given qualified type name, or nil.
|
||||
func (check *Checker) infoFromQualifiedTypeName(qname *ast.SelectorExpr) *ifaceInfo {
|
||||
func (check *Checker) infoFromQualifiedTypeName(scope *Scope, qname *ast.SelectorExpr) *ifaceInfo {
|
||||
// see also Checker.selector
|
||||
name, _ := qname.X.(*ast.Ident)
|
||||
if name == nil {
|
||||
return nil
|
||||
}
|
||||
obj1 := check.lookup(name.Name)
|
||||
_, obj1 := scope.LookupParent(name.Name, check.pos)
|
||||
if obj1 == nil {
|
||||
return nil
|
||||
}
|
||||
|
15
src/go/types/testdata/issue25008a.src
vendored
Normal file
15
src/go/types/testdata/issue25008a.src
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
import "io"
|
||||
|
||||
type A interface {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func f(a A) {
|
||||
a.Read(nil)
|
||||
}
|
9
src/go/types/testdata/issue25008b.src
vendored
Normal file
9
src/go/types/testdata/issue25008b.src
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package p
|
||||
|
||||
type B interface {
|
||||
A
|
||||
}
|
Loading…
Reference in New Issue
Block a user