ungeneric unsigned ops (#12230)

* ungenericise unsigned ops, remove nimNewShiftOps
* fix/remove tests
* update t6448
* fix line info
* disable on 32bit
* fix different line info
* add changelog entry
This commit is contained in:
Jasper Jenkins 2019-10-10 23:38:08 -07:00 • committed by Andreas Rumpf
commit 245a954b25
8 changed files with 149 additions and 97 deletions

View file

@ -30,6 +30,7 @@
## Language changes ## Language changes
- Unsigned integer operators have been fixed to allow promotion of the first operand.
### Tool changes ### Tool changes

View file

@ -53,7 +53,6 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimKnowsNimvm") defineSymbol("nimKnowsNimvm")
defineSymbol("nimArrIdx") defineSymbol("nimArrIdx")
defineSymbol("nimHasalignOf") defineSymbol("nimHasalignOf")
defineSymbol("nimNewShiftOps")
defineSymbol("nimDistros") defineSymbol("nimDistros")
defineSymbol("nimHasCppDefine") defineSymbol("nimHasCppDefine")
defineSymbol("nimGenericInOutFlags") defineSymbol("nimGenericInOutFlags")

View file

@ -1323,8 +1323,6 @@ proc `mod`*(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.} proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.} proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
when defined(nimNewShiftOps):
when defined(nimOldShiftRight) or not defined(nimAshr): when defined(nimOldShiftRight) or not defined(nimAshr):
const shrDepMessage = "`shr` will become sign preserving." const shrDepMessage = "`shr` will become sign preserving."
proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.} proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
@ -1370,18 +1368,6 @@ when defined(nimNewShiftOps):
proc `shl`*(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.} proc `shl`*(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.} proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.} proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
else:
proc `shr`*(x, y: int): int {.magic: "ShrI", noSideEffect.}
proc `shr`*(x, y: int8): int8 {.magic: "ShrI", noSideEffect.}
proc `shr`*(x, y: int16): int16 {.magic: "ShrI", noSideEffect.}
proc `shr`*(x, y: int32): int32 {.magic: "ShrI", noSideEffect.}
proc `shr`*(x, y: int64): int64 {.magic: "ShrI", noSideEffect.}
proc `shl`*(x, y: int): int {.magic: "ShlI", noSideEffect.}
proc `shl`*(x, y: int8): int8 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x, y: int16): int16 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x, y: int32): int32 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x, y: int64): int64 {.magic: "ShlI", noSideEffect.}
when defined(nimAshr): when defined(nimAshr):
proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.}
@ -1518,54 +1504,105 @@ template `>%`*(x, y: untyped): untyped = y <% x
# unsigned integer operations: # unsigned integer operations:
proc `not`*[T: SomeUnsignedInt](x: T): T {.magic: "BitnotI", noSideEffect.} proc `not`*(x: uint): uint {.magic: "BitnotI", noSideEffect.}
## Computes the `bitwise complement` of the integer `x`. ## Computes the `bitwise complement` of the integer `x`.
proc `not`*(x: uint8): uint8 {.magic: "BitnotI", noSideEffect.}
proc `not`*(x: uint16): uint16 {.magic: "BitnotI", noSideEffect.}
proc `not`*(x: uint32): uint32 {.magic: "BitnotI", noSideEffect.}
proc `not`*(x: uint64): uint64 {.magic: "BitnotI", noSideEffect.}
when defined(nimNewShiftOps): proc `shr`*(x: uint, y: SomeInteger): uint {.magic: "ShrI", noSideEffect.}
proc `shr`*[T: SomeUnsignedInt](x: T, y: SomeInteger): T {.magic: "ShrI", noSideEffect.}
## Computes the `shift right` operation of `x` and `y`. ## Computes the `shift right` operation of `x` and `y`.
proc `shl`*[T: SomeUnsignedInt](x: T, y: SomeInteger): T {.magic: "ShlI", noSideEffect.} proc `shr`*(x: uint8, y: SomeInteger): uint8 {.magic: "ShrI", noSideEffect.}
## Computes the `shift left` operation of `x` and `y`. proc `shr`*(x: uint16, y: SomeInteger): uint16 {.magic: "ShrI", noSideEffect.}
else: proc `shr`*(x: uint32, y: SomeInteger): uint32 {.magic: "ShrI", noSideEffect.}
proc `shr`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShrI", noSideEffect.} proc `shr`*(x: uint64, y: SomeInteger): uint64 {.magic: "ShrI", noSideEffect.}
## Computes the `shift right` operation of `x` and `y`.
proc `shl`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ShlI", noSideEffect.}
## Computes the `shift left` operation of `x` and `y`.
proc `and`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitandI", noSideEffect.} proc `shl`*(x: uint, y: SomeInteger): uint {.magic: "ShlI", noSideEffect.}
## Computes the `shift left` operation of `x` and `y`.
proc `shl`*(x: uint8, y: SomeInteger): uint8 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x: uint16, y: SomeInteger): uint16 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x: uint32, y: SomeInteger): uint32 {.magic: "ShlI", noSideEffect.}
proc `shl`*(x: uint64, y: SomeInteger): uint64 {.magic: "ShlI", noSideEffect.}
proc `and`*(x, y: uint): uint {.magic: "BitandI", noSideEffect.}
## Computes the `bitwise and` of numbers `x` and `y`. ## Computes the `bitwise and` of numbers `x` and `y`.
proc `and`*(x, y: uint8): uint8 {.magic: "BitandI", noSideEffect.}
proc `and`*(x, y: uint16): uint16 {.magic: "BitandI", noSideEffect.}
proc `and`*(x, y: uint32): uint32 {.magic: "BitandI", noSideEffect.}
proc `and`*(x, y: uint64): uint64 {.magic: "BitandI", noSideEffect.}
proc `or`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitorI", noSideEffect.} proc `or`*(x, y: uint): uint {.magic: "BitorI", noSideEffect.}
## Computes the `bitwise or` of numbers `x` and `y`. ## Computes the `bitwise or` of numbers `x` and `y`.
proc `or`*(x, y: uint8): uint8 {.magic: "BitorI", noSideEffect.}
proc `or`*(x, y: uint16): uint16 {.magic: "BitorI", noSideEffect.}
proc `or`*(x, y: uint32): uint32 {.magic: "BitorI", noSideEffect.}
proc `or`*(x, y: uint64): uint64 {.magic: "BitorI", noSideEffect.}
proc `xor`*[T: SomeUnsignedInt](x, y: T): T {.magic: "BitxorI", noSideEffect.} proc `xor`*(x, y: uint): uint {.magic: "BitxorI", noSideEffect.}
## Computes the `bitwise xor` of numbers `x` and `y`. ## Computes the `bitwise xor` of numbers `x` and `y`.
proc `xor`*(x, y: uint8): uint8 {.magic: "BitxorI", noSideEffect.}
proc `xor`*(x, y: uint16): uint16 {.magic: "BitxorI", noSideEffect.}
proc `xor`*(x, y: uint32): uint32 {.magic: "BitxorI", noSideEffect.}
proc `xor`*(x, y: uint64): uint64 {.magic: "BitxorI", noSideEffect.}
proc `==`*[T: SomeUnsignedInt](x, y: T): bool {.magic: "EqI", noSideEffect.} proc `==`*(x, y: uint): bool {.magic: "EqI", noSideEffect.}
## Compares two unsigned integers for equality. ## Compares two unsigned integers for equality.
proc `==`*(x, y: uint8): bool {.magic: "EqI", noSideEffect.}
proc `==`*(x, y: uint16): bool {.magic: "EqI", noSideEffect.}
proc `==`*(x, y: uint32): bool {.magic: "EqI", noSideEffect.}
proc `==`*(x, y: uint64): bool {.magic: "EqI", noSideEffect.}
proc `+`*[T: SomeUnsignedInt](x, y: T): T {.magic: "AddU", noSideEffect.} proc `+`*(x, y: uint): uint {.magic: "AddU", noSideEffect.}
## Binary `+` operator for unsigned integers. ## Binary `+` operator for unsigned integers.
proc `+`*(x, y: uint8): uint8 {.magic: "AddU", noSideEffect.}
proc `+`*(x, y: uint16): uint16 {.magic: "AddU", noSideEffect.}
proc `+`*(x, y: uint32): uint32 {.magic: "AddU", noSideEffect.}
proc `+`*(x, y: uint64): uint64 {.magic: "AddU", noSideEffect.}
proc `-`*[T: SomeUnsignedInt](x, y: T): T {.magic: "SubU", noSideEffect.} proc `-`*(x, y: uint): uint {.magic: "SubU", noSideEffect.}
## Binary `-` operator for unsigned integers. ## Binary `-` operator for unsigned integers.
proc `-`*(x, y: uint8): uint8 {.magic: "SubU", noSideEffect.}
proc `-`*(x, y: uint16): uint16 {.magic: "SubU", noSideEffect.}
proc `-`*(x, y: uint32): uint32 {.magic: "SubU", noSideEffect.}
proc `-`*(x, y: uint64): uint64 {.magic: "SubU", noSideEffect.}
proc `*`*[T: SomeUnsignedInt](x, y: T): T {.magic: "MulU", noSideEffect.} proc `*`*(x, y: uint): uint {.magic: "MulU", noSideEffect.}
## Binary `*` operator for unsigned integers. ## Binary `*` operator for unsigned integers.
proc `*`*(x, y: uint8): uint8 {.magic: "MulU", noSideEffect.}
proc `*`*(x, y: uint16): uint16 {.magic: "MulU", noSideEffect.}
proc `*`*(x, y: uint32): uint32 {.magic: "MulU", noSideEffect.}
proc `*`*(x, y: uint64): uint64 {.magic: "MulU", noSideEffect.}
proc `div`*[T: SomeUnsignedInt](x, y: T): T {.magic: "DivU", noSideEffect.} proc `div`*(x, y: uint): uint {.magic: "DivU", noSideEffect.}
## Computes the integer division for unsigned integers. ## Computes the integer division for unsigned integers.
## This is roughly the same as ``trunc(x/y)``. ## This is roughly the same as ``trunc(x/y)``.
proc `div`*(x, y: uint8): uint8 {.magic: "DivU", noSideEffect.}
proc `div`*(x, y: uint16): uint16 {.magic: "DivU", noSideEffect.}
proc `div`*(x, y: uint32): uint32 {.magic: "DivU", noSideEffect.}
proc `div`*(x, y: uint64): uint64 {.magic: "DivU", noSideEffect.}
proc `mod`*[T: SomeUnsignedInt](x, y: T): T {.magic: "ModU", noSideEffect.} proc `mod`*(x, y: uint): uint {.magic: "ModU", noSideEffect.}
## Computes the integer modulo operation (remainder) for unsigned integers. ## Computes the integer modulo operation (remainder) for unsigned integers.
## This is the same as ``x - (x div y) * y``. ## This is the same as ``x - (x div y) * y``.
proc `mod`*(x, y: uint8): uint8 {.magic: "ModU", noSideEffect.}
proc `mod`*(x, y: uint16): uint16 {.magic: "ModU", noSideEffect.}
proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
proc `<=`*[T: SomeUnsignedInt](x, y: T): bool {.magic: "LeU", noSideEffect.} proc `<=`*(x, y: uint): bool {.magic: "LeU", noSideEffect.}
## Returns true if ``x <= y``. ## Returns true if ``x <= y``.
proc `<=`*(x, y: uint8): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint16): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint32): bool {.magic: "LeU", noSideEffect.}
proc `<=`*(x, y: uint64): bool {.magic: "LeU", noSideEffect.}
proc `<`*[T: SomeUnsignedInt](x, y: T): bool {.magic: "LtU", noSideEffect.} proc `<`*(x, y: uint): bool {.magic: "LtU", noSideEffect.}
## Returns true if ``unsigned(x) < unsigned(y)``. ## Returns true if ``unsigned(x) < unsigned(y)``.
proc `<`*(x, y: uint8): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint16): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint32): bool {.magic: "LtU", noSideEffect.}
proc `<`*(x, y: uint64): bool {.magic: "LtU", noSideEffect.}
# floating point operations: # floating point operations:
proc `+`*(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect.} proc `+`*(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect.}

View file

@ -4,6 +4,14 @@ int32
int32 int32
1280 1280
1280 1280
3
1
2
2
3
4294967295
2
0
''' '''
""" """
@ -145,3 +153,17 @@ block tsubrange:
level = min(level + 2, maxLevel).n16 level = min(level + 2, maxLevel).n16
doAssert level == 1 doAssert level == 1
block tissue12177:
var a: uint16 = 1
var b: uint32 = 2
echo(b + a)
echo(b - a)
echo(b * a)
echo(b div a)
echo(a + b)
echo(a - b)
echo(a * b)
echo(a div b)

View file

@ -9,23 +9,23 @@ proc test(foo: Foo[int])
required type for foo: Foo[int] required type for foo: Foo[int]
but expression 'bar' is of type: Bar[system.int] but expression 'bar' is of type: Bar[system.int]
t3330.nim(63, 8) Hint: Non-matching candidates for add(k, string, T) t3330.nim(63, 8) Hint: Non-matching candidates for add(k, string, T)
proc add[T](x: var seq[T]; y: openArray[T])
first type mismatch at position: 1
required type for x: var seq[T]
but expression 'k' is of type: Alias
proc add[T](x: var seq[T]; y: T) proc add[T](x: var seq[T]; y: T)
first type mismatch at position: 1 first type mismatch at position: 1
required type for x: var seq[T] required type for x: var seq[T]
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: string)
first type mismatch at position: 1
required type for x: var string
but expression 'k' is of type: Alias
proc add(result: var string; x: float) proc add(result: var string; x: float)
first type mismatch at position: 1 first type mismatch at position: 1
required type for result: var string required type for result: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: cstring) proc add(x: var string; y: char)
first type mismatch at position: 1 first type mismatch at position: 1
required type for x: var string required type for x: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: string) proc add(x: var string; y: cstring)
first type mismatch at position: 1 first type mismatch at position: 1
required type for x: var string required type for x: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
@ -33,9 +33,9 @@ proc add(result: var string; x: int64)
first type mismatch at position: 1 first type mismatch at position: 1
required type for result: var string required type for result: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: char) proc add[T](x: var seq[T]; y: openArray[T])
first type mismatch at position: 1 first type mismatch at position: 1
required type for x: var string required type for x: var seq[T]
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
t3330.nim(63, 8) template/generic instantiation of `add` from here t3330.nim(63, 8) template/generic instantiation of `add` from here

View file

@ -4,14 +4,14 @@ line: 22
nimout: ''' nimout: '''
twrong_at_operator.nim(22, 30) Error: type mismatch: got <array[0..0, type int]> twrong_at_operator.nim(22, 30) Error: type mismatch: got <array[0..0, type int]>
but expected one of: but expected one of:
proc `@`[T](a: openArray[T]): seq[T]
first type mismatch at position: 1
required type for a: openArray[T]
but expression '[int]' is of type: array[0..0, type int]
proc `@`[IDX, T](a: sink array[IDX, T]): seq[T] proc `@`[IDX, T](a: sink array[IDX, T]): seq[T]
first type mismatch at position: 1 first type mismatch at position: 1
required type for a: sink array[IDX, T] required type for a: sink array[IDX, T]
but expression '[int]' is of type: array[0..0, type int] but expression '[int]' is of type: array[0..0, type int]
proc `@`[T](a: openArray[T]): seq[T]
first type mismatch at position: 1
required type for a: openArray[T]
but expression '[int]' is of type: array[0..0, type int]
expression: @[int] expression: @[int]
''' '''

View file

@ -762,11 +762,3 @@ block t3717:
var f: Foo[Foo[int]] var f: Foo[Foo[int]]
discard foo(f) discard foo(f)
block t5707:
proc foo[T]: seq[int] =
return lc[x | (x <- 1..10, x mod 2 == 0), int]
doAssert foo[float32]() == @[2, 4, 6, 8, 10]

View file

@ -1,6 +1,7 @@
discard """ discard """
errormsg: '''ambiguous call; both foobar.async''' errormsg: '''ambiguous call; both foobar.async'''
line: 9 line: 10
disabled: "32bit"
""" """
import foobar import foobar