mirror of
https://github.com/golang/go
synced 2024-11-18 18:04:46 -07:00
go.tools/go/types: catch cycles in function declarations
Fixes golang/go#5217. R=adonovan CC=golang-dev https://golang.org/cl/10402044
This commit is contained in:
parent
86c0ff156c
commit
7517d8bae3
@ -347,7 +347,7 @@ func (check *checker) declareObject(obj Object, cycleOk bool) {
|
||||
case *TypeName:
|
||||
check.declareType(obj, d.typ, cycleOk)
|
||||
case *Func:
|
||||
check.declareFunc(obj, cycleOk)
|
||||
check.declareFunc(obj)
|
||||
default:
|
||||
unreachable()
|
||||
}
|
||||
@ -525,12 +525,13 @@ func (check *checker) declareType(obj *TypeName, typ ast.Expr, cycleOk bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (check *checker) declareFunc(obj *Func, cycleOk bool) {
|
||||
func (check *checker) declareFunc(obj *Func) {
|
||||
fdecl := obj.decl
|
||||
// methods are typechecked when their receivers are typechecked
|
||||
// TODO(gri) there is no reason to make this a special case: receivers are simply parameters
|
||||
if fdecl.Recv == nil {
|
||||
sig := check.typ(fdecl.Type, cycleOk).(*Signature)
|
||||
obj.typ = Typ[Invalid] // guard against cycles
|
||||
sig := check.typ(fdecl.Type, false).(*Signature)
|
||||
if obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
|
||||
check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
|
||||
// ok to continue
|
||||
|
12
go/types/testdata/decls0.src
vendored
12
go/types/testdata/decls0.src
vendored
@ -186,6 +186,18 @@ type (
|
||||
Last int
|
||||
)
|
||||
|
||||
// cycles in function/method declarations
|
||||
// (test cases for issue 5217 and variants)
|
||||
func f1(x f1 /* ERROR "not a type" */ ) {}
|
||||
func f2(x *f2 /* ERROR "cannot indirect" */ ) {}
|
||||
func f3() (x f3 /* ERROR "not a type" */ ) { return }
|
||||
func f4() (x *f4 /* ERROR "cannot indirect" */ ) { return }
|
||||
|
||||
func (S0) m1(x S0 /* ERROR "field or method" */ .m1) {}
|
||||
func (S0) m2(x *S0 /* ERROR "field or method" */ .m2) {}
|
||||
func (S0) m3() (x S0 /* ERROR "field or method" */ .m3) { return }
|
||||
func (S0) m4() (x *S0 /* ERROR "field or method" */ .m4) { return }
|
||||
|
||||
// interfaces may have blank methods
|
||||
type BlankI interface {
|
||||
_()
|
||||
|
Loading…
Reference in New Issue
Block a user