Skip to content

Commit

Permalink
Add optional recursive arg to distinctBase (v2) (nim-lang#18659)
Browse files Browse the repository at this point in the history
* Add optional recursive arg to distinctBase
* Add docs and examples

Co-authored-by: ALANVF <alan.invents@gmail.com>
  • Loading branch information
2 people authored and PMunch committed Mar 28, 2022
1 parent 980a2df commit d3b7812
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 10 deletions.
5 changes: 3 additions & 2 deletions compiler/semmagic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,10 @@ 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})
let rec = semConstExpr(c, traitCall[2]).intVal != 0
while arg.kind == tyDistinct:
arg = arg.base
arg = arg.skipTypes(skippedTypes + {tyGenericInst})
arg = arg.base.skipTypes(skippedTypes + {tyGenericInst})
if not rec: break
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.
## 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) is 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

0 comments on commit d3b7812

Please sign in to comment.