Skip to content

Commit 0d87589

Browse files
committed
go/types/typeutil: audit for types.Alias safety
Updates golang/go#65294 Change-Id: I921517b9c722d03aaa7c3dc3e0c45364b3a1d53d Reviewed-on: https://go-review.googlesource.com/c/tools/+/559915 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Tim King <[email protected]>
1 parent a297bfd commit 0d87589

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

go/types/typeutil/map.go

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"go/types"
1313
"reflect"
1414

15+
"golang.org/x/tools/internal/aliases"
1516
"golang.org/x/tools/internal/typeparams"
1617
)
1718

@@ -259,6 +260,9 @@ func (h Hasher) hashFor(t types.Type) uint32 {
259260
case *types.Basic:
260261
return uint32(t.Kind())
261262

263+
case *aliases.Alias:
264+
return h.Hash(t.Underlying())
265+
262266
case *types.Array:
263267
return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())
264268

@@ -457,6 +461,9 @@ func (h Hasher) shallowHash(t types.Type) uint32 {
457461
// elements (mostly Slice, Pointer, Basic, Named),
458462
// so there's no need to optimize anything else.
459463
switch t := t.(type) {
464+
case *aliases.Alias:
465+
return h.shallowHash(t.Underlying())
466+
460467
case *types.Signature:
461468
var hash uint32 = 604171
462469
if t.Variadic() {

go/types/typeutil/map_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,15 @@ var Issue56048 = Issue56048_I.m
247247
type Issue56048_Ib interface{ m() chan []*interface { Issue56048_Ib } }
248248
var Issue56048b = Issue56048_Ib.m
249249
250+
// Non-generic alias
251+
type NonAlias int
252+
type Alias1 = NonAlias
253+
type Alias2 = NonAlias
254+
255+
// Generic alias (requires go1.23)
256+
// type SetOfInt = map[int]bool
257+
// type Set[T comparable] = map[K]bool
258+
// type SetOfInt2 = Set[int]
250259
`
251260

252261
fset := token.NewFileSet()
@@ -307,6 +316,16 @@ var Issue56048b = Issue56048_Ib.m
307316
Quux = scope.Lookup("Quux").Type()
308317
Issue56048 = scope.Lookup("Issue56048").Type()
309318
Issue56048b = scope.Lookup("Issue56048b").Type()
319+
320+
// In go1.23 these will be *types.Alias; for now they are all int.
321+
NonAlias = scope.Lookup("NonAlias").Type()
322+
Alias1 = scope.Lookup("Alias1").Type()
323+
Alias2 = scope.Lookup("Alias2").Type()
324+
325+
// Requires go1.23.
326+
// SetOfInt = scope.Lookup("SetOfInt").Type()
327+
// Set = scope.Lookup("Set").Type().(*types.Alias)
328+
// SetOfInt2 = scope.Lookup("SetOfInt2").Type()
310329
)
311330

312331
tmap := new(typeutil.Map)
@@ -379,6 +398,16 @@ var Issue56048b = Issue56048_Ib.m
379398

380399
{Issue56048, "Issue56048", true}, // (not actually about generics)
381400
{Issue56048b, "Issue56048b", true}, // (not actually about generics)
401+
402+
// All three types are identical.
403+
{NonAlias, "NonAlias", true},
404+
{Alias1, "Alias1", false},
405+
{Alias2, "Alias2", false},
406+
407+
// Generic aliases: requires go1.23.
408+
// {SetOfInt, "SetOfInt", true},
409+
// {Set, "Set", false},
410+
// {SetOfInt2, "SetOfInt2", false},
382411
}
383412

384413
for _, step := range steps {

go/types/typeutil/methodsetcache.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ package typeutil
99
import (
1010
"go/types"
1111
"sync"
12+
13+
"golang.org/x/tools/internal/aliases"
1214
)
1315

1416
// A MethodSetCache records the method set of each type T for which
@@ -32,12 +34,12 @@ func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
3234
cache.mu.Lock()
3335
defer cache.mu.Unlock()
3436

35-
switch T := T.(type) {
37+
switch T := aliases.Unalias(T).(type) {
3638
case *types.Named:
3739
return cache.lookupNamed(T).value
3840

3941
case *types.Pointer:
40-
if N, ok := T.Elem().(*types.Named); ok {
42+
if N, ok := aliases.Unalias(T.Elem()).(*types.Named); ok {
4143
return cache.lookupNamed(N).pointer
4244
}
4345
}

0 commit comments

Comments
 (0)