]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types, types2: factor out maximum type computation
authorRobert Griesemer <gri@golang.org>
Thu, 4 May 2023 21:09:27 +0000 (14:09 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 5 May 2023 22:31:54 +0000 (22:31 +0000)
For untyped constant binary operations we need to determine the
"maximum" (untyped) type which includes both constant types.
Factor out this functionality.

Change-Id: If42bd793d38423322885a3063a4321bd56443b36
Reviewed-on: https://go-review.googlesource.com/c/go/+/492619
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/predicates.go
src/go/types/expr.go
src/go/types/predicates.go

index 19e3b9bc98c6b54d39fd698cc1b6427226d27d8b..c4e8a4696c03e5b8588b03e71e013ffd188ab715 100644 (file)
@@ -688,19 +688,14 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
        if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
                return x.typ, nil, 0
        }
+       // x is untyped
 
        if isUntyped(target) {
                // both x and target are untyped
-               xkind := x.typ.(*Basic).kind
-               tkind := target.(*Basic).kind
-               if isNumeric(x.typ) && isNumeric(target) {
-                       if xkind < tkind {
-                               return target, nil, 0
-                       }
-               } else if xkind != tkind {
-                       return nil, nil, InvalidUntypedConversion
+               if m := maxType(x.typ, target); m != nil {
+                       return m, nil, 0
                }
-               return x.typ, nil, 0
+               return nil, nil, InvalidUntypedConversion
        }
 
        if x.isNil() {
index 4f8441467e5c90cfba1fc27af1fd2945362f7a03..13a3bf8af5b5b43fd42f83abbc43a2ea3134c711 100644 (file)
@@ -510,3 +510,23 @@ func Default(t Type) Type {
        }
        return t
 }
+
+// maxType returns the "largest" type that encompasses both x and y.
+// If x and y are different untyped numeric types, the result is the type of x or y
+// that appears later in this list: integer, rune, floating-point, complex.
+// Otherwise, if x != y, the result is nil.
+func maxType(x, y Type) Type {
+       // We only care about untyped types (for now), so == is good enough.
+       // TODO(gri) investigate generalizing this function to simplify code elsewhere
+       if x == y {
+               return x
+       }
+       if isUntyped(x) && isUntyped(y) && isNumeric(x) && isNumeric(y) {
+               // untyped types are basic types
+               if x.(*Basic).kind > y.(*Basic).kind {
+                       return x
+               }
+               return y
+       }
+       return nil
+}
index 27f3c45ac62225f1e8ce0a2ba635c2d96a5290c4..2923d9eb36097d7780fbc1f26e316d00eda940d7 100644 (file)
@@ -652,19 +652,14 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
        if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
                return x.typ, nil, 0
        }
+       // x is untyped
 
        if isUntyped(target) {
                // both x and target are untyped
-               xkind := x.typ.(*Basic).kind
-               tkind := target.(*Basic).kind
-               if isNumeric(x.typ) && isNumeric(target) {
-                       if xkind < tkind {
-                               return target, nil, 0
-                       }
-               } else if xkind != tkind {
-                       return nil, nil, InvalidUntypedConversion
+               if m := maxType(x.typ, target); m != nil {
+                       return m, nil, 0
                }
-               return x.typ, nil, 0
+               return nil, nil, InvalidUntypedConversion
        }
 
        switch u := under(target).(type) {
index e09e774f2a74bca1764993e217cf61c04a0dcebc..b821b584c151156634dad0a2633139e9f2cf35ed 100644 (file)
@@ -512,3 +512,23 @@ func Default(t Type) Type {
        }
        return t
 }
+
+// maxType returns the "largest" type that encompasses both x and y.
+// If x and y are different untyped numeric types, the result is the type of x or y
+// that appears later in this list: integer, rune, floating-point, complex.
+// Otherwise, if x != y, the result is nil.
+func maxType(x, y Type) Type {
+       // We only care about untyped types (for now), so == is good enough.
+       // TODO(gri) investigate generalizing this function to simplify code elsewhere
+       if x == y {
+               return x
+       }
+       if isUntyped(x) && isUntyped(y) && isNumeric(x) && isNumeric(y) {
+               // untyped types are basic types
+               if x.(*Basic).kind > y.(*Basic).kind {
+                       return x
+               }
+               return y
+       }
+       return nil
+}