// construct a suitable new type parameter
tpar := NewTypeName(nopos, nil /* = Universe pkg */, "<type parameter>", nil)
- ptyp := check.NewTypeParam(tp.ptr, tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
+ ptyp := check.NewTypeParam(tpar, 0, &emptyInterface) // assigns type to tpar as a side-effect
tsum := NewSum(rtypes)
ptyp.bound = &Interface{types: tsum, allMethods: markComplete, allTypes: tsum}
}
func (check *Checker) declareTypeParam(tparams []*TypeName, name *syntax.Name) []*TypeName {
- var ptr bool
- nstr := name.Value
- if len(nstr) > 0 && nstr[0] == '*' {
- ptr = true
- nstr = nstr[1:]
- }
- tpar := NewTypeName(name.Pos(), check.pkg, nstr, nil)
- check.NewTypeParam(ptr, 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
+ tpar := NewTypeName(name.Pos(), check.pkg, name.Value, nil)
+ 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)
if check.conf.Trace {
// is shorthand for (&x).m()".
if f, _ := obj.(*Func); f != nil {
// determine if method has a pointer receiver
- hasPtrRecv := tpar == nil && ptrRecv(f) || tpar != nil && tpar.ptr
+ hasPtrRecv := tpar == nil && ptrRecv(f)
if hasPtrRecv && !indirect && !addressable {
return nil, nil, true // pointer/addressable receiver required
}
// - check only if we have methods
check.completeInterface(nopos, iface)
if len(iface.allMethods) > 0 {
- // If the type argument is a type parameter itself, its pointer designation
- // must match the pointer designation of the callee's type parameter.
// If the type argument is a pointer to a type parameter, the type argument's
// method set is empty.
// TODO(gri) is this what we want? (spec question)
- if tparg := targ.TypeParam(); tparg != nil {
- if tparg.ptr != tpar.ptr {
- check.errorf(pos, "pointer designation mismatch")
- break
- }
- } else if base, isPtr := deref(targ); isPtr && base.TypeParam() != nil {
+ if base, isPtr := deref(targ); isPtr && base.TypeParam() != nil {
check.errorf(pos, "%s has no methods", targ)
break
}
- // If a type parameter is marked as a pointer type, the type bound applies
- // to a pointer of the type argument.
- actual := targ
- if tpar.ptr {
- actual = NewPointer(targ)
- }
- if m, wrong := check.missingMethod(actual, iface, true); m != nil {
+ if m, wrong := check.missingMethod(targ, iface, true); m != nil {
// TODO(gri) needs to print updated name to avoid major confusion in error message!
// (print warning for now)
// check.softErrorf(pos, "%s does not satisfy %s (warning: name not updated) = %s (missing method %s)", targ, tpar.bound, iface, m)
type TypeParam struct {
check *Checker // for lazy type bound completion
id uint64 // unique id
- ptr bool // pointer designation
obj *TypeName // corresponding type name
index int // parameter index
bound Type // *Named or *Interface; underlying type is always *Interface
}
// NewTypeParam returns a new TypeParam.
-func (check *Checker) NewTypeParam(ptr bool, obj *TypeName, index int, bound Type) *TypeParam {
+func (check *Checker) NewTypeParam(obj *TypeName, index int, bound Type) *TypeParam {
assert(bound != nil)
- typ := &TypeParam{check: check, id: check.nextId, ptr: ptr, obj: obj, index: index, bound: bound}
+ typ := &TypeParam{check: check, id: check.nextId, obj: obj, index: index, bound: bound}
check.nextId++
if obj.typ == nil {
obj.typ = typ
prev = b
if t, _ := p.typ.(*TypeParam); t != nil {
- if t.ptr {
- buf.WriteByte('*')
- }
writeType(buf, t, qf, visited)
} else {
buf.WriteString(p.name)
// - only do this if we have the right number (otherwise an error is reported elsewhere)
if len(sig.rparams) == len(recvTParams) {
// We have a list of *TypeNames but we need a list of Types.
- // While creating this list, also update type parameter pointer designation
- // for each (*TypeParam) list entry, by copying the information from the
- // receiver base type's type parameters.
list := make([]Type, len(sig.rparams))
for i, t := range sig.rparams {
- t.typ.(*TypeParam).ptr = recvTParams[i].typ.(*TypeParam).ptr
list[i] = t.typ
}
for i, tname := range sig.rparams {