mirror of
https://github.com/golang/go
synced 2024-09-05 07:54:46 +00:00
[dev.typeparams] cmd/compile: remove some shape checks in type substituter, other cleanups
The type substituter (typecheck.Typ()) was temporarily substituting from shapes back to concrete types, but doesn't need to anymore. So, remove two shape checks, so the type substituter is now only for substituting type params again. Several other cleanups: - renamed makeGenericName() to makeInstName1(), since that function is a helper to MakeInstName() and MakeDictName() that definitely makes instantiated names, not generic names. - removed the logic in makeInstName1() that adds the ".inst." prefix for concrete type args. We are only specifying concrete type args (as opposed to shape args) when we are calling from MakeDictName, and then we immediately strip of the .inst prefix anyway. - Added a comment on types.Identical that a shape type is considered identicall to another type if their underlying types are the same, or they are both pointers. Change-Id: I3e0206dbd403897797ae7bec3c527ae16b0b930a Reviewed-on: https://go-review.googlesource.com/c/go/+/341729 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com>
This commit is contained in:
parent
677dfe5ad6
commit
7e9f911ec4
|
@ -900,31 +900,11 @@ func TypesOf(x []ir.Node) []*types.Type {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeGenericName returns the name of the generic function instantiated
|
// makeInstName1 returns the name of the generic function instantiated with the
|
||||||
// with the given types.
|
// given types, which can have type params or shapes, or be concrete types. name is
|
||||||
// name is the name of the generic function or method.
|
// the name of the generic function or method.
|
||||||
func makeGenericName(name string, targs []*types.Type, hasBrackets bool) string {
|
func makeInstName1(name string, targs []*types.Type, hasBrackets bool) string {
|
||||||
b := bytes.NewBufferString("")
|
b := bytes.NewBufferString("")
|
||||||
|
|
||||||
// Determine if the type args are concrete types or new typeparams.
|
|
||||||
hasTParam := false
|
|
||||||
for _, targ := range targs {
|
|
||||||
if hasTParam {
|
|
||||||
assert(targ.HasTParam() || targ.HasShape())
|
|
||||||
} else if targ.HasTParam() || targ.HasShape() {
|
|
||||||
hasTParam = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker to distinguish generic instantiations from fully stenciled wrapper functions.
|
|
||||||
// Once we move to GC shape implementations, this prefix will not be necessary as the
|
|
||||||
// GC shape naming will distinguish them.
|
|
||||||
// e.g. f[8bytenonpointer] vs. f[int].
|
|
||||||
// For now, we use .inst.f[int] vs. f[int].
|
|
||||||
if !hasTParam {
|
|
||||||
b.WriteString(".inst.")
|
|
||||||
}
|
|
||||||
|
|
||||||
i := strings.Index(name, "[")
|
i := strings.Index(name, "[")
|
||||||
assert(hasBrackets == (i >= 0))
|
assert(hasBrackets == (i >= 0))
|
||||||
if i >= 0 {
|
if i >= 0 {
|
||||||
|
@ -963,7 +943,7 @@ func makeGenericName(name string, targs []*types.Type, hasBrackets bool) string
|
||||||
|
|
||||||
// MakeInstName makes the unique name for a stenciled generic function or method,
|
// MakeInstName makes the unique name for a stenciled generic function or method,
|
||||||
// based on the name of the function fnsym and the targs. It replaces any
|
// based on the name of the function fnsym and the targs. It replaces any
|
||||||
// existing bracket type list in the name. makeInstName asserts that fnsym has
|
// existing bracket type list in the name. MakeInstName asserts that fnsym has
|
||||||
// brackets in its name if and only if hasBrackets is true.
|
// brackets in its name if and only if hasBrackets is true.
|
||||||
//
|
//
|
||||||
// Names of declared generic functions have no brackets originally, so hasBrackets
|
// Names of declared generic functions have no brackets originally, so hasBrackets
|
||||||
|
@ -974,7 +954,7 @@ func makeGenericName(name string, targs []*types.Type, hasBrackets bool) string
|
||||||
// The standard naming is something like: 'genFn[int,bool]' for functions and
|
// The standard naming is something like: 'genFn[int,bool]' for functions and
|
||||||
// '(*genType[int,bool]).methodName' for methods
|
// '(*genType[int,bool]).methodName' for methods
|
||||||
func MakeInstName(gf *types.Sym, targs []*types.Type, hasBrackets bool) *types.Sym {
|
func MakeInstName(gf *types.Sym, targs []*types.Type, hasBrackets bool) *types.Sym {
|
||||||
return gf.Pkg.Lookup(makeGenericName(gf.Name, targs, hasBrackets))
|
return gf.Pkg.Lookup(makeInstName1(gf.Name, targs, hasBrackets))
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeDictName(gf *types.Sym, targs []*types.Type, hasBrackets bool) *types.Sym {
|
func MakeDictName(gf *types.Sym, targs []*types.Type, hasBrackets bool) *types.Sym {
|
||||||
|
@ -987,8 +967,8 @@ func MakeDictName(gf *types.Sym, targs []*types.Type, hasBrackets bool) *types.S
|
||||||
panic("dictionary should always have concrete type args")
|
panic("dictionary should always have concrete type args")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name := makeGenericName(gf.Name, targs, hasBrackets)
|
name := makeInstName1(gf.Name, targs, hasBrackets)
|
||||||
name = ".dict." + name[6:]
|
name = ".dict." + name
|
||||||
return gf.Pkg.Lookup(name)
|
return gf.Pkg.Lookup(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,14 +994,14 @@ type Tsubster struct {
|
||||||
// result is t; otherwise the result is a new type. It deals with recursive types
|
// result is t; otherwise the result is a new type. It deals with recursive types
|
||||||
// by using TFORW types and finding partially or fully created types via sym.Def.
|
// by using TFORW types and finding partially or fully created types via sym.Def.
|
||||||
func (ts *Tsubster) Typ(t *types.Type) *types.Type {
|
func (ts *Tsubster) Typ(t *types.Type) *types.Type {
|
||||||
if !t.HasTParam() && !t.HasShape() && t.Kind() != types.TFUNC {
|
if !t.HasTParam() && t.Kind() != types.TFUNC {
|
||||||
// Note: function types need to be copied regardless, as the
|
// Note: function types need to be copied regardless, as the
|
||||||
// types of closures may contain declarations that need
|
// types of closures may contain declarations that need
|
||||||
// to be copied. See #45738.
|
// to be copied. See #45738.
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.IsTypeParam() || t.IsShape() {
|
if t.IsTypeParam() {
|
||||||
for i, tp := range ts.Tparams {
|
for i, tp := range ts.Tparams {
|
||||||
if tp == t {
|
if tp == t {
|
||||||
return ts.Targs[i]
|
return ts.Targs[i]
|
||||||
|
|
|
@ -4,8 +4,11 @@
|
||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
// Identical reports whether t1 and t2 are identical types, following
|
// Identical reports whether t1 and t2 are identical types, following the spec rules.
|
||||||
// the spec rules. Receiver parameter types are ignored.
|
// Receiver parameter types are ignored. Named (defined) types are only equal if they
|
||||||
|
// are pointer-equal - i.e. there must be a unique types.Type for each specific named
|
||||||
|
// type. Also, a type containing a shape type is considered identical to another type
|
||||||
|
// (shape or not) if their underlying types are the same, or they are both pointers.
|
||||||
func Identical(t1, t2 *Type) bool {
|
func Identical(t1, t2 *Type) bool {
|
||||||
return identical(t1, t2, true, nil)
|
return identical(t1, t2, true, nil)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue