Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[superseded] Add optional recursive argument to typetraits.distinctBase #18654

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion compiler/semmagic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,20 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
result = newIntNodeT(toInt128(operand.len), traitCall, c.idgen, c.graph)
of "distinctBase":
var arg = operand.skipTypes({tyGenericInst})
while arg.kind == tyDistinct:
let rec =
if traitCall.len >= 2:
traitCall[2].intVal != 0
else:
true

if arg.kind == tyDistinct:
arg = arg.base
arg = arg.skipTypes(skippedTypes + {tyGenericInst})
if rec:
while arg.kind == tyDistinct:
arg = arg.base
arg = arg.skipTypes(skippedTypes + {tyGenericInst})

result = getTypeDescNode(c, arg, operand.owner, traitCall.info)
else:
localError(c.config, traitCall.info, "unknown trait: " & s)
Expand Down
17 changes: 12 additions & 5 deletions lib/pure/typetraits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,25 +110,32 @@ template pointerBase*[T](_: typedesc[ptr T | ref T]): typedesc =
assert (var s = "abc"; s[0].addr).typeof.pointerBase is char
T

proc distinctBase*(T: typedesc): typedesc {.magic: "TypeTrait".} =
proc distinctBase*(T: typedesc, recursive: static bool = true): typedesc {.magic: "TypeTrait".} =
## Returns the base type for distinct types, or the type itself otherwise.
ALANVF marked this conversation as resolved.
Show resolved Hide resolved
## If `recursive` is false, only the immediate distinct base will be returned.
##
## **See also:**
## * `distinctBase template <#distinctBase.t,T>`_
## * `distinctBase template <#distinctBase.t,T,static[bool]>`_
runnableExamples:
type MyInt = distinct int
type MyOtherInt = distinct MyInt
doAssert distinctBase(MyInt) is int
doAssert distinctBase(MyOtherInt) is int
doAssert distinctBase(MyOtherInt, false) is MyInt
doAssert distinctBase(int) is int

since (1, 1):
template distinctBase*[T](a: T): untyped =
## Overload of `distinctBase <#distinctBase,typedesc>`_ for values.
template distinctBase*[T](a: T, recursive: static bool = true): untyped =
## Overload of `distinctBase <#distinctBase,typedesc,static[bool]>`_ for values.
runnableExamples:
type MyInt = distinct int
type MyOtherInt = distinct MyInt
doAssert 12.MyInt.distinctBase == 12
doAssert 12.MyOtherInt.distinctBase == 12
doAssert 12.MyOtherInt.distinctBase(false) == 12.MyInt
doAssert 12.distinctBase == 12
when T is distinct:
distinctBase(typeof(a))(a)
distinctBase(typeof(a), recursive)(a)
else: # avoids hint ConvFromXtoItselfNotNeeded
a

Expand Down
4 changes: 2 additions & 2 deletions lib/std/jsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ proc initToJsonOptions*(): ToJsonOptions =
## initializes `ToJsonOptions` with sane options.
ToJsonOptions(enumMode: joptEnumOrd, jsonNodeMode: joptJsonNodeAsRef)

proc distinctBase(T: typedesc): typedesc {.magic: "TypeTrait".}
template distinctBase[T](a: T): untyped = distinctBase(typeof(a))(a)
proc distinctBase(T: typedesc, recursive: static bool = true): typedesc {.magic: "TypeTrait".}
template distinctBase[T](a: T, recursive: static bool = true): untyped = distinctBase(typeof(a), recursive)(a)

macro getDiscriminants(a: typedesc): seq[string] =
## return the discriminant keys
Expand Down
2 changes: 1 addition & 1 deletion lib/system/repr_v2.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".}
## imported from typetraits

proc distinctBase(T: typedesc): typedesc {.magic: "TypeTrait".}
proc distinctBase(T: typedesc, recursive: static bool = true): typedesc {.magic: "TypeTrait".}
## imported from typetraits

proc repr*(x: NimNode): string {.magic: "Repr", noSideEffect.}
Expand Down