mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile/internal/types2: remove support for type parameter pointer designation
An earlier version of the draft design supported pointer designation for type parameters. Remove related code since we don't need it anymore. Change-Id: I0d9e8c5f02a9a6745ff7ee15b8267a99ab1529e1 Reviewed-on: https://go-review.googlesource.com/c/go/+/273327 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
ba9c35aa12
commit
fbc4c6a3ae
7 changed files with 9 additions and 36 deletions
|
|
@ -727,7 +727,7 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x Type) Type {
|
||||||
|
|
||||||
// construct a suitable new type parameter
|
// construct a suitable new type parameter
|
||||||
tpar := NewTypeName(nopos, nil /* = Universe pkg */, "<type parameter>", nil)
|
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)
|
tsum := NewSum(rtypes)
|
||||||
ptyp.bound = &Interface{types: tsum, allMethods: markComplete, allTypes: tsum}
|
ptyp.bound = &Interface{types: tsum, allMethods: markComplete, allTypes: tsum}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -734,15 +734,9 @@ func (check *Checker) collectTypeParams(list []*syntax.Field) (tparams []*TypeNa
|
||||||
}
|
}
|
||||||
|
|
||||||
func (check *Checker) declareTypeParam(tparams []*TypeName, name *syntax.Name) []*TypeName {
|
func (check *Checker) declareTypeParam(tparams []*TypeName, name *syntax.Name) []*TypeName {
|
||||||
var ptr bool
|
tpar := NewTypeName(name.Pos(), check.pkg, name.Value, nil)
|
||||||
nstr := name.Value
|
check.NewTypeParam(tpar, len(tparams), &emptyInterface) // assigns type to tpar as a side-effect
|
||||||
if len(nstr) > 0 && nstr[0] == '*' {
|
check.declare(check.scope, name, tpar, check.scope.pos) // TODO(gri) check scope position
|
||||||
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
|
|
||||||
tparams = append(tparams, tpar)
|
tparams = append(tparams, tpar)
|
||||||
|
|
||||||
if check.conf.Trace {
|
if check.conf.Trace {
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ func (check *Checker) rawLookupFieldOrMethod(T Type, addressable bool, pkg *Pack
|
||||||
// is shorthand for (&x).m()".
|
// is shorthand for (&x).m()".
|
||||||
if f, _ := obj.(*Func); f != nil {
|
if f, _ := obj.(*Func); f != nil {
|
||||||
// determine if method has a pointer receiver
|
// 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 {
|
if hasPtrRecv && !indirect && !addressable {
|
||||||
return nil, nil, true // pointer/addressable receiver required
|
return nil, nil, true // pointer/addressable receiver required
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,27 +143,14 @@ func (check *Checker) instantiate(pos syntax.Pos, typ Type, targs []Type, poslis
|
||||||
// - check only if we have methods
|
// - check only if we have methods
|
||||||
check.completeInterface(nopos, iface)
|
check.completeInterface(nopos, iface)
|
||||||
if len(iface.allMethods) > 0 {
|
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
|
// If the type argument is a pointer to a type parameter, the type argument's
|
||||||
// method set is empty.
|
// method set is empty.
|
||||||
// TODO(gri) is this what we want? (spec question)
|
// TODO(gri) is this what we want? (spec question)
|
||||||
if tparg := targ.TypeParam(); tparg != nil {
|
if base, isPtr := deref(targ); isPtr && base.TypeParam() != nil {
|
||||||
if tparg.ptr != tpar.ptr {
|
|
||||||
check.errorf(pos, "pointer designation mismatch")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if base, isPtr := deref(targ); isPtr && base.TypeParam() != nil {
|
|
||||||
check.errorf(pos, "%s has no methods", targ)
|
check.errorf(pos, "%s has no methods", targ)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// If a type parameter is marked as a pointer type, the type bound applies
|
if m, wrong := check.missingMethod(targ, iface, true); m != nil {
|
||||||
// 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 {
|
|
||||||
// TODO(gri) needs to print updated name to avoid major confusion in error message!
|
// TODO(gri) needs to print updated name to avoid major confusion in error message!
|
||||||
// (print warning for now)
|
// (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)
|
// check.softErrorf(pos, "%s does not satisfy %s (warning: name not updated) = %s (missing method %s)", targ, tpar.bound, iface, m)
|
||||||
|
|
|
||||||
|
|
@ -832,7 +832,6 @@ func (t *Named) AddMethod(m *Func) {
|
||||||
type TypeParam struct {
|
type TypeParam struct {
|
||||||
check *Checker // for lazy type bound completion
|
check *Checker // for lazy type bound completion
|
||||||
id uint64 // unique id
|
id uint64 // unique id
|
||||||
ptr bool // pointer designation
|
|
||||||
obj *TypeName // corresponding type name
|
obj *TypeName // corresponding type name
|
||||||
index int // parameter index
|
index int // parameter index
|
||||||
bound Type // *Named or *Interface; underlying type is always *Interface
|
bound Type // *Named or *Interface; underlying type is always *Interface
|
||||||
|
|
@ -840,9 +839,9 @@ type TypeParam struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTypeParam returns a new TypeParam.
|
// 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)
|
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++
|
check.nextId++
|
||||||
if obj.typ == nil {
|
if obj.typ == nil {
|
||||||
obj.typ = typ
|
obj.typ = typ
|
||||||
|
|
|
||||||
|
|
@ -350,9 +350,6 @@ func writeTParamList(buf *bytes.Buffer, list []*TypeName, qf Qualifier, visited
|
||||||
prev = b
|
prev = b
|
||||||
|
|
||||||
if t, _ := p.typ.(*TypeParam); t != nil {
|
if t, _ := p.typ.(*TypeParam); t != nil {
|
||||||
if t.ptr {
|
|
||||||
buf.WriteByte('*')
|
|
||||||
}
|
|
||||||
writeType(buf, t, qf, visited)
|
writeType(buf, t, qf, visited)
|
||||||
} else {
|
} else {
|
||||||
buf.WriteString(p.name)
|
buf.WriteString(p.name)
|
||||||
|
|
|
||||||
|
|
@ -307,12 +307,8 @@ func (check *Checker) funcType(sig *Signature, recvPar *syntax.Field, tparams []
|
||||||
// - only do this if we have the right number (otherwise an error is reported elsewhere)
|
// - only do this if we have the right number (otherwise an error is reported elsewhere)
|
||||||
if len(sig.rparams) == len(recvTParams) {
|
if len(sig.rparams) == len(recvTParams) {
|
||||||
// We have a list of *TypeNames but we need a list of Types.
|
// 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))
|
list := make([]Type, len(sig.rparams))
|
||||||
for i, t := range sig.rparams {
|
for i, t := range sig.rparams {
|
||||||
t.typ.(*TypeParam).ptr = recvTParams[i].typ.(*TypeParam).ptr
|
|
||||||
list[i] = t.typ
|
list[i] = t.typ
|
||||||
}
|
}
|
||||||
for i, tname := range sig.rparams {
|
for i, tname := range sig.rparams {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue