diff options
-rw-r--r-- | compiler/ast.nim | 3 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 11 | ||||
-rw-r--r-- | compiler/sighashes.nim | 5 | ||||
-rw-r--r-- | tests/cpp/tsigbreak.nim | 28 |
5 files changed, 42 insertions, 7 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 38f481282..d9c886d7f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -444,7 +444,7 @@ type nfPreventCg # this node should be ignored by the codegen TNodeFlags* = set[TNodeFlag] - TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 28) + TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 30) tfVarargs, # procedure has C styled varargs tfNoSideEffect, # procedure type does not allow side effects tfFinal, # is the object final? @@ -488,6 +488,7 @@ type tfBorrowDot # distinct type borrows '.' tfTriggersCompileTime # uses the NimNode type which make the proc # implicitly '.compiletime' + tfRefsAnonObj # used for 'ref object' and 'ptr object' TTypeFlags* = set[TTypeFlag] diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index b59036ea5..fb57f6500 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -759,9 +759,11 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = if st.kind == tyGenericBody: st = st.lastSon internalAssert st.kind in {tyPtr, tyRef} internalAssert st.lastSon.sym == nil + incl st.flags, tfRefsAnonObj st.lastSon.sym = newSym(skType, getIdent(s.name.s & ":ObjectType"), getCurrOwner(), s.info) + proc checkForMetaFields(n: PNode) = template checkMeta(t) = if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 29e75e188..4f1f420a8 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -293,6 +293,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = let bbody = lastSon body var newbody = replaceTypeVarsT(cl, bbody) + let bodyIsNew = newbody != bbody cl.skipTypedesc = oldSkipTypedesc newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags) result.flags = result.flags + newbody.flags - tfInstClearedFlags @@ -310,9 +311,13 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = # generics *when the type is constructed*: newbody.deepCopy = cl.c.instTypeBoundOp(cl.c, dc, result, cl.info, attachedDeepCopy, 1) - newbody.typeInst = result - if newbody.kind == tyRef: - newbody.lastSon.typeInst = result + if bodyIsNew and newbody.typeInst == nil: + #doassert newbody.typeInst == nil + newbody.typeInst = result + if tfRefsAnonObj in newbody.flags: + assert newbody.kind in {tyRef, tyPtr} + assert newbody.lastSon.typeInst == nil + newbody.lastSon.typeInst = result let asgn = newbody.assignment if asgn != nil and sfFromGeneric notin asgn.flags: # '=' needs to be instantiated for generics when the type is constructed: diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 07734f9af..04b3d7a34 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -122,7 +122,6 @@ type ConsiderFlag* = enum CoProc CoType - CoNoGeneric proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = if t == nil: @@ -153,10 +152,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = if t.sym != nil and {sfImportc, sfExportc} * t.sym.flags != {}: c.hashSym(t.sym) of tyObject, tyEnum: - if t.typeInst != nil and CoNoGeneric notin flags: + if t.typeInst != nil: assert t.typeInst.kind == tyGenericInst for i in countup(1, sonsLen(t.typeInst) - 2): - c.hashType t.typeInst.sons[i], flags+{CoNoGeneric} + c.hashType t.typeInst.sons[i], flags # Every cyclic type in Nim need to be constructed via some 't.sym', so this # is actually safe without an infinite recursion check: if t.sym != nil: diff --git a/tests/cpp/tsigbreak.nim b/tests/cpp/tsigbreak.nim new file mode 100644 index 000000000..c8044f2bf --- /dev/null +++ b/tests/cpp/tsigbreak.nim @@ -0,0 +1,28 @@ +discard """ + cmd: "nim cpp $file" +""" + +import tables, lists + +type + ListTable[K, V] = object + table: Table[K, DoublyLinkedNode[V]] + +proc initListTable*[K, V](initialSize = 64): ListTable[K, V] = + result.table = initTable[K, DoublyLinkedNode[V]]() + +proc `[]=`*[K, V](t: var ListTable[K, V], key: K, val: V) = + t.table[key].value = val + +type + SomeObj = object + OtherObj = object + +proc main() = + var someTable = initListTable[int, SomeObj]() + var otherTable = initListTable[int, OtherObj]() + + someTable[1] = SomeObj() + otherTable[42] = OtherObj() + +main() |