diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2018-08-10 00:20:14 -0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-10 09:20:14 +0200 |
commit | 43f634db8dfac4fb13c8454958d35e776410dac1 (patch) | |
tree | 9cbbddca55b70e5e85daac9bc9edf9381f46c01a /lib | |
parent | 730ce53b71a207edf93abe09c14c150b9c360028 (diff) | |
download | Nim-43f634db8dfac4fb13c8454958d35e776410dac1.tar.gz |
fixes #8519; implements T.distinctBase to reverse T = distinct A (#8531)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/sugar.nim | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim index 258b40191..8ded552d9 100644 --- a/lib/pure/sugar.nim +++ b/lib/pure/sugar.nim @@ -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 |