summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim3
-rw-r--r--compiler/vm.nim3
-rw-r--r--compiler/vmdef.nim5
-rw-r--r--compiler/vmgen.nim1
-rw-r--r--lib/core/macros.nim4
-rw-r--r--tests/macros/tsametype.nim41
6 files changed, 54 insertions, 3 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 0a7fc28f4..51dcbc14f 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -587,7 +587,8 @@ type
     mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo,
     mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr,
     mNBindSym, mLocals, mNCallSite,
-    mEqIdent, mEqNimrodNode, mNHint, mNWarning, mNError,
+    mEqIdent, mEqNimrodNode, mSameNodeType,
+    mNHint, mNWarning, mNError,
     mInstantiationInfo, mGetTypeInfo, mNGenSym
 
 # things that we can evaluate safely at compile time, even if not asked for it:
diff --git a/compiler/vm.nim b/compiler/vm.nim
index a8972f420..6d496d6e1 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -692,6 +692,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       regs[ra].intVal =
         ord(exprStructuralEquivalent(regs[rb].node, regs[rc].node,
                                      strictSymEquality=true))
+    of opcSameNodeType:
+      decodeBC(rkInt)
+      regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil regs[rc].node.typ)
     of opcXor:
       decodeBC(rkInt)
       regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 2d0272cd7..6900b17c2 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -60,8 +60,9 @@ type
     opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt,
     opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu,
     opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat,
-    opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcEqNimrodNode, opcXor,
-    opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
+    opcLeFloat, opcLtFloat, opcLeu, opcLtu,
+    opcEqRef, opcEqNimrodNode, opcSameNodeType,
+    opcXor, opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
     opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
     opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
     opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index b608ae48e..004adedb9 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -991,6 +991,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
   of mIdentToStr: genUnaryABC(c, n, dest, opcIdentToStr)
   of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent)
   of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqNimrodNode)
+  of mSameNodeType: genBinaryABC(c, n, dest, opcSameNodeType)
   of mNLineInfo: genUnaryABC(c, n, dest, opcNLineInfo)
   of mNHint:
     unused(n, dest)
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 044020b2a..49def06f0 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -144,6 +144,10 @@ proc `==`*(a, b: NimIdent): bool {.magic: "EqIdent", noSideEffect.}
 proc `==`*(a, b: NimNode): bool {.magic: "EqNimrodNode", noSideEffect.}
   ## compares two Nim nodes
 
+proc sameType*(a, b: NimNode): bool {.magic: "SameNodeType", noSideEffect.}
+  ## compares two Nim nodes' types. Return true if the types are the same,
+  ## eg. true when comparing alias with original type.
+
 proc len*(n: NimNode): int {.magic: "NLen", noSideEffect.}
   ## returns the number of children of `n`.
 
diff --git a/tests/macros/tsametype.nim b/tests/macros/tsametype.nim
new file mode 100644
index 000000000..6baa34751
--- /dev/null
+++ b/tests/macros/tsametype.nim
@@ -0,0 +1,41 @@
+discard """
+output: '''1
+0
+1
+0
+1
+0
+1
+0
+1
+0'''
+"""
+
+import macros
+
+macro same(a: typedesc, b: typedesc): expr =
+  newLit(a.getType[1].sameType b.getType[1])
+
+echo same(int, int)
+echo same(int, float)
+
+type
+  SomeInt = int
+  DistinctInt = distinct int
+  SomeFloat = float
+  DistinctFloat = distinct float
+
+echo same(int, SomeInt)
+echo same(int, DistinctInt)
+echo same(float, SomeFloat)
+echo same(float, DistinctFloat)
+
+type
+  Obj = object of RootObj
+  SubObj = object of Obj
+  Other = object of RootObj
+
+echo same(Obj, Obj)
+echo same(int, Obj)
+echo same(SubObj, SubObj)
+echo same(Other, Obj)