mirror of https://github.com/golang/go.git
go/types: factor out/consolidate instantiate calls
Change-Id: I4973e0ebcd07d543b049f1fcdd8040f2ae214142
This commit is contained in:
parent
be92a40c3f
commit
3458c46de1
|
|
@ -1,5 +1,6 @@
|
|||
TODO
|
||||
- satisfyBounds is not working correctly
|
||||
- no bounds checks in instantiate call (see open issues below)
|
||||
- allow recursive type parameterization without need to repeat type parameters
|
||||
- if type parameters are repeated in recursive instantiation, they must be the same order
|
||||
- implement contract embedding
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
|
|||
}
|
||||
|
||||
// instantiate function signature
|
||||
x.typ = check.subst(x.pos(), sig, sig.tparams, targs)
|
||||
x.typ = check.instantiate(x.pos(), sig, targs)
|
||||
x.mode = value
|
||||
x.expr = e
|
||||
return expression
|
||||
|
|
@ -313,7 +313,7 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, args []*oper
|
|||
if targs == nil {
|
||||
return
|
||||
}
|
||||
rsig = check.subst(call.Pos(), sig, sig.tparams, targs).(*Signature)
|
||||
rsig = check.instantiate(call.Pos(), sig, targs).(*Signature)
|
||||
params = check.subst(call.Pos(), params, sig.tparams, targs).(*Tuple)
|
||||
// TODO(gri) Optimization: We don't need to check arguments
|
||||
// from which we inferred parameter types.
|
||||
|
|
|
|||
|
|
@ -14,10 +14,9 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func (check *Checker) instantiate(pos token.Pos, named *Named, targs []Type) (res Type) {
|
||||
tname := named.obj
|
||||
func (check *Checker) instantiate(pos token.Pos, typ Type, targs []Type) (res Type) {
|
||||
if check.conf.Trace {
|
||||
check.trace(pos, "-- instantiating %s with %s", tname, typeListString(targs))
|
||||
check.trace(pos, "-- instantiating %s with %s", typ, typeListString(targs))
|
||||
check.indent++
|
||||
defer func() {
|
||||
check.indent--
|
||||
|
|
@ -29,8 +28,18 @@ func (check *Checker) instantiate(pos token.Pos, named *Named, targs []Type) (re
|
|||
}()
|
||||
}
|
||||
|
||||
// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
|
||||
return check.subst(pos, named, tname.tparams, targs)
|
||||
// TODO(gri) need to do a satisfy bounds check here
|
||||
|
||||
switch typ := typ.(type) {
|
||||
case *Named:
|
||||
// TODO(gri) What is better here: work with TypeParams, or work with TypeNames?
|
||||
return check.subst(pos, typ, typ.obj.tparams, targs)
|
||||
|
||||
case *Signature:
|
||||
return check.subst(pos, typ, typ.tparams, targs)
|
||||
}
|
||||
|
||||
panic("unreachable") // only defined types and (defined) functions can be generic
|
||||
}
|
||||
|
||||
// subst returns the type typ with its type parameters tparams replaced by
|
||||
|
|
|
|||
|
|
@ -279,8 +279,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) (T Type) {
|
|||
}
|
||||
|
||||
// the number of supplied types must match the number of type parameters
|
||||
named, _ := typ.(*Named) // generic types are defined (= Named) types
|
||||
tname := named.obj
|
||||
tname := typ.(*Named).obj // generic types are defined (= Named) types
|
||||
if len(targs) != len(tname.tparams) {
|
||||
// TODO(gri) provide better error message
|
||||
check.errorf(e.Pos(), "got %d arguments but %d type parameters", len(e.Args), len(tname.tparams))
|
||||
|
|
@ -313,7 +312,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) (T Type) {
|
|||
}
|
||||
|
||||
// instantiate parameterized type
|
||||
typ = check.instantiate(e.Pos(), named, targs)
|
||||
typ = check.instantiate(e.Pos(), typ, targs)
|
||||
def.setUnderlying(typ)
|
||||
return typ
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue