From 0c6e13806d0abfad30b8a4bd9f1fe7858ff2125a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20M=20G=C3=B3mez?= Date: Fri, 1 Sep 2023 12:42:47 +0100 Subject: [PATCH] fixes internal error: no generic body fixes #1500 (#22580) * fixes internal error: no generic body fixes #1500 * adds guard * adds guard * removes unnecessary test * refactor: extracts containsGenericInvocationWithForward --- compiler/semdata.nim | 2 +- compiler/semtypes.nim | 10 ++++++++++ tests/generics/t1500.nim | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/generics/t1500.nim diff --git a/compiler/semdata.nim b/compiler/semdata.nim index db3b8370ee56..00559a5b6142 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -168,7 +168,7 @@ type sideEffects*: Table[int, seq[(TLineInfo, PSym)]] # symbol.id index inUncheckedAssignSection*: int importModuleLookup*: Table[int, seq[int]] # (module.ident.id, [module.id]) - skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance and sets. + skipTypes*: seq[PNode] # used to skip types between passes in type section. So far only used for inheritance, sets and generic bodies. TBorrowState* = enum bsNone, bsReturnNotMatch, bsNoDistinct, bsGeneric, bsNotSupported, bsMatch diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index b469c69fbfb7..282bc53fea6a 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1508,6 +1508,14 @@ proc trySemObjectTypeForInheritedGenericInst(c: PContext, n: PNode, t: PType): b var newf = newNodeI(nkRecList, n.info) semRecordNodeAux(c, t.n, check, pos, newf, t) +proc containsGenericInvocationWithForward(n: PNode): bool = + if n.kind == nkSym and n.sym.ast != nil and n.sym.ast.len > 1 and n.sym.ast[2].kind == nkObjectTy: + for p in n.sym.ast[2][^1]: + if p.kind == nkIdentDefs and p[1].typ != nil and p[1].typ.kind == tyGenericInvocation and + p[1][0].kind == nkSym and p[1][0].typ.kind == tyForward: + return true + return false + proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if s.typ == nil: localError(c.config, n.info, "cannot instantiate the '$1' $2" % @@ -1577,6 +1585,8 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = # XXX: What kind of error is this? is it still relevant? localError(c.config, n.info, errCannotInstantiateX % s.name.s) result = newOrPrevType(tyError, prev, c) + elif containsGenericInvocationWithForward(n[0]): + c.skipTypes.add n #fixes 1500 else: result = instGenericContainer(c, n.info, result, allowMetaTypes = false) diff --git a/tests/generics/t1500.nim b/tests/generics/t1500.nim new file mode 100644 index 000000000000..6dd457d336c0 --- /dev/null +++ b/tests/generics/t1500.nim @@ -0,0 +1,8 @@ +#issue 1500 + +type + TFtpBase*[SockType] = object + job: TFTPJob[SockType] + PFtpBase*[SockType] = ref TFtpBase[SockType] + TFtpClient* = TFtpBase[string] + TFTPJob[T] = object \ No newline at end of file