diff options
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/seminst.nim | 9 | ||||
-rw-r--r-- | doc/intern.txt | 40 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 8 | ||||
-rw-r--r-- | tests/compiles/tevilcompiles.nim | 12 |
5 files changed, 56 insertions, 15 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 4f0b47b85..ec309ba1a 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1055,7 +1055,7 @@ proc discardSons(father: PNode) = father.sons = nil when defined(useNodeIds): - const nodeIdToDebug* = 310841 # 612794 + const nodeIdToDebug* = -1 # 884953 # 612794 #612840 # 612905 # 614635 # 614637 # 614641 # 423408 #429107 # 430443 # 441048 # 441090 # 441153 diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 8ac3849b4..2decb5d0b 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -157,8 +157,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable, # # The solution would be to move this logic into semtypinst, but # at this point semtypinst have to become part of sem, because it - # will need to use openScope, addDecl, etc - # + # will need to use openScope, addDecl, etc. addDecl(c, prc) pushInfoContext(info) @@ -223,7 +222,11 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, n.sons[genericParamsPos] = ast.emptyNode var oldPrc = genericCacheGet(fn, entry[]) if oldPrc == nil: - fn.procInstCache.safeAdd(entry) + # we MUST not add potentially wrong instantiations to the caching mechanism. + # This means recursive instantiations behave differently when in + # a ``compiles`` context but this is the lesser evil. See + # bug #1055 (tevilcompiles). + if c.inCompilesContext == 0: fn.procInstCache.safeAdd(entry) c.generics.add(makeInstPair(fn, entry)) if n.sons[pragmasPos].kind != nkEmpty: pragma(c, result, n.sons[pragmasPos], allRoutinePragmas) diff --git a/doc/intern.txt b/doc/intern.txt index 6cd1987aa..26dd49444 100644 --- a/doc/intern.txt +++ b/doc/intern.txt @@ -118,6 +118,34 @@ Thus we need to serialize this graph as RTTI for C code generation. Look at the file ``lib/system/hti.nim`` for more information. +Debugging the compiler +====================== + +You can of course use GDB or Visual Studio to debug the +compiler (via ``--debuginfo --lineDir:on``). However, there +are also lots of procs that aid in debugging: + + +.. code-block:: nim + # pretty prints the Nim AST + echo renderTree(someNode) + # outputs some JSON representation + debug(someNode) + # pretty prints some type + echo typeToString(someType) + debug(someType) + echo symbol.name.s + debug(symbol) + # pretty prints the nimrod ast, but annotates symbol IDs: + echo renderTree(someNode, {renderIds}) + if n.info ?? "temp.nim": + # only output when it comes from "temp.nim" + echo renderTree(n) + if n.info ?? "temp.nim": + # why does it process temp.nim here? + writeStackTrace() + + The compiler's architecture =========================== @@ -255,16 +283,14 @@ turned on". Debugging Nim's memory management -==================================== +================================= The following paragraphs are mostly a reminder for myself. Things to keep in mind: -* Segmentation faults can have multiple reasons: One that is frequently - forgotten is that *stack overflow* can trigger one! * If an assertion in Nim's memory manager or GC fails, the stack trace keeps allocating memory! Thus a stack overflow may happen, hiding the - real issue. + real issue. * What seem to be C code generation problems is often a bug resulting from not producing prototypes, so that some types default to ``cint``. Testing without the ``-w`` option helps! @@ -304,8 +330,8 @@ modifying a ``TCellSet`` during traversation leads to undefined behaviour. type TCellSet # hidden - proc CellSetInit(s: var TCellSet) # initialize a new set - proc CellSetDeinit(s: var TCellSet) # empty the set and free its memory + proc cellSetInit(s: var TCellSet) # initialize a new set + proc cellSetDeinit(s: var TCellSet) # empty the set and free its memory proc incl(s: var TCellSet, elem: PCell) # include an element proc excl(s: var TCellSet, elem: PCell) # exclude an element @@ -493,7 +519,7 @@ Accumulator ----------- .. code-block:: nim - proc GetAccumulator(start: int): proc (): int {.closure} = + proc getAccumulator(start: int): proc (): int {.closure} = var i = start return lambda: int = inc i diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index cfbc4a708..50246f2e0 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -728,9 +728,9 @@ proc renderTocEntry(d: PDoc, e: TTocEntry, result: var string) = "\\item\\label{$1_toc} $2\\ref{$1}\n", [e.refname, e.header]) proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, - result: var string) = + result: var string) = var tmp = "" - while j <= high(d.tocPart): + while j <= high(d.tocPart): var a = abs(d.tocPart[j].n.level) if a == lvl: renderTocEntry(d, d.tocPart[j], tmp) @@ -740,11 +740,11 @@ proc renderTocEntries*(d: var TRstGenerator, j: var int, lvl: int, else: break if lvl > 1: - dispA(d.target, result, "<ul class=\"simple\">$1</ul>", + dispA(d.target, result, "<ul class=\"simple\">$1</ul>", "\\begin{enumerate}$1\\end{enumerate}", [tmp]) else: result.add(tmp) - + proc renderImage(d: PDoc, n: PRstNode, result: var string) = var options = "" var s = getFieldValue(n, "scale") diff --git a/tests/compiles/tevilcompiles.nim b/tests/compiles/tevilcompiles.nim new file mode 100644 index 000000000..0930507d1 --- /dev/null +++ b/tests/compiles/tevilcompiles.nim @@ -0,0 +1,12 @@ +# bug #1055 +import unittest +type TMatrix*[N,M: static[int], T] = object + data*: array[0..N*M-1, T] +proc `==`*(a: distinct TMatrix; b: distinct TMatrix): bool = + result = a.data == b.data + +test "c": + var a = TMatrix[2,2,int](data: [1,2,3,4]) + var b = TMatrix[2,2,int](data: [1,2,3,4]) + check(a == b) + |