diff options
author | Juan M Gómez <info@jmgomez.me> | 2023-09-01 12:42:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-01 13:42:47 +0200 |
commit | 0c6e13806d0abfad30b8a4bd9f1fe7858ff2125a (patch) | |
tree | 252de32fedf2cd3c0f27171eafe2fc90bc97ec74 | |
parent | f1789cc465bcabc7afe0fe991df615246cfadb3b (diff) | |
download | Nim-0c6e13806d0abfad30b8a4bd9f1fe7858ff2125a.tar.gz |
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
-rw-r--r-- | compiler/semdata.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 10 | ||||
-rw-r--r-- | tests/generics/t1500.nim | 8 |
3 files changed, 19 insertions, 1 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim index db3b8370e..00559a5b6 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 b469c69fb..282bc53fe 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 000000000..6dd457d33 --- /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 |