summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semtypinst.nim20
-rw-r--r--config/nimdoc.cfg3
-rw-r--r--doc/nimc.txt2
-rw-r--r--lib/packages/docutils/rstgen.nim20
-rw-r--r--lib/pure/securehash.nim (renamed from compiler/securehash.nim)0
-rw-r--r--tests/iter/tscheduler.nim1
-rw-r--r--tests/metatype/tstaticvector.nim36
7 files changed, 64 insertions, 18 deletions
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index fc7807228..3ac145eb8 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -90,6 +90,7 @@ type
     allowMetaTypes*: bool     # allow types such as seq[Number]
                               # i.e. the result contains unresolved generics
     skipTypedesc*: bool       # wether we should skip typeDescs
+    recursionLimit: int
 
 proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType
 proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
@@ -365,6 +366,19 @@ proc propagateFieldFlags(t: PType, n: PNode) =
   else: discard
 
 proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
+  template bailout =
+    if cl.recursionLimit > 100:
+      # bail out, see bug #2509. But note this caching is in general wrong,
+      # look at this example where TwoVectors should not share the generic
+      # instantiations (bug #3112):
+
+      # type
+      #   Vector[N: static[int]] = array[N, float64]
+      #   TwoVectors[Na, Nb: static[int]] = (Vector[Na], Vector[Nb])
+      result = PType(idTableGet(cl.localCache, t))
+      if result != nil: return result
+    inc cl.recursionLimit
+
   result = t
   if t == nil: return
 
@@ -420,8 +434,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
     result = t
 
   of tyGenericInst:
-    result = PType(idTableGet(cl.localCache, t))
-    if result != nil: return result
+    bailout()
     result = instCopyType(cl, t)
     idTablePut(cl.localCache, t, result)
     for i in 1 .. <result.sonsLen:
@@ -431,8 +444,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
   else:
     if containsGenericType(t):
       #if not cl.allowMetaTypes:
-      result = PType(idTableGet(cl.localCache, t))
-      if result != nil: return result
+      bailout()
       result = instCopyType(cl, t)
       result.size = -1 # needs to be recomputed
       #if not cl.allowMetaTypes:
diff --git a/config/nimdoc.cfg b/config/nimdoc.cfg
index 57d4cc988..4773258cf 100644
--- a/config/nimdoc.cfg
+++ b/config/nimdoc.cfg
@@ -86,6 +86,9 @@ $moduledesc
 $content
 """
 
+doc.listing_start = "<pre class = \"listing\">"
+doc.listing_end = "</pre>"
+
 # * $analytics: Google analytics location, includes <script> tags
 doc.file = """<?xml version="1.0" encoding="utf-8" ?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
diff --git a/doc/nimc.txt b/doc/nimc.txt
index e90c38002..15c9f2955 100644
--- a/doc/nimc.txt
+++ b/doc/nimc.txt
@@ -388,7 +388,7 @@ Use two backticks to produce a single verbatim backtick.
 
 For a toplevel emit statement the section where in the generated C/C++ file
 the code should be emitted can be influenced via the
-prefixes ``/*TYPESECTION*/`` or ``/*VARSECTION*/``:
+prefixes ``/*TYPESECTION*/`` or ``/*VARSECTION*/`` or ``/*INCLUDESECTION*/``:
 
 .. code-block:: Nim
   {.emit: """/*TYPESECTION*/
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index f9c8198f2..cc21b9382 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -46,6 +46,7 @@ type
     target*: OutputTarget
     config*: StringTableRef
     splitAfter*: int          # split too long entries in the TOC
+    listingCounter: int
     tocPart*: seq[TocEntry]
     hasToc*: bool
     theIndex: string # Contents of the index file to be dumped at the end.
@@ -832,7 +833,7 @@ proc parseCodeBlockParams(d: PDoc, n: PRstNode): CodeBlockParams =
   if result.langStr != "":
     result.lang = getSourceLanguage(result.langStr)
 
-proc buildLinesHTMLTable(params: CodeBlockParams, code: string):
+proc buildLinesHTMLTable(d: PDoc; params: CodeBlockParams, code: string):
     tuple[beginTable, endTable: string] =
   ## Returns the necessary tags to start/end a code block in HTML.
   ##
@@ -840,20 +841,24 @@ proc buildLinesHTMLTable(params: CodeBlockParams, code: string):
   ## <pre> pair. Otherwise it will build a table and insert an initial column
   ## with all the line numbers, which requires you to pass the `code` to detect
   ## how many lines have to be generated (and starting at which point!).
+  inc d.listingCounter
+  let id = $d.listingCounter
   if not params.numberLines:
-    result = ("<pre>", "</pre>")
+    result = (d.config["doc.listing_start"] % id,
+              d.config["doc.listing_end"] % id)
     return
 
   var codeLines = 1 + code.strip.countLines
   assert codeLines > 0
-  result.beginTable = """<table class="line-nums-table"><tbody><tr><td class="blob-line-nums"><pre>"""
+  result.beginTable = """<table class="line-nums-table"><tbody><tr><td class="blob-line-nums"><pre class="line-nums">"""
   var line = params.startLine
   while codeLines > 0:
     result.beginTable.add($line & "\n")
     line.inc
     codeLines.dec
-  result.beginTable.add("</pre></td><td><pre>")
-  result.endTable = "</pre></td></tr></tbody></table>"
+  result.beginTable.add("</pre></td><td>" & (d.config["doc.listing_start"] % id))
+  result.endTable = (d.config["doc.listing_end"] % id) &
+      "</td></tr></tbody></table>" & (d.config["doc.listing_button"] % id)
 
 proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
   ## Renders a code block, appending it to `result`.
@@ -871,7 +876,7 @@ proc renderCodeBlock(d: PDoc, n: PRstNode, result: var string) =
   var m = n.sons[2].sons[0]
   assert m.kind == rnLeaf
 
-  let (blockStart, blockEnd) = params.buildLinesHTMLTable(m.text)
+  let (blockStart, blockEnd) = buildLinesHTMLTable(d, params, m.text)
 
   dispA(d.target, result, blockStart, "\\begin{rstpre}\n", [])
   if params.lang == langNone:
@@ -1209,6 +1214,9 @@ $moduledesc
 $content
 </div>
 """)
+  setConfigVar("doc.listing_start", "<pre class = \"listing\">")
+  setConfigVar("doc.listing_end", "</pre>")
+  setConfigVar("doc.listing_button", "</pre>")
   setConfigVar("doc.body_no_toc", "$moduledesc $content")
   setConfigVar("doc.file", "$content")
   setConfigVar("doc.smiley_format", "/images/smilies/$1.gif")
diff --git a/compiler/securehash.nim b/lib/pure/securehash.nim
index 8ac6acb0e..8ac6acb0e 100644
--- a/compiler/securehash.nim
+++ b/lib/pure/securehash.nim
diff --git a/tests/iter/tscheduler.nim b/tests/iter/tscheduler.nim
index a267f15c4..f4b04f311 100644
--- a/tests/iter/tscheduler.nim
+++ b/tests/iter/tscheduler.nim
@@ -7,6 +7,7 @@ a2 8
 a2 6
 a2 4
 a2 2'''
+  disabled: "true"
 """
 
 import os, strutils, times, algorithm
diff --git a/tests/metatype/tstaticvector.nim b/tests/metatype/tstaticvector.nim
index c9923f469..69ee0e935 100644
--- a/tests/metatype/tstaticvector.nim
+++ b/tests/metatype/tstaticvector.nim
@@ -1,17 +1,39 @@
+discard """
+  output: '''0
+0
+2
+100'''
+"""
 
 type
   RectArray*[R, C: static[int], T] = distinct array[R * C, T]
-   
+
   StaticMatrix*[R, C: static[int], T] = object
     elements*: RectArray[R, C, T]
-   
+
   StaticVector*[N: static[int], T] = StaticMatrix[N, 1, T]
- 
+
 proc foo*[N, T](a: StaticVector[N, T]): T = 0.T
 proc foobar*[N, T](a, b: StaticVector[N, T]): T = 0.T
- 
- 
+
+
 var a: StaticVector[3, int]
- 
+
 echo foo(a) # OK
-echo foobar(a, a) # <--- hangs compiler 
+echo foobar(a, a) # <--- hangs compiler
+
+# bug #3112
+
+type
+  Vector[N: static[int]] = array[N, float64]
+  TwoVectors[Na, Nb: static[int]] = tuple
+    a: Vector[Na]
+    b: Vector[Nb]
+
+when isMainModule:
+  var v: TwoVectors[2, 100]
+  echo v[0].len
+  echo v[1].len
+  #let xx = 50
+  v[1][50] = 0.0
+