mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-16 08:04:20 +00:00
This commit is contained in:
committed by
Andreas Rumpf
parent
730ce53b71
commit
43f634db8d
@@ -1673,7 +1673,8 @@ A ``distinct`` type is new type derived from a `base type`:idx: that is
|
||||
incompatible with its base type. In particular, it is an essential property
|
||||
of a distinct type that it **does not** imply a subtype relation between it
|
||||
and its base type. Explicit type conversions from a distinct type to its
|
||||
base type and vice versa are allowed.
|
||||
base type and vice versa are allowed. See also ``distinctBase`` to get the
|
||||
reverse operation.
|
||||
|
||||
|
||||
Modelling currencies
|
||||
|
||||
@@ -198,3 +198,41 @@ macro dump*(x: typed): untyped =
|
||||
let r = quote do:
|
||||
debugEcho `s`, " = ", `x`
|
||||
return r
|
||||
|
||||
# TODO: consider exporting this in macros.nim
|
||||
proc freshIdentNodes(ast: NimNode): NimNode =
|
||||
# Replace NimIdent and NimSym by a fresh ident node
|
||||
# see also https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
|
||||
proc inspect(node: NimNode): NimNode =
|
||||
case node.kind:
|
||||
of nnkIdent, nnkSym:
|
||||
result = ident($node)
|
||||
of nnkEmpty, nnkLiterals:
|
||||
result = node
|
||||
else:
|
||||
result = node.kind.newTree()
|
||||
for child in node:
|
||||
result.add inspect(child)
|
||||
result = inspect(ast)
|
||||
|
||||
macro distinctBase*(T: typedesc): untyped =
|
||||
## reverses ``type T = distinct A``; works recursively.
|
||||
runnableExamples:
|
||||
type T = distinct int
|
||||
doAssert distinctBase(T) is int
|
||||
doAssert: not compiles(distinctBase(int))
|
||||
type T2 = distinct T
|
||||
doAssert distinctBase(T2) is int
|
||||
|
||||
let typeNode = getTypeImpl(T)
|
||||
expectKind(typeNode, nnkBracketExpr)
|
||||
if typeNode[0].typeKind != ntyTypeDesc:
|
||||
error "expected typeDesc, got " & $typeNode[0]
|
||||
var typeSym = typeNode[1]
|
||||
typeSym = getTypeImpl(typeSym)
|
||||
if typeSym.typeKind != ntyDistinct:
|
||||
error "type is not distinct"
|
||||
typeSym = typeSym[0]
|
||||
while typeSym.typeKind == ntyDistinct:
|
||||
typeSym = getTypeImpl(typeSym)[0]
|
||||
typeSym.freshIdentNodes
|
||||
|
||||
29
tests/stdlib/tsugar.nim
Normal file
29
tests/stdlib/tsugar.nim
Normal file
@@ -0,0 +1,29 @@
|
||||
discard """
|
||||
file: "tsugar.nim"
|
||||
output: ""
|
||||
"""
|
||||
import sugar
|
||||
import macros
|
||||
|
||||
block distinctBase:
|
||||
block:
|
||||
type
|
||||
Foo[T] = distinct seq[T]
|
||||
var a: Foo[int]
|
||||
doAssert a.type.distinctBase is seq[int]
|
||||
|
||||
block:
|
||||
# simplified from https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
|
||||
macro uintImpl(bits: static[int]): untyped =
|
||||
if bits >= 128:
|
||||
let inner = getAST(uintImpl(bits div 2))
|
||||
result = newTree(nnkBracketExpr, ident("UintImpl"), inner)
|
||||
else:
|
||||
result = ident("uint64")
|
||||
|
||||
type
|
||||
BaseUint = UintImpl or SomeUnsignedInt
|
||||
UintImpl[Baseuint] = object
|
||||
Uint[bits: static[int]] = distinct uintImpl(bits)
|
||||
|
||||
doAssert Uint[128].distinctBase is UintImpl[uint64]
|
||||
Reference in New Issue
Block a user