summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-07-12 18:08:45 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-07-12 18:08:45 +0200
commit3163a0f46649bcb54e181b055bb32cc7bfec98df (patch)
tree161aa84e431eaf1df2dc0b75b207fe6aee90521d /compiler
parent3fec2ba5e5a29402aeb1bbb0d160deb85a93ffd1 (diff)
downloadNim-3163a0f46649bcb54e181b055bb32cc7bfec98df.tar.gz
Do not consider enums with holes as ordinals (#8264)
Make the compiler behave consistently with respect to what's written in
the manual.

Fixes #1239
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semmagic.nim2
-rw-r--r--compiler/types.nim14
2 files changed, 8 insertions, 8 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index 1975fb77b..b5875c67a 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -171,7 +171,7 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
 proc semOrd(c: PContext, n: PNode): PNode =
   result = n
   let parType = n.sons[1].typ
-  if isOrdinalType(parType):
+  if isOrdinalType(parType, allowEnumWithHoles=true):
     discard
   elif parType.kind == tySet:
     result.typ = makeRangeType(c, firstOrd(c.config, parType), lastOrd(c.config, parType), n.info)
diff --git a/compiler/types.nim b/compiler/types.nim
index 4d3f99c31..4180d34a7 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -133,18 +133,18 @@ proc elemType*(t: PType): PType =
   else: result = t.lastSon
   assert(result != nil)
 
-proc isOrdinalType*(t: PType): bool =
+proc enumHasHoles*(t: PType): bool =
+  var b = t.skipTypes({tyRange, tyGenericInst, tyAlias, tySink})
+  result = b.kind == tyEnum and tfEnumHasHoles in b.flags
+
+proc isOrdinalType*(t: PType, allowEnumWithHoles = false): bool =
   assert(t != nil)
   const
     # caution: uint, uint64 are no ordinal types!
     baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
     parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tySink, tyDistinct}
-  t.kind in baseKinds or (t.kind in parentKinds and isOrdinalType(t.sons[0]))
-
-proc enumHasHoles*(t: PType): bool =
-  var b = t
-  while b.kind in {tyRange, tyGenericInst, tyAlias, tySink}: b = b.sons[0]
-  result = b.kind == tyEnum and tfEnumHasHoles in b.flags
+  (t.kind in baseKinds and not (t.enumHasHoles and not allowEnumWithHoles)) or
+    (t.kind in parentKinds and isOrdinalType(t.lastSon))
 
 proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
                      closure: RootRef): bool