return nil
}
- // construct a suitable new type parameter
- tpar := NewTypeName(token.NoPos, nil /* = Universe pkg */, "<type parameter>", nil)
- ptyp := check.newTypeParam(tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
+ // Construct a suitable new type parameter for the sum type. The
+ // type param is placed in the current package so export/import
+ // works as expected.
+ tpar := NewTypeName(token.NoPos, check.pkg, "<type parameter>", nil)
+ ptyp := check.NewTypeParam(tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
tsum := newUnion(rtypes, tildes)
ptyp.bound = &Interface{complete: true, tset: &TypeSet{types: tsum}}
func (check *Checker) declareTypeParams(tparams []*TypeName, names []*ast.Ident) []*TypeName {
for _, name := range names {
tpar := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
- check.newTypeParam(tpar, len(tparams), &emptyInterface) // assigns type to tpar as a side-effect
+ check.NewTypeParam(tpar, len(tparams), &emptyInterface) // assigns type to tpar as a side-effect
check.declare(check.scope, name, tpar, check.scope.pos) // TODO(gri) check scope position
tparams = append(tparams, tpar)
}
return t
}
-// optype returns a type's operational type. Except for type parameters,
-// the operational type is the same as the underlying type (as returned
-// by under). For Type parameters, the operational type is determined
-// by the corresponding type constraint. The result may be the top type,
-// but it is never the incoming type parameter.
+// optype returns a type's operational type. Except for
+// type parameters, the operational type is the same
+// as the underlying type (as returned by under). For
+// Type parameters, the operational type is determined
+// by the corresponding type bound's type list. The
+// result may be the bottom or top type, but it is never
+// the incoming type parameter.
func optype(typ Type) Type {
if t := asTypeParam(typ); t != nil {
// If the optype is typ, return the top type as we have
bound Type // *Named or *Interface; underlying type is always *Interface
}
-// NewTypeParam returns a new TypeParam.
-func NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
- return (*Checker)(nil).newTypeParam(obj, index, bound)
-}
-
-// TODO(rfindley): this is factored slightly differently in types2.
-func (check *Checker) newTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
- assert(bound != nil)
-
+// NewTypeParam returns a new TypeParam. bound can be nil (and set later).
+func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
// Always increment lastID, even if it is not used.
id := nextID()
if check != nil {
check.nextID++
id = check.nextID
}
-
typ := &TypeParam{check: check, id: id, obj: obj, index: index, bound: bound}
if obj.typ == nil {
obj.typ = typ
return iface
}
+func (t *TypeParam) _SetBound(bound Type) {
+ if bound == nil {
+ panic("internal error: bound must not be nil")
+ }
+ t.bound = bound
+}
+
func (t *TypeParam) Underlying() Type { return t }
func (t *TypeParam) String() string { return TypeString(t, nil) }