Skip to content

Commit 3f9badb

Browse files
committed
go/ssa: types.Unalias() cleanup.
Removes a few instances of unneeded Unalias calls, and adds additional documentation about aliases. Change-Id: I02045ef74d6d9b80189caf6a9831bded2bae5ad4 Reviewed-on: https://go-review.googlesource.com/c/tools/+/568176 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Tim King <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent e5cf370 commit 3f9badb

File tree

10 files changed

+65
-21
lines changed

10 files changed

+65
-21
lines changed

go/ssa/builder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,7 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero
12531253
case *types.Array, *types.Slice:
12541254
var at *types.Array
12551255
var array Value
1256-
switch t := aliases.Unalias(t).(type) {
1256+
switch t := t.(type) {
12571257
case *types.Slice:
12581258
at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts))
12591259
array = emitNew(fn, at, e.Lbrace, "slicelit")

go/ssa/const.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func soleTypeKind(typ types.Type) types.BasicInfo {
4646
// Candidates (perhaps all) are eliminated during the type-set
4747
// iteration, which executes at least once.
4848
state := types.IsBoolean | types.IsInteger | types.IsString
49-
underIs(typeSetOf(typ), func(t types.Type) bool {
49+
underIs(typeSetOf(typ), func(ut types.Type) bool {
5050
var c types.BasicInfo
51-
if t, ok := aliases.Unalias(t).(*types.Basic); ok {
51+
if t, ok := ut.(*types.Basic); ok {
5252
c = t.Info()
5353
}
5454
if c&types.IsNumeric != 0 { // int/float/complex

go/ssa/coretype.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func typeSetOf(typ types.Type) termList {
5050
// This is a adaptation of x/exp/typeparams.NormalTerms which x/tools cannot depend on.
5151
var terms []*types.Term
5252
var err error
53+
// typeSetOf(t) == typeSetOf(Unalias(t))
5354
switch typ := aliases.Unalias(typ).(type) {
5455
case *types.TypeParam:
5556
terms, err = typeparams.StructuralTerms(typ)

go/ssa/emit.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"go/token"
1313
"go/types"
1414

15-
"golang.org/x/tools/internal/aliases"
1615
"golang.org/x/tools/internal/typeparams"
1716
)
1817

@@ -277,18 +276,20 @@ func emitConv(f *Function, val Value, typ types.Type) Value {
277276
sliceTo0ArrayPtr
278277
convert
279278
)
280-
classify := func(s, d types.Type) conversionCase {
279+
// classify the conversion case of a source type us to a destination type ud.
280+
// us and ud are underlying types (not *Named or *Alias)
281+
classify := func(us, ud types.Type) conversionCase {
281282
// Just a change of type, but not value or representation?
282-
if isValuePreserving(s, d) {
283+
if isValuePreserving(us, ud) {
283284
return changeType
284285
}
285286

286287
// Conversion from slice to array or slice to array pointer?
287-
if slice, ok := aliases.Unalias(s).(*types.Slice); ok {
288+
if slice, ok := us.(*types.Slice); ok {
288289
var arr *types.Array
289290
var ptr bool
290291
// Conversion from slice to array pointer?
291-
switch d := aliases.Unalias(d).(type) {
292+
switch d := ud.(type) {
292293
case *types.Array:
293294
arr = d
294295
case *types.Pointer:
@@ -313,8 +314,8 @@ func emitConv(f *Function, val Value, typ types.Type) Value {
313314

314315
// The only remaining case in well-typed code is a representation-
315316
// changing conversion of basic types (possibly with []byte/[]rune).
316-
if !isBasic(s) && !isBasic(d) {
317-
panic(fmt.Sprintf("in %s: cannot convert term %s (%s [within %s]) to type %s [within %s]", f, val, val.Type(), s, typ, d))
317+
if !isBasic(us) && !isBasic(ud) {
318+
panic(fmt.Sprintf("in %s: cannot convert term %s (%s [within %s]) to type %s [within %s]", f, val, val.Type(), us, typ, ud))
318319
}
319320
return convert
320321
}

go/ssa/func.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ func (f *Function) typeOf(e ast.Expr) types.Type {
3737
panic(fmt.Sprintf("no type for %T @ %s", e, f.Prog.Fset.Position(e.Pos())))
3838
}
3939

40-
// typ is the locally instantiated type of T. T==typ(T) if f is not an instantiation.
40+
// typ is the locally instantiated type of T.
41+
// If f is not an instantiation, then f.typ(T)==T.
4142
func (f *Function) typ(T types.Type) types.Type {
4243
return f.subst.typ(T)
4344
}

go/ssa/interp/ops.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func asUnsigned(x value) (value, bool) {
173173

174174
// zero returns a new "zero" value of the specified type.
175175
func zero(t types.Type) value {
176-
switch t := aliases.Unalias(t).(type) {
176+
switch t := t.(type) {
177177
case *types.Basic:
178178
if t.Kind() == types.UntypedNil {
179179
panic("untyped nil has no zero value")
@@ -235,6 +235,8 @@ func zero(t types.Type) value {
235235
return a
236236
case *types.Named:
237237
return zero(t.Underlying())
238+
case *aliases.Alias:
239+
return zero(aliases.Unalias(t))
238240
case *types.Interface:
239241
return iface{} // nil type, methodset and value
240242
case *types.Slice:

go/ssa/interp/reflect.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ func ext۰reflect۰Zero(fr *frame, args []value) value {
179179
}
180180

181181
func reflectKind(t types.Type) reflect.Kind {
182-
switch t := aliases.Unalias(t).(type) {
183-
case *types.Named:
182+
switch t := t.(type) {
183+
case *types.Named, *aliases.Alias:
184184
return reflectKind(t.Underlying())
185185
case *types.Basic:
186186
switch t.Kind() {

go/ssa/methods.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func forEachReachable(msets *typeutil.MethodSetCache, T types.Type, f func(types
210210

211211
switch T := T.(type) {
212212
case *aliases.Alias:
213-
visit(aliases.Unalias(T), false)
213+
visit(aliases.Unalias(T), skip) // emulates the pre-Alias behavior
214214

215215
case *types.Basic:
216216
// nop

go/ssa/subst.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,7 @@ func (subst *subster) typ(t types.Type) (res types.Type) {
8080
subst.cache[t] = res
8181
}()
8282

83-
// fall through if result r will be identical to t, types.Identical(r, t).
8483
switch t := t.(type) {
85-
case *aliases.Alias:
86-
return subst.typ(aliases.Unalias(t))
87-
8884
case *types.TypeParam:
8985
r := subst.replacements[t]
9086
assert(r != nil, "type param without replacement encountered")
@@ -140,6 +136,9 @@ func (subst *subster) typ(t types.Type) (res types.Type) {
140136
case *types.Interface:
141137
return subst.interface_(t)
142138

139+
case *aliases.Alias:
140+
return subst.alias(t)
141+
143142
case *types.Named:
144143
return subst.named(t)
145144

@@ -307,6 +306,18 @@ func (subst *subster) interface_(iface *types.Interface) *types.Interface {
307306
return types.NewInterfaceType(methods, embeds).Complete()
308307
}
309308

309+
func (subst *subster) alias(t *aliases.Alias) types.Type {
310+
// TODO(go.dev/issues/46477): support TypeParameters once these are available from go/types.
311+
u := aliases.Unalias(t)
312+
if s := subst.typ(u); s != u {
313+
// If there is any change, do not create a new alias.
314+
return s
315+
}
316+
// If there is no change, t did not reach any type parameter.
317+
// Keep the Alias.
318+
return t
319+
}
320+
310321
func (subst *subster) named(t *types.Named) types.Type {
311322
// A named type may be:
312323
// (1) ordinary named type (non-local scope, no type parameters, no type arguments),

go/ssa/util.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ func isNonTypeParamInterface(t types.Type) bool {
5151
}
5252

5353
// isBasic reports whether t is a basic type.
54+
// t is assumed to be an Underlying type (not Named or Alias).
5455
func isBasic(t types.Type) bool {
55-
_, ok := aliases.Unalias(t).(*types.Basic)
56+
_, ok := t.(*types.Basic)
5657
return ok
5758
}
5859

@@ -263,13 +264,40 @@ func (c *canonizer) List(ts []types.Type) *typeList {
263264
return nil
264265
}
265266

267+
unaliasAll := func(ts []types.Type) []types.Type {
268+
// Is there some top level alias?
269+
var found bool
270+
for _, t := range ts {
271+
if _, ok := t.(*aliases.Alias); ok {
272+
found = true
273+
break
274+
}
275+
}
276+
if !found {
277+
return ts // no top level alias
278+
}
279+
280+
cp := make([]types.Type, len(ts)) // copy with top level aliases removed.
281+
for i, t := range ts {
282+
cp[i] = aliases.Unalias(t)
283+
}
284+
return cp
285+
}
286+
l := unaliasAll(ts)
287+
266288
c.mu.Lock()
267289
defer c.mu.Unlock()
268-
return c.lists.rep(ts)
290+
return c.lists.rep(l)
269291
}
270292

271293
// Type returns a canonical representative of type T.
294+
// Removes top-level aliases.
295+
//
296+
// For performance, reasons the canonical instance is order-dependent,
297+
// and may contain deeply nested aliases.
272298
func (c *canonizer) Type(T types.Type) types.Type {
299+
T = aliases.Unalias(T) // remove the top level alias.
300+
273301
c.mu.Lock()
274302
defer c.mu.Unlock()
275303

0 commit comments

Comments
 (0)