Skip to content

Commit 05ca41d

Browse files
griesemergopherbot
authored andcommitted
go/types, types2: factor out maximum type computation
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>
1 parent 445e520 commit 05ca41d

File tree

4 files changed

+48
-18
lines changed

4 files changed

+48
-18
lines changed

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -688,19 +688,14 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
688688
if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
689689
return x.typ, nil, 0
690690
}
691+
// x is untyped
691692

692693
if isUntyped(target) {
693694
// both x and target are untyped
694-
xkind := x.typ.(*Basic).kind
695-
tkind := target.(*Basic).kind
696-
if isNumeric(x.typ) && isNumeric(target) {
697-
if xkind < tkind {
698-
return target, nil, 0
699-
}
700-
} else if xkind != tkind {
701-
return nil, nil, InvalidUntypedConversion
695+
if m := maxType(x.typ, target); m != nil {
696+
return m, nil, 0
702697
}
703-
return x.typ, nil, 0
698+
return nil, nil, InvalidUntypedConversion
704699
}
705700

706701
if x.isNil() {

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,23 @@ func Default(t Type) Type {
510510
}
511511
return t
512512
}
513+
514+
// maxType returns the "largest" type that encompasses both x and y.
515+
// If x and y are different untyped numeric types, the result is the type of x or y
516+
// that appears later in this list: integer, rune, floating-point, complex.
517+
// Otherwise, if x != y, the result is nil.
518+
func maxType(x, y Type) Type {
519+
// We only care about untyped types (for now), so == is good enough.
520+
// TODO(gri) investigate generalizing this function to simplify code elsewhere
521+
if x == y {
522+
return x
523+
}
524+
if isUntyped(x) && isUntyped(y) && isNumeric(x) && isNumeric(y) {
525+
// untyped types are basic types
526+
if x.(*Basic).kind > y.(*Basic).kind {
527+
return x
528+
}
529+
return y
530+
}
531+
return nil
532+
}

src/go/types/expr.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -652,19 +652,14 @@ func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, const
652652
if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
653653
return x.typ, nil, 0
654654
}
655+
// x is untyped
655656

656657
if isUntyped(target) {
657658
// both x and target are untyped
658-
xkind := x.typ.(*Basic).kind
659-
tkind := target.(*Basic).kind
660-
if isNumeric(x.typ) && isNumeric(target) {
661-
if xkind < tkind {
662-
return target, nil, 0
663-
}
664-
} else if xkind != tkind {
665-
return nil, nil, InvalidUntypedConversion
659+
if m := maxType(x.typ, target); m != nil {
660+
return m, nil, 0
666661
}
667-
return x.typ, nil, 0
662+
return nil, nil, InvalidUntypedConversion
668663
}
669664

670665
switch u := under(target).(type) {

src/go/types/predicates.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)