From 1bddb66b7c6bd32eae3bcbf8ae9eb51398166ea9 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 13 Sep 2019 22:18:19 -0700 Subject: [PATCH] go/types: more operators supported by contracts Change-Id: I03493508813d13dd1a16cd675de68170da14b29f --- src/go/types/predicates.go | 57 ++++++++--------------------- src/go/types/testdata/contracts.go2 | 21 +++++++++-- 2 files changed, 34 insertions(+), 44 deletions(-) diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go index f4e332d07a..5f5e14f75d 100644 --- a/src/go/types/predicates.go +++ b/src/go/types/predicates.go @@ -16,40 +16,23 @@ func isNamed(typ Type) bool { return ok } -func isBoolean(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsBoolean != 0 +func is(typ Type, what BasicInfo) bool { + switch t := typ.Underlying().(type) { + case *Basic: + return t.info&what != 0 + case *TypeParam: + return t.contr.ifaceAt(t.index).is(func(typ Type) bool { return is(typ, what) }) + } + return false } -func isInteger(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsInteger != 0 -} - -func isUnsigned(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsUnsigned != 0 -} - -func isFloat(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsFloat != 0 -} - -func isComplex(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsComplex != 0 -} - -func isNumeric(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsNumeric != 0 -} - -func isString(typ Type) bool { - t, ok := typ.Underlying().(*Basic) - return ok && t.info&IsString != 0 -} +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) } func isTyped(typ Type) bool { t, ok := typ.Underlying().(*Basic) @@ -61,15 +44,7 @@ func isUntyped(typ Type) bool { return ok && t.info&IsUntyped != 0 } -func isOrdered(typ Type) bool { - switch t := typ.Underlying().(type) { - case *Basic: - return t.info&IsOrdered != 0 - case *TypeParam: - return t.contr.ifaceAt(t.index).is(isOrdered) - } - return false -} +func isOrdered(typ Type) bool { return is(typ, IsOrdered) } func isConstType(typ Type) bool { t, ok := typ.Underlying().(*Basic) diff --git a/src/go/types/testdata/contracts.go2 b/src/go/types/testdata/contracts.go2 index ed19849031..ef128e1115 100644 --- a/src/go/types/testdata/contracts.go2 +++ b/src/go/types/testdata/contracts.go2 @@ -119,13 +119,28 @@ var _ T2(struct{x int}) // Use of contracts in parameterized functions -contract SignedInteger(T) { - T int8, int16, int32, int64, int +contract Ordered(T) { + T int8, int16, int32, int64, int, + uint8, uint16, uint32, uint64, uint, + float32, float64, string, rune } -func min(type T SignedInteger)(x, y T) T { +func min(type T Ordered)(x, y T) T { if x < y { return x } return y +} + +contract Integer(T) { + T int8, int16, int32, int64, int, + uint8, uint16, uint32, uint64, uint +} + +func sum(type T Integer)(data []T) T { + var s T + for _, x := range data { + s += x + } + return s } \ No newline at end of file