Skip to content

Commit bf26e43

Browse files
committed
go/types: eliminate Named.instPos
We no longer need to use the nilness of Named.instPos to signal whether instance expansion has occurred, so remove it from the Named struct by instead closing over the instantiation position in the resolver. This means we cannot print instance markers for unexpanded instances: instances may escape the type checking pass without being fully expanded, and we can not check whether they have been expanded in a concurrency-safe way without introducing a more heavy-weight syncronization mechanism. With this change, instantiation should be concurrency safe, modulo bugs of course as we have little test coverage of concurrency (see #47729). Fixes #47910 Change-Id: Ifeef6df296f00105579554b333a44d08aae113c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/349411 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 2933c45 commit bf26e43

File tree

9 files changed

+8
-33
lines changed

9 files changed

+8
-33
lines changed

src/go/internal/gcimporter/gcimporter_test.go

-3
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,6 @@ func TestImportTypeparamTests(t *testing.T) {
238238
func sanitizeObjectString(s string) string {
239239
var runes []rune
240240
for _, r := range s {
241-
if r == '#' {
242-
continue // trim instance markers
243-
}
244241
if '₀' <= r && r < '₀'+10 {
245242
continue // trim type parameter subscripts
246243
}

src/go/types/environment.go

-7
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,6 @@ func (env *Environment) typeHash(typ Type, targs []Type) string {
5050
h.typ(typ)
5151
}
5252

53-
if debug {
54-
// there should be no instance markers in type hashes
55-
for _, b := range buf.Bytes() {
56-
assert(b != instanceMarker)
57-
}
58-
}
59-
6053
return buf.String()
6154
}
6255

src/go/types/errors.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ func stripAnnotations(s string) string {
265265
var b strings.Builder
266266
for _, r := range s {
267267
// strip #'s and subscript digits
268-
if r != instanceMarker && !('₀' <= r && r < '₀'+10) { // '₀' == U+2080
268+
if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
269269
b.WriteRune(r)
270270
}
271271
}

src/go/types/errors_test.go

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ func TestStripAnnotations(t *testing.T) {
1515
{"foo", "foo"},
1616
{"foo₀", "foo"},
1717
{"foo(T₀)", "foo(T)"},
18-
{"#foo(T₀)", "foo(T)"},
1918
} {
2019
got := stripAnnotations(test.in)
2120
if got != test.want {

src/go/types/instantiate.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ func (check *Checker) instance(pos token.Pos, typ Type, targs []Type, env *Envir
118118
tname := NewTypeName(pos, t.obj.pkg, t.obj.name, nil)
119119
named := check.newNamed(tname, t, nil, nil, nil) // methods and tparams are set when named is resolved
120120
named.targs = NewTypeList(targs)
121-
named.instPos = &pos
122-
named.resolver = expandNamed
121+
named.resolver = func(env *Environment, n *Named) (*TypeParamList, Type, []*Func) {
122+
return expandNamed(env, n, pos)
123+
}
123124
if env != nil {
124125
// It's possible that we've lost a race to add named to the environment.
125126
// In this case, use whichever instance is recorded in the environment.

src/go/types/named.go

+3-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ type Named struct {
1717
orig *Named // original, uninstantiated type
1818
fromRHS Type // type (on RHS of declaration) this *Named type is derived of (for cycle reporting)
1919
underlying Type // possibly a *Named during setup; never a *Named once set up completely
20-
instPos *token.Pos // position information for lazy instantiation, or nil
2120
tparams *TypeParamList // type parameters, or nil
2221
targs *TypeList // type arguments (after instantiation), or nil
2322
methods []*Func // methods declared for this type (not the method set of this type); signatures are type-checked lazily
@@ -222,11 +221,11 @@ func (n *Named) setUnderlying(typ Type) {
222221

223222
// expandNamed ensures that the underlying type of n is instantiated.
224223
// The underlying type will be Typ[Invalid] if there was an error.
225-
func expandNamed(env *Environment, n *Named) (*TypeParamList, Type, []*Func) {
224+
func expandNamed(env *Environment, n *Named, instPos token.Pos) (*TypeParamList, Type, []*Func) {
226225
n.orig.resolve(env)
227226

228227
var u Type
229-
if n.check.validateTArgLen(*n.instPos, n.orig.tparams.Len(), n.targs.Len()) {
228+
if n.check.validateTArgLen(instPos, n.orig.tparams.Len(), n.targs.Len()) {
230229
// TODO(rfindley): handling an optional Checker and Environment here (and
231230
// in subst) feels overly complicated. Can we simplify?
232231
if env == nil {
@@ -245,11 +244,10 @@ func expandNamed(env *Environment, n *Named) (*TypeParamList, Type, []*Func) {
245244
// shouldn't return that instance from expand.
246245
env.typeForHash(h, n)
247246
}
248-
u = n.check.subst(*n.instPos, n.orig.underlying, makeSubstMap(n.orig.tparams.list(), n.targs.list()), env)
247+
u = n.check.subst(instPos, n.orig.underlying, makeSubstMap(n.orig.tparams.list(), n.targs.list()), env)
249248
} else {
250249
u = Typ[Invalid]
251250
}
252-
n.instPos = nil
253251
return n.orig.tparams, u, n.orig.methods
254252
}
255253

src/go/types/sizeof_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestSizeof(t *testing.T) {
3030
{Interface{}, 44, 88},
3131
{Map{}, 16, 32},
3232
{Chan{}, 12, 24},
33-
{Named{}, 72, 136},
33+
{Named{}, 68, 128},
3434
{TypeParam{}, 28, 48},
3535
{term{}, 12, 24},
3636
{top{}, 0, 0},

src/go/types/subst.go

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ package types
88

99
import "go/token"
1010

11-
// TODO(rFindley) decide error codes for the errors in this file, and check
12-
// if error spans can be improved
13-
1411
type substMap map[*TypeParam]Type
1512

1613
// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].

src/go/types/typestring.go

-10
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@ func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
6565
newTypeWriter(buf, qf).signature(sig)
6666
}
6767

68-
// instanceMarker is the prefix for an instantiated type in unexpanded form.
69-
const instanceMarker = '#'
70-
7168
type typeWriter struct {
7269
buf *bytes.Buffer
7370
seen map[Type]bool
@@ -226,13 +223,6 @@ func (w *typeWriter) typ(typ Type) {
226223
}
227224

228225
case *Named:
229-
// Instance markers indicate unexpanded instantiated
230-
// types. Write them to aid debugging, but don't write
231-
// them when we need an instance hash: whether a type
232-
// is fully expanded or not doesn't matter for identity.
233-
if w.env == nil && t.instPos != nil {
234-
w.byte(instanceMarker)
235-
}
236226
w.typePrefix(t)
237227
w.typeName(t.obj)
238228
if t.targs != nil {

0 commit comments

Comments
 (0)