summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/condsyms.nim1
-rw-r--r--lib/pure/hashes.nim2
-rw-r--r--lib/system.nim12
-rw-r--r--lib/system/arithmetics.nim4
-rw-r--r--lib/system/basic_types.nim6
-rw-r--r--tests/system/tsystem_misc.nim17
-rw-r--r--tests/varres/tprevent_forloopvar_mutations.nim4
7 files changed, 36 insertions, 10 deletions
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 344f6fd5a..d82f4811d 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -104,6 +104,7 @@ proc initDefines*(symbols: StringTableRef) =
   defineSymbol("nimHasCursor")
   defineSymbol("nimHasExceptionsQuery")
   defineSymbol("nimHasIsNamedTuple")
+  defineSymbol("nimHashOrdinalFixed")
 
   when defined(nimHasLibFFI):
     # Renaming as we can't conflate input vs output define flags; e.g. this
diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim
index b55a7865d..52a724d7b 100644
--- a/lib/pure/hashes.nim
+++ b/lib/pure/hashes.nim
@@ -112,7 +112,7 @@ proc hash*[T: proc](x: T): Hash {.inline.} =
   else:
     result = hash(pointer(x))
 
-proc hash*(x: int|int64|uint|uint64|char|Ordinal): Hash {.inline.} =
+proc hash*[T: Ordinal](x: T): Hash {.inline.} =
   ## Efficient hashing of integers.
   cast[Hash](ord(x))
 
diff --git a/lib/system.nim b/lib/system.nim
index 69083673b..51ff3af40 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -87,6 +87,18 @@ proc defined*(x: untyped): bool {.magic: "Defined", noSideEffect, compileTime.}
   ##     # Do here programmer friendly expensive sanity checks.
   ##   # Put here the normal code
 
+when defined(nimHashOrdinalFixed):
+  type
+    Ordinal*[T] {.magic: Ordinal.} ## Generic ordinal type. Includes integer,
+                                   ## bool, character, and enumeration types
+                                   ## as well as their subtypes. See also
+                                   ## `SomeOrdinal`.
+else:
+  # bootstrap <= 0.20.0
+  type
+    OrdinalImpl[T] {.magic: Ordinal.}
+    Ordinal* = OrdinalImpl | uint | uint64
+
 when defined(nimHasRunnableExamples):
   proc runnableExamples*(body: untyped) {.magic: "RunnableExamples".}
     ## A section you should use to mark `runnable example`:idx: code with.
diff --git a/lib/system/arithmetics.nim b/lib/system/arithmetics.nim
index ba9ade192..757a813e8 100644
--- a/lib/system/arithmetics.nim
+++ b/lib/system/arithmetics.nim
@@ -22,7 +22,7 @@ proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.}
   ##   echo pred(5)    # => 4
   ##   echo pred(5, 3) # => 2
 
-proc inc*[T: Ordinal|uint|uint64](x: var T, y = 1) {.magic: "Inc", noSideEffect.}
+proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.}
   ## Increments the ordinal ``x`` by ``y``.
   ##
   ## If such a value does not exist, ``OverflowError`` is raised or a compile
@@ -33,7 +33,7 @@ proc inc*[T: Ordinal|uint|uint64](x: var T, y = 1) {.magic: "Inc", noSideEffect.
   ##  inc(i)    # i <- 3
   ##  inc(i, 3) # i <- 6
 
-proc dec*[T: Ordinal|uint|uint64](x: var T, y = 1) {.magic: "Dec", noSideEffect.}
+proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.}
   ## Decrements the ordinal ``x`` by ``y``.
   ##
   ## If such a value does not exist, ``OverflowError`` is raised or a compile
diff --git a/lib/system/basic_types.nim b/lib/system/basic_types.nim
index 39ad0a76c..a6bf69ebc 100644
--- a/lib/system/basic_types.nim
+++ b/lib/system/basic_types.nim
@@ -20,10 +20,6 @@ const
   off* = false  ## Alias for ``false``.
 
 type
-  Ordinal*[T] {.magic: Ordinal.} ## Generic ordinal type. Includes integer,
-                                 ## bool, character, and enumeration types
-                                 ## as well as their subtypes.
-
   SomeSignedInt* = int|int8|int16|int32|int64
     ## Type class matching all signed integer types.
 
@@ -35,7 +31,7 @@ type
 
   SomeOrdinal* = int|int8|int16|int32|int64|bool|enum|uint|uint8|uint16|uint32|uint64
     ## Type class matching all ordinal types; however this includes enums with
-    ## holes.
+    ## holes. See also `Ordinal`
 
   BiggestInt* = int64
     ## is an alias for the biggest signed integer type the Nim compiler
diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim
index 56af97f36..fff8b7022 100644
--- a/tests/system/tsystem_misc.nim
+++ b/tests/system/tsystem_misc.nim
@@ -193,3 +193,20 @@ block:
     a = {k1}
     b = {k1,k2}
   doAssert a < b
+
+
+block: # Ordinal
+  doAssert int is Ordinal
+  doAssert uint is Ordinal
+  doAssert int64 is Ordinal
+  doAssert uint64 is Ordinal
+  doAssert char is Ordinal
+  type Foo = enum k1, k2
+  doAssert Foo is Ordinal
+  doAssert Foo is SomeOrdinal
+  doAssert enum is SomeOrdinal
+
+  # these fail:
+  # doAssert enum is Ordinal # fails
+  # doAssert Ordinal is SomeOrdinal
+  # doAssert SomeOrdinal is Ordinal
diff --git a/tests/varres/tprevent_forloopvar_mutations.nim b/tests/varres/tprevent_forloopvar_mutations.nim
index 398191658..ac62608af 100644
--- a/tests/varres/tprevent_forloopvar_mutations.nim
+++ b/tests/varres/tprevent_forloopvar_mutations.nim
@@ -3,9 +3,9 @@ discard """
   line: 17
   nimout: '''type mismatch: got <int>
 but expected one of:
-proc inc[T: Ordinal | uint | uint64](x: var T; y = 1)
+proc inc[T: Ordinal](x: var T; y = 1)
   first type mismatch at position: 1
-  required type for x: var T: Ordinal or uint or uint64
+  required type for x: var T: Ordinal
   but expression 'i' is immutable, not 'var'
 
 expression: inc i