diff options
-rw-r--r-- | compiler/vmdeps.nim | 7 | ||||
-rw-r--r-- | tests/macros/tgettypeinst.nim | 65 | ||||
-rw-r--r-- | web/news/e031_version_0_16_2.rst | 2 |
3 files changed, 55 insertions, 19 deletions
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 8c7388643..b2b1ec92b 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -175,7 +175,12 @@ proc mapTypeToAstX(t: PType; info: TLineInfo; result.add mapTypeToAst(t.sons[i], info) else: result = mapTypeToAstX(t.lastSon, info, inst, allowRecursion) - of tyGenericBody, tyOrdinal: + of tyGenericBody: + if inst: + result = mapTypeToAstX(t.lastSon, info, inst, true) + else: + result = mapTypeToAst(t.lastSon, info) + of tyOrdinal: result = mapTypeToAst(t.lastSon, info) of tyDistinct: if inst: diff --git a/tests/macros/tgettypeinst.nim b/tests/macros/tgettypeinst.nim index 255eff949..f89aa5e0b 100644 --- a/tests/macros/tgettypeinst.nim +++ b/tests/macros/tgettypeinst.nim @@ -21,49 +21,67 @@ proc symToIdent(x: NimNode): NimNode = for c in x: result.add symToIdent(c) +# check getTypeInst and getTypeImpl for given symbol x macro testX(x,inst0: typed; recurse: static[bool]; implX: stmt): typed = + # check that getTypeInst(x) equals inst0 let inst = x.getTypeInst - let impl = x.getTypeImpl - let inst0r = inst0.symToIdent.treeRepr let instr = inst.symToIdent.treeRepr - #echo inst0r + let inst0r = inst0.symToIdent.treeRepr #echo instr + #echo inst0r doAssert(instr == inst0r) + + # check that getTypeImpl(x) is correct + # if implX is nil then compare to inst0 + # else we expect implX to be a type definition + # and we extract the implementation from that + let impl = x.getTypeImpl var impl0 = if implX.kind == nnkNilLit: inst0 else: implX[0][2] - let impl0r = impl0.symToIdent.treerepr let implr = impl.symToIdent.treerepr - #echo impl0r + let impl0r = impl0.symToIdent.treerepr #echo implr + #echo impl0r doAssert(implr == impl0r) - template echoString(s:string) = echo s.replace("\n","\n ") + result = newStmtList() + #template echoString(s: string) = echo s.replace("\n","\n ") #result.add getAst(echoString(" " & inst0.repr)) #result.add getAst(echoString(" " & inst.repr)) #result.add getAst(echoString(" " & impl0.repr)) #result.add getAst(echoString(" " & impl.repr)) + if recurse: - template testDecl(n, m :typed) = + # now test using a newly formed variable of type getTypeInst(x) + template testDecl(n,m: typed) = testV(n, false): type _ = m result.add getAst(testDecl(inst.symToIdent, impl.symToIdent)) +# test with a variable (instance) of type template testV(inst, recurse, impl) = block: #echo "testV(" & astToStr(inst) & ", " & $recurse & "):" & astToStr(impl) var x: inst testX(x, inst, recurse, impl) -template testT(inst, recurse) = + +# test with a newly created typedesc (myType) +# using the passed type as the implementation +template testT(impl, recurse) = block: - type myType = inst + type myType = impl testV(myType, recurse): - type _ = inst + type _ = impl +# test a built-in type whose instance is equal to the implementation template test(inst) = testT(inst, false) testV(inst, true, nil) -template test(inst, impl) = testV(inst, true, impl) + +# test a custom type with provided implementation +template test(inst, impl) = + testV(inst, true, impl) type Model = object of RootObj @@ -87,9 +105,12 @@ type value:T Foo[N:static[int],T] = object Bar[N:static[int],T] = object - #baz:Foo[N+1,GenericObject[T]] + #baz:Foo[N+1,GenericObject[T]] # currently fails baz:Foo[N,GenericObject[T]] + Generic[T] = seq[int] + Concrete = Generic[int] + test(bool) test(char) test(int) @@ -97,13 +118,17 @@ test(float) test(ptr int) test(ref int) test(array[1..10,Bar[2,Foo[3,float]]]) +test(array[MyEnum,Bar[2,Foo[3,float]]]) test(distinct Bar[2,Foo[3,float]]) test(tuple[a:int,b:Foo[-1,float]]) -#test(MyEnum): -# type _ = enum -# valueA, valueB, valueC -test(set[MyEnum]) test(seq[int]) +test(set[MyEnum]) +test(proc (a: int, b: Foo[2,float])) +test(proc (a: int, b: Foo[2,float]): Bar[3,int]) + +test(MyEnum): + type _ = enum + valueA, valueB, valueC test(Bar[2,Foo[3,float]]): type _ = object baz: Foo[2, GenericObject[Foo[3, float]]] @@ -118,8 +143,12 @@ test(Tree): value: int left: ref Tree right: ref Tree -test(proc (a: int, b: Foo[2,float])) -test(proc (a: int, b: Foo[2,float]): Bar[3,int]) +test(Concrete): + type _ = Generic[int] +test(Generic[int]): + type _ = seq[int] +test(Generic[float]): + type _ = seq[int] # bug #4862 static: diff --git a/web/news/e031_version_0_16_2.rst b/web/news/e031_version_0_16_2.rst index 63884700f..4f49bd8d9 100644 --- a/web/news/e031_version_0_16_2.rst +++ b/web/news/e031_version_0_16_2.rst @@ -45,6 +45,8 @@ Changes affecting backwards compatibility AST that is the same as what is used to define an enum. Previously the AST returned had a repeated ``EnumTy`` node and was missing the initial pragma node (which is currently empty for an enum). +- ``macros.getTypeImpl`` now correctly returns the implementation for a symbol + of type ``tyGenericBody``. - If the dispatcher parameter's value used in multi method is ``nil``, a ``NilError`` exception is raised. The old behavior was that the method would be a ``nop`` then. |