summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semstmts.nim4
-rw-r--r--compiler/types.nim7
2 files changed, 10 insertions, 1 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 5232c5706..d0cab48a5 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1329,8 +1329,10 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
       else:
         while x.kind in {nkStmtList, nkStmtListExpr} and x.len > 0:
           x = x.lastSon
+        # we need the 'safeSkipTypes' here because illegally recursive types
+        # can enter at this point, see bug #13763
         if x.kind notin {nkObjectTy, nkDistinctTy, nkEnumTy, nkEmpty} and
-            s.typ.skipTypes(abstractPtrs-{tyAlias}).kind notin {tyObject, tyEnum}:
+            s.typ.safeSkipTypes(abstractPtrs).kind notin {tyObject, tyEnum}:
           # type aliases are hard:
           var t = semTypeNode(c, x, nil)
           assert t != nil
diff --git a/compiler/types.nim b/compiler/types.nim
index 33c81f9cc..38dc15498 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1503,6 +1503,13 @@ proc containsCompileTimeOnly*(t: PType): bool =
       return true
   return false
 
+proc safeSkipTypes*(t: PType, kinds: TTypeKinds): PType =
+  ## same as 'skipTypes' but with a simple cycle detector.
+  result = t
+  var seen = initIntSet()
+  while result.kind in kinds and not containsOrIncl(seen, result.id):
+    result = lastSon(result)
+
 type
   OrdinalType* = enum
     NoneLike, IntLike, FloatLike