Skip to content

Commit 7c50ef6

Browse files
committed
go/types: remove asTypeParam and simplify some code
This is a port of CL 363438 from types2 to go/types. Change-Id: I87c76d31b398b9ce406f96b0030ee458619b3dbe Reviewed-on: https://go-review.googlesource.com/c/go/+/364235 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 f041c7e commit 7c50ef6

File tree

13 files changed

+33
-54
lines changed

13 files changed

+33
-54
lines changed

src/go/types/builtins.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
298298
// the argument types must be of floating-point type
299299
// (applyTypeFunc never calls f with a type parameter)
300300
f := func(typ Type) Type {
301-
assert(asTypeParam(typ) == nil)
301+
assert(!isTypeParam(typ))
302302
if t, _ := under(typ).(*Basic); t != nil {
303303
switch t.kind {
304304
case Float32:
@@ -441,7 +441,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
441441
// the argument must be of complex type
442442
// (applyTypeFunc never calls f with a type parameter)
443443
f := func(typ Type) Type {
444-
assert(asTypeParam(typ) == nil)
444+
assert(!isTypeParam(typ))
445445
if t, _ := under(typ).(*Basic); t != nil {
446446
switch t.kind {
447447
case Complex64:
@@ -822,7 +822,7 @@ func hasVarSize(t Type) bool {
822822
// applyTypeFunc returns nil.
823823
// If x is not a type parameter, the result is f(x).
824824
func (check *Checker) applyTypeFunc(f func(Type) Type, x Type) Type {
825-
if tp := asTypeParam(x); tp != nil {
825+
if tp, _ := x.(*TypeParam); tp != nil {
826826
// Test if t satisfies the requirements for the argument
827827
// type and collect possible result types at the same time.
828828
var terms []*Term

src/go/types/call.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
531531
check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
532532
default:
533533
var why string
534-
if tpar := asTypeParam(x.typ); tpar != nil {
534+
if tpar, _ := x.typ.(*TypeParam); tpar != nil {
535535
// Type parameter bounds don't specify fields, so don't mention "field".
536536
if tname := tpar.iface().obj; tname != nil {
537537
why = check.sprintf("interface %s has no method %s", tname.name, sel)

src/go/types/conversions.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (check *Checker) conversion(x *operand, T Type) {
4747
// If T's type set is empty, or if it doesn't
4848
// have specific types, constant x cannot be
4949
// converted.
50-
ok = under(T).(*TypeParam).underIs(func(u Type) bool {
50+
ok = T.(*TypeParam).underIs(func(u Type) bool {
5151
// t is nil if there are no specific type terms
5252
if u == nil {
5353
cause = check.sprintf("%s does not contain specific types", T)
@@ -186,8 +186,8 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
186186
}
187187

188188
// optimization: if we don't have type parameters, we're done
189-
Vp, _ := Vu.(*TypeParam)
190-
Tp, _ := Tu.(*TypeParam)
189+
Vp, _ := V.(*TypeParam)
190+
Tp, _ := T.(*TypeParam)
191191
if Vp == nil && Tp == nil {
192192
return false
193193
}

src/go/types/decl.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,11 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
669669
}
670670

671671
// Disallow a lone type parameter as the RHS of a type declaration (issue #45639).
672-
// We can look directly at named.underlying because even if it is still a *Named
673-
// type (underlying not fully resolved yet) it cannot become a type parameter due
674-
// to this very restriction.
675-
if tpar, _ := named.underlying.(*TypeParam); tpar != nil {
672+
// We don't need this restriction anymore if we make the underlying type of a type
673+
// parameter its constraint interface: if the RHS is a lone type parameter, we will
674+
// use its underlying type (like we do for any RHS in a type declaration), and its
675+
// underlying type is an interface and the type declaration is well defined.
676+
if isTypeParam(rhs) {
676677
check.error(tdecl.Type, _MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
677678
named.underlying = Typ[Invalid]
678679
}
@@ -723,7 +724,7 @@ func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList
723724

724725
check.later(func() {
725726
for i, bound := range bounds {
726-
if _, ok := under(bound).(*TypeParam); ok {
727+
if isTypeParam(bound) {
727728
check.error(posns[i], _MisplacedTypeParam, "cannot use a type parameter as constraint")
728729
}
729730
}

src/go/types/expr.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,10 @@ var op2str2 = [...]string{
147147
// If typ is a type parameter, underIs returns the result of typ.underIs(f).
148148
// Otherwise, underIs returns the result of f(under(typ)).
149149
func underIs(typ Type, f func(Type) bool) bool {
150-
u := under(typ)
151-
if tpar, _ := u.(*TypeParam); tpar != nil {
150+
if tpar, _ := typ.(*TypeParam); tpar != nil {
152151
return tpar.underIs(f)
153152
}
154-
return f(u)
153+
return f(under(typ))
155154
}
156155

157156
// The unary expression e may be nil. It's passed in for better error messages only.

src/go/types/instantiate.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (check *Checker) satisfies(pos token.Pos, targ Type, tpar *TypeParam, smap
157157

158158
// A type argument that is a type parameter with an empty type set satisfies any constraint.
159159
// (The empty set is a subset of any set.)
160-
if targ := asTypeParam(targ); targ != nil && targ.iface().typeSet().IsEmpty() {
160+
if targ, _ := targ.(*TypeParam); targ != nil && targ.iface().typeSet().IsEmpty() {
161161
return nil
162162
}
163163

@@ -186,7 +186,7 @@ func (check *Checker) satisfies(pos token.Pos, targ Type, tpar *TypeParam, smap
186186
// if iface is comparable, targ must be comparable
187187
// TODO(gri) the error messages needs to be better, here
188188
if iface.IsComparable() && !Comparable(targ) {
189-
if tpar := asTypeParam(targ); tpar != nil && tpar.iface().typeSet().IsAll() {
189+
if tpar, _ := targ.(*TypeParam); tpar != nil && tpar.iface().typeSet().IsAll() {
190190
return errorf("%s has no constraints", targ)
191191
}
192192
return errorf("%s does not satisfy comparable", targ)
@@ -198,7 +198,7 @@ func (check *Checker) satisfies(pos token.Pos, targ Type, tpar *TypeParam, smap
198198
// If the type argument is a pointer to a type parameter, the type argument's
199199
// method set is empty.
200200
// TODO(gri) is this what we want? (spec question)
201-
if base, isPtr := deref(targ); isPtr && asTypeParam(base) != nil {
201+
if base, isPtr := deref(targ); isPtr && isTypeParam(base) {
202202
return errorf("%s has no methods", targ)
203203
}
204204
if m, wrong := check.missingMethod(targ, iface, true); m != nil {
@@ -227,7 +227,7 @@ func (check *Checker) satisfies(pos token.Pos, targ Type, tpar *TypeParam, smap
227227
// If targ is itself a type parameter, each of its possible types must be in the set
228228
// of iface types (i.e., the targ type set must be a subset of the iface type set).
229229
// Type arguments with empty type sets were already excluded above.
230-
if targ := asTypeParam(targ); targ != nil {
230+
if targ, _ := targ.(*TypeParam); targ != nil {
231231
targBound := targ.iface()
232232
if !targBound.typeSet().subsetOf(iface.typeSet()) {
233233
// TODO(gri) report which type is missing

src/go/types/lookup.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,8 @@ func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
134134
continue // we can't have a matching field or interface method
135135
}
136136

137-
// continue with underlying type, but only if it's not a type parameter
138-
// TODO(gri) is this what we want to do for type parameters? (spec question)
139-
// TODO(#45639) the error message produced as a result of skipping an
140-
// underlying type parameter should be improved.
137+
// continue with underlying type
141138
typ = named.under()
142-
if asTypeParam(typ) != nil {
143-
continue
144-
}
145139
}
146140

147141
tpar = nil

src/go/types/operand.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func operandString(x *operand, qf Qualifier) string {
166166
}
167167
buf.WriteString(intro)
168168
WriteType(&buf, x.typ, qf)
169-
if tpar := asTypeParam(x.typ); tpar != nil {
169+
if tpar, _ := x.typ.(*TypeParam); tpar != nil {
170170
buf.WriteString(" constrained by ")
171171
WriteType(&buf, tpar.bound, qf) // do not compute interface type sets here
172172
}
@@ -241,8 +241,8 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, er
241241

242242
Vu := under(V)
243243
Tu := under(T)
244-
Vp, _ := Vu.(*TypeParam)
245-
Tp, _ := Tu.(*TypeParam)
244+
Vp, _ := V.(*TypeParam)
245+
Tp, _ := T.(*TypeParam)
246246

247247
// x is an untyped value representable by a value of type T.
248248
if isUntyped(Vu) {

src/go/types/predicates.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func IsInterface(t Type) bool {
9292

9393
// isTypeParam reports whether t is a type parameter.
9494
func isTypeParam(t Type) bool {
95-
_, ok := under(t).(*TypeParam)
95+
_, ok := t.(*TypeParam)
9696
return ok
9797
}
9898

src/go/types/type.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,3 @@ func asNamed(t Type) *Named {
8888
}
8989
return e
9090
}
91-
92-
// If t is a type parameter, asTypeParam returns that type, otherwise it returns nil.
93-
func asTypeParam(t Type) *TypeParam {
94-
u, _ := under(t).(*TypeParam)
95-
return u
96-
}

src/go/types/typeset.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,6 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
289289
continue // ignore invalid unions
290290
}
291291
terms = tset.terms
292-
case *TypeParam:
293-
// Embedding stand-alone type parameters is not permitted.
294-
// Union parsing reports a (delayed) error, so we can ignore this entry.
295-
continue
296292
default:
297293
if u == Typ[Invalid] {
298294
continue
@@ -370,10 +366,6 @@ func computeUnionTypeSet(check *Checker, pos token.Pos, utyp *Union) *_TypeSet {
370366
switch u := under(t.typ).(type) {
371367
case *Interface:
372368
terms = computeInterfaceTypeSet(check, pos, u).terms
373-
case *TypeParam:
374-
// A stand-alone type parameters is not permitted as union term.
375-
// Union parsing reports a (delayed) error, so we can ignore this entry.
376-
continue
377369
default:
378370
if t.typ == Typ[Invalid] {
379371
continue

src/go/types/typexpr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
337337
check.later(func() {
338338
if !Comparable(typ.key) {
339339
var why string
340-
if asTypeParam(typ.key) != nil {
340+
if isTypeParam(typ.key) {
341341
why = " (missing comparable constraint)"
342342
}
343343
check.errorf(e.Key, _IncomparableMapKey, "incomparable map key type %s%s", typ.key, why)

src/go/types/union.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,14 @@ func parseTilde(check *Checker, x ast.Expr) (tilde bool, typ Type) {
118118
}
119119
typ = check.typ(x)
120120
// Embedding stand-alone type parameters is not permitted (issue #47127).
121-
// Do this check later because it requires computation of the underlying type (see also issue #46461).
122-
// Note: If an underlying type cannot be a type parameter, the call to
123-
// under() will not be needed and then we don't need to delay this
124-
// check to later and could return Typ[Invalid] instead.
125-
check.later(func() {
126-
if _, ok := under(typ).(*TypeParam); ok {
127-
check.error(x, _MisplacedTypeParam, "cannot embed a type parameter")
128-
}
129-
})
121+
// We don't need this restriction anymore if we make the underlying type of a type
122+
// parameter its constraint interface: if we embed a lone type parameter, we will
123+
// simply use its underlying type (like we do for other named, embedded interfaces),
124+
// and since the underlying type is an interface the embedding is well defined.
125+
if isTypeParam(typ) {
126+
check.error(x, _MisplacedTypeParam, "cannot embed a type parameter")
127+
typ = Typ[Invalid]
128+
}
130129
return
131130
}
132131

0 commit comments

Comments
 (0)