]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: rename isX predicates to allX, add simple is_X (step...
authorRobert Griesemer <gri@golang.org>
Wed, 3 Nov 2021 00:31:51 +0000 (17:31 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 4 Nov 2021 02:57:37 +0000 (02:57 +0000)
Rename the isX predicates to allX to clearly identify that these
predicates are looking inside type parameters.

Introduce is_X as predicates that do not look
inside type parameters so we can see all call sites.
The next CL will rename them all back to isX.

Review all call sites and use correct predicate.

Replace the single helper function is with isBasic and allBasic.

Change-Id: I3430ccfc466fdedf4b58a6158f95d47b9020f7a5

Change-Id: I81116b87cf8f2e17526723c7440676d133057aca
Reviewed-on: https://go-review.googlesource.com/c/go/+/360955
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/builtins.go
src/cmd/compile/internal/types2/check.go
src/cmd/compile/internal/types2/conversions.go
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/index.go
src/cmd/compile/internal/types2/predicates.go
src/cmd/compile/internal/types2/sizes.go
src/cmd/compile/internal/types2/stmt.go
src/cmd/compile/internal/types2/typexpr.go

index c5c6bdf0a5df1cb71d224a6d7636f4f13bab960d..c92eccf76547ea226fcab1a61ecce70cd39b6d87 100644 (file)
@@ -101,7 +101,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                                if x.mode == invalid {
                                        return
                                }
-                               if isString(x.typ) {
+                               if allString(x.typ) {
                                        if check.Types != nil {
                                                sig := makeSig(S, S, x.typ)
                                                sig.variadic = true
@@ -146,7 +146,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                var val constant.Value
                switch typ = arrayPtrDeref(under(x.typ)); t := typ.(type) {
                case *Basic:
-                       if isString(t) && id == _Len {
+                       if is_String(t) && id == _Len {
                                if x.mode == constant_ {
                                        mode = constant_
                                        val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
@@ -182,7 +182,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                        if t.underIs(func(t Type) bool {
                                switch t := arrayPtrDeref(t).(type) {
                                case *Basic:
-                                       if isString(t) && id == _Len {
+                                       if is_String(t) && id == _Len {
                                                return true
                                        }
                                case *Array, *Slice, *Chan:
@@ -267,7 +267,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                        //    because shifts of floats are not permitted)
                        if x.mode == constant_ && y.mode == constant_ {
                                toFloat := func(x *operand) {
-                                       if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
+                                       if is_Numeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
                                                x.typ = Typ[UntypedFloat]
                                        }
                                }
@@ -398,7 +398,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                        if x.mode == constant_ {
                                // an untyped constant number can always be considered
                                // as a complex constant
-                               if isNumeric(x.typ) {
+                               if is_Numeric(x.typ) {
                                        x.typ = Typ[UntypedComplex]
                                }
                        } else {
@@ -726,7 +726,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                // assert(pred) causes a typechecker error if pred is false.
                // The result of assert is the value of pred if there is no error.
                // Note: assert is only available in self-test mode.
-               if x.mode != constant_ || !isBoolean(x.typ) {
+               if x.mode != constant_ || !is_Boolean(x.typ) {
                        check.errorf(x, invalidArg+"%s is not a boolean constant", x)
                        return
                }
@@ -802,7 +802,7 @@ func structure(typ Type) Type {
 func structureString(typ Type) Type {
        var su Type
        if underIs(typ, func(u Type) bool {
-               if isString(u) {
+               if is_String(u) {
                        u = NewSlice(universeByte)
                }
                if su != nil && !Identical(su, u) {
index ffc59f7011efa7d7cc3245caba3a3c4c5766a86e..f69514e38a0c6e9383048ef99df26eeac2a3d266 100644 (file)
@@ -430,9 +430,9 @@ func (check *Checker) recordTypeAndValue(x syntax.Expr, mode operandMode, typ Ty
        }
        if mode == constant_ {
                assert(val != nil)
-               // We check is(typ, IsConstType) here as constant expressions may be
+               // We check allBasic(typ, IsConstType) here as constant expressions may be
                // recorded as type parameters.
-               assert(typ == Typ[Invalid] || is(typ, IsConstType))
+               assert(typ == Typ[Invalid] || allBasic(typ, IsConstType))
        }
        if m := check.Types; m != nil {
                m[x] = TypeAndValue{mode, typ, val}
@@ -462,7 +462,7 @@ func (check *Checker) recordCommaOkTypes(x syntax.Expr, a [2]Type) {
        if a[0] == nil || a[1] == nil {
                return
        }
-       assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError))
+       assert(isTyped(a[0]) && isTyped(a[1]) && (is_Boolean(a[1]) || a[1] == universeError))
        if m := check.Types; m != nil {
                for {
                        tv := m[x]
index 5798bacca70deb7e8428b116317e460998ef3832..c029f1147d04b041ba5af6b2cfcf2389451510d7 100644 (file)
@@ -22,7 +22,7 @@ func (check *Checker) conversion(x *operand, T Type) {
                        // nothing to do
                case representableConst(x.val, check, t, val):
                        return true
-               case isInteger(x.typ) && isString(t):
+               case is_Integer(x.typ) && is_String(t):
                        codepoint := unicode.ReplacementChar
                        if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune {
                                codepoint = rune(i)
@@ -93,7 +93,7 @@ func (check *Checker) conversion(x *operand, T Type) {
                        // ok
                } else if IsInterface(T) || constArg && !isConstType(T) {
                        final = Default(x.typ)
-               } else if isInteger(x.typ) && isString(T) {
+               } else if is_Integer(x.typ) && allString(T) {
                        final = x.typ
                }
                check.updateExprType(x.expr, final, true)
@@ -197,22 +197,22 @@ func convertibleToImpl(check *Checker, V, T Type, cause *string) bool {
        }
 
        // "V and T are both integer or floating point types"
-       if isIntegerOrFloat(V) && isIntegerOrFloat(T) {
+       if is_IntegerOrFloat(V) && is_IntegerOrFloat(T) {
                return true
        }
 
        // "V and T are both complex types"
-       if isComplex(V) && isComplex(T) {
+       if is_Complex(V) && is_Complex(T) {
                return true
        }
 
        // "V is an integer or a slice of bytes or runes and T is a string type"
-       if (isInteger(V) || isBytesOrRunes(Vu)) && isString(T) {
+       if (is_Integer(V) || isBytesOrRunes(Vu)) && is_String(T) {
                return true
        }
 
        // "V is a string and T is a slice of bytes or runes"
-       if isString(V) && isBytesOrRunes(Tu) {
+       if is_String(V) && isBytesOrRunes(Tu) {
                return true
        }
 
index eb5ec9f3fb0b999753b32807774e610848146653..1db5af00da87501196451c004b481956cd189495 100644 (file)
@@ -63,10 +63,10 @@ var unaryOpPredicates opPredicates
 func init() {
        // Setting unaryOpPredicates in init avoids declaration cycles.
        unaryOpPredicates = opPredicates{
-               syntax.Add: isNumeric,
-               syntax.Sub: isNumeric,
-               syntax.Xor: isInteger,
-               syntax.Not: isBoolean,
+               syntax.Add: allNumeric,
+               syntax.Sub: allNumeric,
+               syntax.Xor: allInteger,
+               syntax.Not: allBoolean,
        }
 }
 
@@ -225,7 +225,7 @@ func (check *Checker) unary(x *operand, e *syntax.Operation) {
                        return
                }
                var prec uint
-               if isUnsigned(x.typ) {
+               if is_Unsigned(x.typ) {
                        prec = uint(check.conf.sizeof(x.typ) * 8)
                }
                x.val = constant.UnaryOp(op2tok[e.Op], x.val, prec)
@@ -302,7 +302,7 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c
        }
 
        switch {
-       case isInteger(typ):
+       case is_Integer(typ):
                x := constant.ToInt(x)
                if x.Kind() != constant.Int {
                        return false
@@ -357,7 +357,7 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c
                        return true
                }
 
-       case isFloat(typ):
+       case is_Float(typ):
                x := constant.ToFloat(x)
                if x.Kind() != constant.Float {
                        return false
@@ -387,7 +387,7 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c
                        unreachable()
                }
 
-       case isComplex(typ):
+       case is_Complex(typ):
                x := constant.ToComplex(x)
                if x.Kind() != constant.Complex {
                        return false
@@ -419,10 +419,10 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c
                        unreachable()
                }
 
-       case isString(typ):
+       case is_String(typ):
                return x.Kind() == constant.String
 
-       case isBoolean(typ):
+       case is_Boolean(typ):
                return x.Kind() == constant.Bool
        }
 
@@ -474,7 +474,7 @@ func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, er
        assert(x.mode == constant_)
        v := x.val
        if !representableConst(x.val, check, typ, &v) {
-               if isNumeric(x.typ) && isNumeric(typ) {
+               if is_Numeric(x.typ) && is_Numeric(typ) {
                        // numeric conversion : error msg
                        //
                        // integer -> integer : overflows
@@ -482,7 +482,7 @@ func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, er
                        // float   -> integer : truncated
                        // float   -> float   : overflows
                        //
-                       if !isInteger(x.typ) && isInteger(typ) {
+                       if !is_Integer(x.typ) && is_Integer(typ) {
                                return nil, _TruncatedFloat
                        } else {
                                return nil, _NumericOverflow
@@ -630,7 +630,7 @@ func (check *Checker) updateExprType(x syntax.Expr, typ Type, final bool) {
                // If x is the lhs of a shift, its final type must be integer.
                // We already know from the shift check that it is representable
                // as an integer if it is a constant.
-               if !isInteger(typ) {
+               if !is_Integer(typ) {
                        check.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
                        return
                }
@@ -692,7 +692,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                // both x and target are untyped
                xkind := x.typ.(*Basic).kind
                tkind := target.(*Basic).kind
-               if isNumeric(x.typ) && isNumeric(target) {
+               if is_Numeric(x.typ) && is_Numeric(target) {
                        if xkind < tkind {
                                return target, nil, 0
                        }
@@ -710,10 +710,10 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                return nil, nil, _InvalidUntypedConversion
        }
 
-       switch t := under(target).(type) {
+       switch u := under(target).(type) {
        case *Basic:
                if x.mode == constant_ {
-                       v, code := check.representation(x, t)
+                       v, code := check.representation(x, u)
                        if code != 0 {
                                return nil, nil, code
                        }
@@ -725,18 +725,18 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                // the value nil.
                switch x.typ.(*Basic).kind {
                case UntypedBool:
-                       if !isBoolean(target) {
+                       if !is_Boolean(target) {
                                return nil, nil, _InvalidUntypedConversion
                        }
                case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
-                       if !isNumeric(target) {
+                       if !is_Numeric(target) {
                                return nil, nil, _InvalidUntypedConversion
                        }
                case UntypedString:
                        // Non-constant untyped string values are not permitted by the spec and
                        // should not occur during normal typechecking passes, but this path is
                        // reachable via the AssignableTo API.
-                       if !isString(target) {
+                       if !is_String(target) {
                                return nil, nil, _InvalidUntypedConversion
                        }
                default:
@@ -744,7 +744,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                }
        case *TypeParam:
                // TODO(gri) review this code - doesn't look quite right
-               ok := t.underIs(func(t Type) bool {
+               ok := u.underIs(func(t Type) bool {
                        target, _, _ := check.implicitTypeAndValue(x, t)
                        return target != nil
                })
@@ -755,7 +755,7 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
                // Update operand types to the default type rather than the target
                // (interface) type: values must have concrete dynamic types.
                // Untyped nil was handled upfront.
-               if !t.Empty() {
+               if !u.Empty() {
                        return nil, nil, _InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
                }
                return Default(x.typ), nil, 0 // default type for nil is nil
@@ -779,7 +779,7 @@ func (check *Checker) comparison(x, y *operand, op syntax.Operator) {
                        defined = Comparable(x.typ) && Comparable(y.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
                case syntax.Lss, syntax.Leq, syntax.Gtr, syntax.Geq:
                        // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
-                       defined = isOrdered(x.typ) && isOrdered(y.typ)
+                       defined = allOrdered(x.typ) && allOrdered(y.typ)
                default:
                        unreachable()
                }
@@ -833,7 +833,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                xval = constant.ToInt(x.val)
        }
 
-       if isInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
+       if allInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
                // The lhs is of integer type or an untyped constant representable
                // as an integer. Nothing to do.
        } else {
@@ -856,7 +856,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                }
        }
 
-       // Caution: Check for isUntyped first because isInteger includes untyped
+       // Caution: Check for isUntyped first because is_Integer includes untyped
        //          integers (was bug #43697).
        if isUntyped(y.typ) {
                check.convertUntyped(y, Typ[Uint])
@@ -864,11 +864,11 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                        x.mode = invalid
                        return
                }
-       } else if !isInteger(y.typ) {
+       } else if !allInteger(y.typ) {
                check.errorf(y, invalidOp+"shift count %s must be integer", y)
                x.mode = invalid
                return
-       } else if !isUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
+       } else if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
                check.errorf(y, invalidOp+"signed shift count %s requires go1.13 or later", y)
                x.mode = invalid
                return
@@ -880,7 +880,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                        if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
                                x.val = constant.MakeUnknown()
                                // ensure the correct type - see comment below
-                               if !isInteger(x.typ) {
+                               if !is_Integer(x.typ) {
                                        x.typ = Typ[UntypedInt]
                                }
                                return
@@ -897,7 +897,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
                        // (e.g., 2.0, an untyped float) - this can only happen for untyped
                        // non-integer numeric constants. Correct the type so that the shift
                        // result is of integer type.
-                       if !isInteger(x.typ) {
+                       if !is_Integer(x.typ) {
                                x.typ = Typ[UntypedInt]
                        }
                        // x is a constant so xval != nil and it must be of Int kind.
@@ -939,7 +939,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
        }
 
        // non-constant shift - lhs must be an integer
-       if !isInteger(x.typ) {
+       if !allInteger(x.typ) {
                check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
                x.mode = invalid
                return
@@ -953,19 +953,19 @@ var binaryOpPredicates opPredicates
 func init() {
        // Setting binaryOpPredicates in init avoids declaration cycles.
        binaryOpPredicates = opPredicates{
-               syntax.Add: isNumericOrString,
-               syntax.Sub: isNumeric,
-               syntax.Mul: isNumeric,
-               syntax.Div: isNumeric,
-               syntax.Rem: isInteger,
+               syntax.Add: allNumericOrString,
+               syntax.Sub: allNumeric,
+               syntax.Mul: allNumeric,
+               syntax.Div: allNumeric,
+               syntax.Rem: allInteger,
 
-               syntax.And:    isInteger,
-               syntax.Or:     isInteger,
-               syntax.Xor:    isInteger,
-               syntax.AndNot: isInteger,
+               syntax.And:    allInteger,
+               syntax.Or:     allInteger,
+               syntax.Xor:    allInteger,
+               syntax.AndNot: allInteger,
 
-               syntax.AndAnd: isBoolean,
-               syntax.OrOr:   isBoolean,
+               syntax.AndAnd: allBoolean,
+               syntax.OrOr:   allBoolean,
        }
 }
 
@@ -995,10 +995,10 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
                if IsInterface(x.typ) || IsInterface(y.typ) {
                        return true
                }
-               if isBoolean(x.typ) != isBoolean(y.typ) {
+               if allBoolean(x.typ) != allBoolean(y.typ) {
                        return false
                }
-               if isString(x.typ) != isString(y.typ) {
+               if allString(x.typ) != allString(y.typ) {
                        return false
                }
                if x.isNil() && !hasNil(y.typ) {
@@ -1047,14 +1047,14 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
 
        if op == syntax.Div || op == syntax.Rem {
                // check for zero divisor
-               if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
+               if (x.mode == constant_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
                        check.error(&y, invalidOp+"division by zero")
                        x.mode = invalid
                        return
                }
 
                // check for divisor underflow in complex division (see issue 20227)
-               if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) {
+               if x.mode == constant_ && y.mode == constant_ && is_Complex(x.typ) {
                        re, im := constant.Real(y.val), constant.Imag(y.val)
                        re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
                        if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
@@ -1074,7 +1074,7 @@ func (check *Checker) binary(x *operand, e syntax.Expr, lhs, rhs syntax.Expr, op
                }
                // force integer division for integer operands
                tok := op2tok[op]
-               if op == syntax.Div && isInteger(x.typ) {
+               if op == syntax.Div && is_Integer(x.typ) {
                        tok = token.QUO_ASSIGN
                }
                x.val = constant.BinaryOp(x.val, tok, y.val)
index bb7033e95784fee80264de19d1090a949fccc4a4..1b080139f3c3724c0cf7b89970dbb952c3bbb20f 100644 (file)
@@ -51,7 +51,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
        length := int64(-1) // valid if >= 0
        switch typ := under(x.typ).(type) {
        case *Basic:
-               if isString(typ) {
+               if is_String(typ) {
                        valid = true
                        if x.mode == constant_ {
                                length = int64(len(constant.StringVal(x.val)))
@@ -109,7 +109,7 @@ func (check *Checker) indexExpr(x *operand, e *syntax.IndexExpr) (isFuncInst boo
                        var k, e Type  // k is only set for maps
                        switch t := u.(type) {
                        case *Basic:
-                               if isString(t) {
+                               if is_String(t) {
                                        e = universeByte
                                        mode = value
                                }
@@ -217,7 +217,7 @@ func (check *Checker) sliceExpr(x *operand, e *syntax.SliceExpr) {
                return
 
        case *Basic:
-               if isString(u) {
+               if is_String(u) {
                        if e.Full {
                                check.error(x, invalidOp+"3-index slice of string")
                                x.mode = invalid
@@ -386,7 +386,7 @@ func (check *Checker) isValidIndex(x *operand, what string, allowNegative bool)
        }
 
        // spec: "the index x must be of integer type or an untyped constant"
-       if !isInteger(x.typ) {
+       if !allInteger(x.typ) {
                check.errorf(x, invalidArg+"%s %s must be integer", what, x)
                return false
        }
index 6d93a8a2273703c63fc0a7f8a83dea4206ba0c17..980d254084f405631a0c20cbc43b6c229832050f 100644 (file)
@@ -25,33 +25,55 @@ func isGeneric(typ Type) bool {
        return named != nil && named.obj != nil && named.targs == nil && named.TypeParams() != nil
 }
 
-func is(typ Type, what BasicInfo) bool {
-       switch t := under(typ).(type) {
+// The is_X predicates below report whether t is an X.
+// If t is a type parameter the result is false; i.e.,
+// these predicates don't look inside a type parameter.
+
+func is_Boolean(t Type) bool        { return isBasic(t, IsBoolean) }
+func is_Integer(t Type) bool        { return isBasic(t, IsInteger) }
+func is_Unsigned(t Type) bool       { return isBasic(t, IsUnsigned) }
+func is_Float(t Type) bool          { return isBasic(t, IsFloat) }
+func is_Complex(t Type) bool        { return isBasic(t, IsComplex) }
+func is_Numeric(t Type) bool        { return isBasic(t, IsNumeric) }
+func is_String(t Type) bool         { return isBasic(t, IsString) }
+func is_IntegerOrFloat(t Type) bool { return isBasic(t, IsInteger|IsFloat) }
+
+// isBasic reports whether under(t) is a basic type with the specified info.
+// If t is a type parameter the result is false; i.e.,
+// isBasic does not look inside a type parameter.
+func isBasic(t Type, info BasicInfo) bool {
+       u, _ := under(t).(*Basic)
+       return u != nil && u.info&info != 0
+}
+
+// The allX predicates below report whether t is an X.
+// If t is a type parameter the result is true if is_X is true
+// for all specified types of the type parameter's type set.
+// allX is an optimized version of is_X(structure(t)) (which
+// is the same as underIs(t, is_X)).
+
+func allBoolean(t Type) bool         { return allBasic(t, IsBoolean) }
+func allInteger(t Type) bool         { return allBasic(t, IsInteger) }
+func allUnsigned(t Type) bool        { return allBasic(t, IsUnsigned) }
+func allNumeric(t Type) bool         { return allBasic(t, IsNumeric) }
+func allString(t Type) bool          { return allBasic(t, IsString) }
+func allOrdered(t Type) bool         { return allBasic(t, IsOrdered) }
+func allNumericOrString(t Type) bool { return allBasic(t, IsNumeric|IsString) }
+
+// allBasic reports whether under(t) is a basic type with the specified info.
+// If t is a type parameter, the result is true if isBasic(t, info) is true
+// for all specific types of the type parameter's type set.
+// allBasic(t, info) is an optimized version of isBasic(structure(t), info).
+func allBasic(t Type, info BasicInfo) bool {
+       switch u := under(t).(type) {
        case *Basic:
-               return t.info&what != 0
+               return u.info&info != 0
        case *TypeParam:
-               return t.underIs(func(t Type) bool { return is(t, what) })
+               return u.is(func(t *term) bool { return t != nil && isBasic(t.typ, info) })
        }
        return false
 }
 
-func isBoolean(typ Type) bool  { return is(typ, IsBoolean) }
-func isInteger(typ Type) bool  { return is(typ, IsInteger) }
-func isUnsigned(typ Type) bool { return is(typ, IsUnsigned) }
-func isFloat(typ Type) bool    { return is(typ, IsFloat) }
-func isComplex(typ Type) bool  { return is(typ, IsComplex) }
-func isNumeric(typ Type) bool  { return is(typ, IsNumeric) }
-func isString(typ Type) bool   { return is(typ, IsString) }
-
-// Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
-// produce the expected result because a type set that contains both an integer
-// and a floating-point type is neither (all) integers, nor (all) floats.
-// Use isIntegerOrFloat instead.
-func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }
-
-// isNumericOrString is the equivalent of isIntegerOrFloat for isNumeric(typ) || isString(typ).
-func isNumericOrString(typ Type) bool { return is(typ, IsNumeric|IsString) }
-
 // isTyped reports whether typ is typed; i.e., not an untyped
 // constant or boolean. isTyped may be called with types that
 // are not fully set up.
@@ -67,8 +89,6 @@ func isUntyped(typ Type) bool {
        return !isTyped(typ)
 }
 
-func isOrdered(typ Type) bool { return is(typ, IsOrdered) }
-
 func isConstType(typ Type) bool {
        // Type parameters are never const types.
        t := asBasic(typ)
index 6a3d19d8eaf293971266e4424ab57e97698092b1..8f93ca6b872305953829e52949ec8de8363f54ec 100644 (file)
@@ -82,7 +82,7 @@ func (s *StdSizes) Alignof(T Type) int64 {
                return 1
        }
        // complex{64,128} are aligned like [2]float{32,64}.
-       if isComplex(T) {
+       if is_Complex(T) {
                a /= 2
        }
        if a > s.MaxAlign {
index dd2100f7110da55fa831fa686cf43f32f7e337b6..b8b53a868e6e4f4903109d561af2154d9fc7bda0 100644 (file)
@@ -443,7 +443,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
                        if x.mode == invalid {
                                return
                        }
-                       if !isNumeric(x.typ) {
+                       if !allNumeric(x.typ) {
                                check.errorf(lhs[0], invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
                                return
                        }
@@ -556,7 +556,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
                check.simpleStmt(s.Init)
                var x operand
                check.expr(&x, s.Cond)
-               if x.mode != invalid && !isBoolean(x.typ) {
+               if x.mode != invalid && !allBoolean(x.typ) {
                        check.error(s.Cond, "non-boolean condition in if statement")
                }
                check.stmt(inner, s.Then)
@@ -645,7 +645,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
                if s.Cond != nil {
                        var x operand
                        check.expr(&x, s.Cond)
-                       if x.mode != invalid && !isBoolean(x.typ) {
+                       if x.mode != invalid && !allBoolean(x.typ) {
                                check.error(s.Cond, "non-boolean condition in for statement")
                        }
                }
@@ -942,7 +942,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
 func rangeKeyVal(typ Type) (key, val Type) {
        switch typ := arrayPtrDeref(typ).(type) {
        case *Basic:
-               if isString(typ) {
+               if is_String(typ) {
                        return Typ[Int], universeRune // use 'rune' name
                }
        case *Array:
index 95893fd1e1d50afb8ac9f5c453c87fd9e7096d08..70071769800d67aaa327562ad55b5a7f2c04b24b 100644 (file)
@@ -513,7 +513,7 @@ func (check *Checker) arrayLength(e syntax.Expr) int64 {
                return -1
        }
 
-       if isUntyped(x.typ) || isInteger(x.typ) {
+       if isUntyped(x.typ) || is_Integer(x.typ) {
                if val := constant.ToInt(x.val); val.Kind() == constant.Int {
                        if representableConst(val, check, Typ[Int], nil) {
                                if n, ok := constant.Int64Val(val); ok && n >= 0 {