Skip to content

Commit 1b796a9

Browse files
timothy-kinggopherbot
authored andcommitted
go/ssa: removing termList type
This is cleanup to remove the internal termList type. Some additional minor refactoring so underIs takes a Type instead of a list of terms. Change-Id: I934b16bbf94f1d62762a5622a85ceea22f1c2108 Reviewed-on: https://go-review.googlesource.com/c/tools/+/641835 Auto-Submit: Tim King <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 6efe0f4 commit 1b796a9

File tree

5 files changed

+39
-43
lines changed

5 files changed

+39
-43
lines changed

go/ssa/builder.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
856856
if recv, ok := types.Unalias(sel.recv).(*types.TypeParam); ok {
857857
// Emit a nil check if any possible instantiation of the
858858
// type parameter is an interface type.
859-
if typeSetOf(recv).Len() > 0 {
859+
if len(typeSetOf(recv)) > 0 {
860860
// recv has a concrete term its typeset.
861861
// So it cannot be instantiated as an interface.
862862
//

go/ssa/const.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func soleTypeKind(typ types.Type) types.BasicInfo {
4545
// Candidates (perhaps all) are eliminated during the type-set
4646
// iteration, which executes at least once.
4747
state := types.IsBoolean | types.IsInteger | types.IsString
48-
underIs(typeSetOf(typ), func(ut types.Type) bool {
48+
underIs(typ, func(ut types.Type) bool {
4949
var c types.BasicInfo
5050
if t, ok := ut.(*types.Basic); ok {
5151
c = t.Info()
@@ -126,7 +126,7 @@ func (c *Const) IsNil() bool {
126126
// nillable reports whether *new(T) == nil is legal for type T.
127127
func nillable(t types.Type) bool {
128128
if typeparams.IsTypeParam(t) {
129-
return underIs(typeSetOf(t), func(u types.Type) bool {
129+
return underIs(t, func(u types.Type) bool {
130130
// empty type set (u==nil) => any underlying types => not nillable
131131
return u != nil && nillable(u)
132132
})

go/ssa/coretype.go

+27-32
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,24 @@ func isBytestring(T types.Type) bool {
2222
return false
2323
}
2424

25-
tset := typeSetOf(U)
26-
if tset.Len() != 2 {
27-
return false
28-
}
2925
hasBytes, hasString := false, false
30-
underIs(tset, func(t types.Type) bool {
26+
ok := underIs(U, func(t types.Type) bool {
3127
switch {
3228
case isString(t):
3329
hasString = true
30+
return true
3431
case isByteSlice(t):
3532
hasBytes = true
33+
return true
34+
default:
35+
return false
3636
}
37-
return hasBytes || hasString
3837
})
39-
return hasBytes && hasString
38+
return ok && hasBytes && hasString
4039
}
4140

42-
// termList is a list of types.
43-
type termList []*types.Term // type terms of the type set
44-
func (s termList) Len() int { return len(s) }
45-
func (s termList) At(i int) types.Type { return s[i].Type() }
46-
47-
// typeSetOf returns the type set of typ. Returns an empty typeset on an error.
48-
func typeSetOf(typ types.Type) termList {
41+
// typeSetOf returns the type set of typ as a normalized term set. Returns an empty set on an error.
42+
func typeSetOf(typ types.Type) []*types.Term {
4943
// This is a adaptation of x/exp/typeparams.NormalTerms which x/tools cannot depend on.
5044
var terms []*types.Term
5145
var err error
@@ -65,20 +59,21 @@ func typeSetOf(typ types.Type) termList {
6559
}
6660

6761
if err != nil {
68-
return termList(nil)
62+
return nil
6963
}
70-
return termList(terms)
64+
return terms
7165
}
7266

73-
// underIs calls f with the underlying types of the specific type terms
74-
// of s and reports whether all calls to f returned true. If there are
75-
// no specific terms, underIs returns the result of f(nil).
76-
func underIs(s termList, f func(types.Type) bool) bool {
77-
if s.Len() == 0 {
67+
// underIs calls f with the underlying types of the type terms
68+
// of the type set of typ and reports whether all calls to f returned true.
69+
// If there are no specific terms, underIs returns the result of f(nil).
70+
func underIs(typ types.Type, f func(types.Type) bool) bool {
71+
s := typeSetOf(typ)
72+
if len(s) == 0 {
7873
return f(nil)
7974
}
80-
for i := 0; i < s.Len(); i++ {
81-
u := s.At(i).Underlying()
75+
for _, t := range s {
76+
u := t.Type().Underlying()
8277
if !f(u) {
8378
return false
8479
}
@@ -87,7 +82,7 @@ func underIs(s termList, f func(types.Type) bool) bool {
8782
}
8883

8984
// indexType returns the element type and index mode of a IndexExpr over a type.
90-
// It returns (nil, invalid) if the type is not indexable; this should never occur in a well-typed program.
85+
// It returns an invalid mode if the type is not indexable; this should never occur in a well-typed program.
9186
func indexType(typ types.Type) (types.Type, indexMode) {
9287
switch U := typ.Underlying().(type) {
9388
case *types.Array:
@@ -104,22 +99,22 @@ func indexType(typ types.Type) (types.Type, indexMode) {
10499
return tByte, ixValue // must be a string
105100
case *types.Interface:
106101
tset := typeSetOf(U)
107-
if tset.Len() == 0 {
102+
if len(tset) == 0 {
108103
return nil, ixInvalid // no underlying terms or error is empty.
109104
}
110-
111-
elem, mode := indexType(tset.At(0))
112-
for i := 1; i < tset.Len() && mode != ixInvalid; i++ {
113-
e, m := indexType(tset.At(i))
105+
elem, mode := indexType(tset[0].Type())
106+
for _, t := range tset[1:] {
107+
e, m := indexType(t.Type())
114108
if !types.Identical(elem, e) { // if type checked, just a sanity check
115109
return nil, ixInvalid
116110
}
117111
// Update the mode to the most constrained address type.
118112
mode = mode.meet(m)
113+
if mode == ixInvalid {
114+
return nil, ixInvalid // fast exit
115+
}
119116
}
120-
if mode != ixInvalid {
121-
return elem, mode
122-
}
117+
return elem, mode
123118
}
124119
return nil, ixInvalid
125120
}

go/ssa/sanity.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ func (s *sanity) checkInstr(idx int, instr Instruction) {
142142
case *ChangeType:
143143
case *SliceToArrayPointer:
144144
case *Convert:
145-
if from := instr.X.Type(); !isBasicConvTypes(typeSetOf(from)) {
146-
if to := instr.Type(); !isBasicConvTypes(typeSetOf(to)) {
145+
if from := instr.X.Type(); !isBasicConvTypes(from) {
146+
if to := instr.Type(); !isBasicConvTypes(to) {
147147
s.errorf("convert %s -> %s: at least one type must be basic (or all basic, []byte, or []rune)", from, to)
148148
}
149149
}

go/ssa/util.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,22 @@ func isRuneSlice(t types.Type) bool {
8585
return false
8686
}
8787

88-
// isBasicConvTypes returns true when a type set can be
89-
// one side of a Convert operation. This is when:
88+
// isBasicConvTypes returns true when the type set of a type
89+
// can be one side of a Convert operation. This is when:
9090
// - All are basic, []byte, or []rune.
9191
// - At least 1 is basic.
9292
// - At most 1 is []byte or []rune.
93-
func isBasicConvTypes(tset termList) bool {
94-
basics := 0
95-
all := underIs(tset, func(t types.Type) bool {
93+
func isBasicConvTypes(typ types.Type) bool {
94+
basics, cnt := 0, 0
95+
ok := underIs(typ, func(t types.Type) bool {
96+
cnt++
9697
if isBasic(t) {
9798
basics++
9899
return true
99100
}
100101
return isByteSlice(t) || isRuneSlice(t)
101102
})
102-
return all && basics >= 1 && tset.Len()-basics <= 1
103+
return ok && basics >= 1 && cnt-basics <= 1
103104
}
104105

105106
// isPointer reports whether t's underlying type is a pointer.

0 commit comments

Comments
 (0)