summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2024-06-09 08:16:05 +0200
committerGitHub <noreply@github.com>2024-06-09 08:16:05 +0200
commit56c95758b2777a36c8608a7b9950ba5ce8ce0b65 (patch)
treea71a603085e4fb75e7fd21b48bfb5fb94ffb5e6d
parentc7ee16182eb54b6f426358fee359280278d0b780 (diff)
downloadNim-56c95758b2777a36c8608a7b9950ba5ce8ce0b65.tar.gz
fixes #23445; fixes #23418 [backport] (#23699)
-rw-r--r--compiler/seminst.nim3
-rw-r--r--compiler/types.nim10
-rw-r--r--tests/metatype/twrong_same_type.nim28
3 files changed, 40 insertions, 1 deletions
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index e9b46c382..92f8664fe 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -396,6 +396,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TypeMapping,
   for _, param in paramTypes(result.typ):
     entry.concreteTypes[i] = param
     inc i
+  #echo "INSTAN ", fn.name.s, " ", typeToString(result.typ), " ", entry.concreteTypes.len
   if tfTriggersCompileTime in result.typ.flags:
     incl(result.flags, sfCompileTime)
   n[genericParamsPos] = c.graph.emptyNode
@@ -424,7 +425,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TypeMapping,
     if result.magic notin {mSlice, mTypeOf}:
       # 'toOpenArray' is special and it is allowed to return 'openArray':
       paramsTypeCheck(c, result.typ)
+    #echo "INSTAN ", fn.name.s, " ", typeToString(result.typ), " <-- NEW PROC!", " ", entry.concreteTypes.len
   else:
+    #echo "INSTAN ", fn.name.s, " ", typeToString(result.typ), " <-- CACHED! ", typeToString(oldPrc.typ), " ", entry.concreteTypes.len
     result = oldPrc
   popProcCon(c)
   popInfoContext(c.config)
diff --git a/compiler/types.nim b/compiler/types.nim
index e5ce0aea1..880f811dd 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1316,9 +1316,17 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
     result = sameTypeOrNilAux(a.elementType, b.elementType, c) and
         sameValue(a.n[0], b.n[0]) and
         sameValue(a.n[1], b.n[1])
-  of tyGenericInst, tyAlias, tyInferred, tyIterable:
+  of tyAlias, tyInferred, tyIterable:
     cycleCheck()
     result = sameTypeAux(a.skipModifier, b.skipModifier, c)
+  of tyGenericInst:
+    # BUG #23445
+    # The type system must distinguish between `T[int] = object #[empty]#`
+    # and `T[float] = object #[empty]#`!
+    cycleCheck()
+    for ff, aa in underspecifiedPairs(a, b, 1, -1):
+      if not sameTypeAux(ff, aa, c): return false
+    result = sameTypeAux(a.skipModifier, b.skipModifier, c)
   of tyNone: result = false
   of tyConcept:
     result = exprStructuralEquivalent(a.n, b.n)
diff --git a/tests/metatype/twrong_same_type.nim b/tests/metatype/twrong_same_type.nim
new file mode 100644
index 000000000..ea903b7a3
--- /dev/null
+++ b/tests/metatype/twrong_same_type.nim
@@ -0,0 +1,28 @@
+# bug #23418
+
+template mapIt*(x: untyped): untyped =
+  type OutType {.gensym.} = typeof(x) #typeof(x, typeOfProc)
+  newSeq[OutType](5)
+
+type F[E] = object
+
+proc start(v: int): F[(ValueError,)] = discard
+proc stop(v: int): F[tuple[]] = discard
+
+assert $typeof(mapIt(start(9))) == "seq[F[(ValueError,)]]"
+assert $typeof(mapIt(stop(9))) == "seq[F[tuple[]]]"
+
+# bug #23445
+
+type F2[T; I: static int] = distinct int
+
+proc start2(v: int): F2[void, 22] = discard
+proc stop2(v: int): F2[void, 33] = discard
+
+var a = mapIt(start2(5))
+
+assert $type(a) == "seq[F2[system.void, 22]]", $type(a)
+
+var b = mapIt(stop2(5))
+
+assert $type(b) == "seq[F2[system.void, 33]]", $type(b)