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
This commit is contained in:
parent
3fec2ba5e5
commit
3163a0f466
3 changed files with 11 additions and 11 deletions
|
|
@ -171,7 +171,7 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
|
||||||
proc semOrd(c: PContext, n: PNode): PNode =
|
proc semOrd(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
let parType = n.sons[1].typ
|
let parType = n.sons[1].typ
|
||||||
if isOrdinalType(parType):
|
if isOrdinalType(parType, allowEnumWithHoles=true):
|
||||||
discard
|
discard
|
||||||
elif parType.kind == tySet:
|
elif parType.kind == tySet:
|
||||||
result.typ = makeRangeType(c, firstOrd(c.config, parType), lastOrd(c.config, parType), n.info)
|
result.typ = makeRangeType(c, firstOrd(c.config, parType), lastOrd(c.config, parType), n.info)
|
||||||
|
|
|
||||||
|
|
@ -133,18 +133,18 @@ proc elemType*(t: PType): PType =
|
||||||
else: result = t.lastSon
|
else: result = t.lastSon
|
||||||
assert(result != nil)
|
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)
|
assert(t != nil)
|
||||||
const
|
const
|
||||||
# caution: uint, uint64 are no ordinal types!
|
# caution: uint, uint64 are no ordinal types!
|
||||||
baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
|
baseKinds = {tyChar,tyInt..tyInt64,tyUInt8..tyUInt32,tyBool,tyEnum}
|
||||||
parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tySink, tyDistinct}
|
parentKinds = {tyRange, tyOrdinal, tyGenericInst, tyAlias, tySink, tyDistinct}
|
||||||
t.kind in baseKinds or (t.kind in parentKinds and isOrdinalType(t.sons[0]))
|
(t.kind in baseKinds and not (t.enumHasHoles and not allowEnumWithHoles)) or
|
||||||
|
(t.kind in parentKinds and isOrdinalType(t.lastSon))
|
||||||
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
|
|
||||||
|
|
||||||
proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
|
proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
|
||||||
closure: RootRef): bool
|
closure: RootRef): bool
|
||||||
|
|
|
||||||
|
|
@ -263,14 +263,14 @@ proc high*[T: Ordinal](x: T): T {.magic: "High", noSideEffect.}
|
||||||
## high(2) #=> 9223372036854775807
|
## high(2) #=> 9223372036854775807
|
||||||
## high(int) #=> 9223372036854775807
|
## high(int) #=> 9223372036854775807
|
||||||
|
|
||||||
proc high*[T: Ordinal](x: typeDesc[T]): T {.magic: "High", noSideEffect.}
|
proc high*[T: Ordinal|enum](x: typeDesc[T]): T {.magic: "High", noSideEffect.}
|
||||||
proc high*[T](x: openArray[T]): int {.magic: "High", noSideEffect.}
|
proc high*[T](x: openArray[T]): int {.magic: "High", noSideEffect.}
|
||||||
proc high*[I, T](x: array[I, T]): I {.magic: "High", noSideEffect.}
|
proc high*[I, T](x: array[I, T]): I {.magic: "High", noSideEffect.}
|
||||||
proc high*[I, T](x: typeDesc[array[I, T]]): I {.magic: "High", noSideEffect.}
|
proc high*[I, T](x: typeDesc[array[I, T]]): I {.magic: "High", noSideEffect.}
|
||||||
proc high*(x: cstring): int {.magic: "High", noSideEffect.}
|
proc high*(x: cstring): int {.magic: "High", noSideEffect.}
|
||||||
proc high*(x: string): int {.magic: "High", noSideEffect.}
|
proc high*(x: string): int {.magic: "High", noSideEffect.}
|
||||||
|
|
||||||
proc low*[T: Ordinal](x: typeDesc[T]): T {.magic: "Low", noSideEffect.}
|
proc low*[T: Ordinal|enum](x: typeDesc[T]): T {.magic: "Low", noSideEffect.}
|
||||||
proc low*[T](x: openArray[T]): int {.magic: "Low", noSideEffect.}
|
proc low*[T](x: openArray[T]): int {.magic: "Low", noSideEffect.}
|
||||||
proc low*[I, T](x: array[I, T]): I {.magic: "Low", noSideEffect.}
|
proc low*[I, T](x: array[I, T]): I {.magic: "Low", noSideEffect.}
|
||||||
proc low*[T](x: T): T {.magic: "Low", noSideEffect.}
|
proc low*[T](x: T): T {.magic: "Low", noSideEffect.}
|
||||||
|
|
@ -792,7 +792,7 @@ proc card*[T](x: set[T]): int {.magic: "Card", noSideEffect.}
|
||||||
## var i = {1,2,3,4}
|
## var i = {1,2,3,4}
|
||||||
## card(i) #=> 4
|
## card(i) #=> 4
|
||||||
|
|
||||||
proc ord*[T](x: T): int {.magic: "Ord", noSideEffect.}
|
proc ord*[T: Ordinal|enum](x: T): int {.magic: "Ord", noSideEffect.}
|
||||||
## returns the internal int value of an ordinal value ``x``.
|
## returns the internal int value of an ordinal value ``x``.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue