mirror of https://github.com/golang/go.git
go/types: steps towards type-checking of methods with parameterized receivers
Change-Id: I80b4d4c248cb5e29933366322cca1d76c3ed5e23
This commit is contained in:
parent
0ffe62a473
commit
be88be6e7a
|
|
@ -659,10 +659,20 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
|
|||
// func declarations cannot use iota
|
||||
assert(check.iota == nil)
|
||||
|
||||
if obj.IsParameterized() {
|
||||
assert(obj.scope != nil)
|
||||
check.scope = obj.scope // push type parameter scope
|
||||
}
|
||||
|
||||
sig := new(Signature)
|
||||
obj.typ = sig // guard against cycles
|
||||
fdecl := decl.fdecl
|
||||
check.funcType(sig, fdecl.Recv, obj.scope, obj.tparams, fdecl.Type)
|
||||
check.funcType(sig, fdecl.Recv, fdecl.Type)
|
||||
sig.tparams = obj.tparams
|
||||
|
||||
if obj.IsParameterized() {
|
||||
check.closeScope()
|
||||
}
|
||||
|
||||
// function body must be type-checked after global declarations
|
||||
// (functions implemented elsewhere have no body)
|
||||
|
|
|
|||
|
|
@ -338,6 +338,9 @@ func (obj *Func) FullName() string {
|
|||
// Scope returns the scope of the function's body block.
|
||||
func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
|
||||
|
||||
// IsParameterized reports whether obj is a parameterized function.
|
||||
func (obj *Func) IsParameterized() bool { return len(obj.tparams) > 0 }
|
||||
|
||||
func (*Func) isDependency() {} // a function may be a dependency of an initialization expression
|
||||
|
||||
// A Label represents a declared label.
|
||||
|
|
|
|||
|
|
@ -6,14 +6,11 @@ package p
|
|||
|
||||
type List(type E) []E
|
||||
|
||||
func f(type P) (x P) List(P) {
|
||||
return List(P){x}
|
||||
/*
|
||||
func (l List(E)) First() E {
|
||||
if len(l) == 0 {
|
||||
panic("no first")
|
||||
}
|
||||
return l[0]
|
||||
}
|
||||
|
||||
var (
|
||||
_ []int = f(0)
|
||||
_ []float32 = f(float32)(10)
|
||||
_ [](List(int)) = f(List(int){})
|
||||
_ List(List(int)) = [](List(int)){}
|
||||
_ = [](List(int)){}
|
||||
)
|
||||
*/
|
||||
|
|
@ -199,8 +199,9 @@ type Signature struct {
|
|||
// and store it in the Func Object) because when type-checking a function
|
||||
// literal we call the general type checker which returns a general Type.
|
||||
// We then unpack the *Signature and use the scope for the literal body.
|
||||
scope *Scope // function scope, present for package-local signatures
|
||||
recv *Var // nil if not a method
|
||||
scope *Scope // function scope, present for package-local signatures
|
||||
recv *Var // nil if not a method
|
||||
// TODO(gri) do we need to keep tparams in the signature?
|
||||
tparams []*TypeName // type parameters from left to right; or nil
|
||||
params *Tuple // (incoming) parameters from left to right; or nil
|
||||
results *Tuple // (outgoing) results from left to right; or nil
|
||||
|
|
|
|||
|
|
@ -157,15 +157,8 @@ func (check *Checker) instantiatedType(e ast.Expr) Type {
|
|||
}
|
||||
|
||||
// funcType type-checks a function or method type.
|
||||
func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, scope *Scope, tparams []*TypeName, ftyp *ast.FuncType) {
|
||||
// type parameters are in a scope enclosing the function scope
|
||||
if tparams != nil {
|
||||
check.scope = scope
|
||||
// TODO(gri) push/pop both (type parameter and function) scopes
|
||||
// defer check.closeScope()
|
||||
}
|
||||
|
||||
scope = NewScope(check.scope, token.NoPos, token.NoPos, "function")
|
||||
func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
|
||||
scope := NewScope(check.scope, token.NoPos, token.NoPos, "function")
|
||||
// TODO(gri) should we close this scope?
|
||||
scope.isFunc = true
|
||||
check.recordScope(ftyp, scope)
|
||||
|
|
@ -224,7 +217,6 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, scope *Sc
|
|||
}
|
||||
|
||||
sig.scope = scope
|
||||
sig.tparams = tparams
|
||||
sig.params = NewTuple(params...)
|
||||
sig.results = NewTuple(results...)
|
||||
sig.variadic = variadic
|
||||
|
|
@ -319,7 +311,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
|
|||
case *ast.FuncType:
|
||||
typ := new(Signature)
|
||||
def.setUnderlying(typ)
|
||||
check.funcType(typ, nil, nil, nil, e)
|
||||
check.funcType(typ, nil, e)
|
||||
return typ
|
||||
|
||||
case *ast.InterfaceType:
|
||||
|
|
|
|||
Loading…
Reference in New Issue