id uint64 // unique id, for debugging only
obj *TypeName // corresponding type name
index int // type parameter index in source order, starting at 0
- bound Type // any type, but eventually an *Interface for correct programs (see TypeParam.iface)
+ bound Type // any type, but underlying is eventually *Interface for correct programs (see TypeParam.iface)
}
// Obj returns the type name for the type parameter t.
if obj.typ == nil {
obj.typ = typ
}
+ // iface may mutate typ.bound, so we must ensure that iface() is called
+ // at least once before the resulting TypeParam escapes.
+ if check != nil {
+ check.later(func() {
+ typ.iface()
+ })
+ } else if constraint != nil {
+ typ.iface()
+ }
return typ
}
}
// SetConstraint sets the type constraint for t.
+//
+// SetConstraint should not be called concurrently, but once SetConstraint
+// returns the receiver t is safe for concurrent use.
func (t *TypeParam) SetConstraint(bound Type) {
if bound == nil {
panic("nil constraint")
}
t.bound = bound
+ // iface may mutate t.bound (if bound is not an interface), so ensure that
+ // this is done before returning.
+ t.iface()
}
func (t *TypeParam) Underlying() Type {
id uint64 // unique id, for debugging only
obj *TypeName // corresponding type name
index int // type parameter index in source order, starting at 0
- bound Type // any type, but eventually an *Interface for correct programs (see TypeParam.iface)
+ bound Type // any type, but underlying is eventually *Interface for correct programs (see TypeParam.iface)
}
// NewTypeParam returns a new TypeParam. Type parameters may be set on a Named
if obj.typ == nil {
obj.typ = typ
}
+ // iface may mutate typ.bound, so we must ensure that iface() is called
+ // at least once before the resulting TypeParam escapes.
+ if check != nil {
+ check.later(func() {
+ typ.iface()
+ })
+ } else if constraint != nil {
+ typ.iface()
+ }
return typ
}
}
// SetConstraint sets the type constraint for t.
+//
+// SetConstraint should not be called concurrently, but once SetConstraint
+// returns the receiver t is safe for concurrent use.
func (t *TypeParam) SetConstraint(bound Type) {
if bound == nil {
panic("nil constraint")
}
t.bound = bound
+ // iface may mutate t.bound (if bound is not an interface), so ensure that
+ // this is done before returning.
+ t.iface()
}
func (t *TypeParam) Underlying() Type {
}
// If we don't have an interface, wrap constraint into an implicit interface.
- // TODO(gri) mark it as implicit - see comment in Checker.bound
if ityp == nil {
ityp = NewInterfaceType(nil, []Type{bound})
ityp.implicit = true