summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/astalgo.nim2
-rw-r--r--compiler/semexprs.nim1
-rw-r--r--compiler/seminst.nim14
-rw-r--r--tests/generics/tforward_generic.nim16
-rw-r--r--tests/generics/tforwardgeneric.nim18
5 files changed, 36 insertions, 15 deletions
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 161e4d637..77108eb7b 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -82,7 +82,7 @@ template mdbg*: bool {.dirty.} =
   elif compiles(L.fileIdx):
     L.fileIdx == gProjectMainIdx
   else:
-    false
+    error()
 
 # --------------------------- ident tables ----------------------------------
 proc idTableGet*(t: TIdTable, key: PIdObj): RootRef
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 39113079a..4d698dbfc 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1433,7 +1433,6 @@ proc semReturn(c: PContext, n: PNode): PNode =
 
 proc semProcBody(c: PContext, n: PNode): PNode =
   openScope(c)
-
   result = semExpr(c, n)
   if c.p.resultSym != nil and not isEmptyType(result.typ):
     # transform ``expr`` to ``result = expr``, but not if the expr is already
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 78dd7efe5..71752f5c3 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -125,6 +125,11 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind)
 
 proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
   if n.sons[bodyPos].kind != nkEmpty:
+    let procParams = result.typ.n
+    for i in 1 .. <procParams.len:
+      addDecl(c, procParams[i].sym)
+    maybeAddResult(c, result, result.ast)
+
     inc c.inGenericInst
     # add it here, so that recursive generic procs are possible:
     var b = n.sons[bodyPos]
@@ -147,13 +152,17 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
   for i in countup(0, c.generics.len - 1):
     if c.generics[i].genericSym.id == s.id:
       var oldPrc = c.generics[i].inst.sym
+      pushProcCon(c, oldPrc)
+      pushOwner(c, oldPrc)
       pushInfoContext(oldPrc.info)
       openScope(c)
       var n = oldPrc.ast
       n.sons[bodyPos] = copyTree(s.getBody)
-      instantiateBody(c, n, nil, oldPrc, s)
+      instantiateBody(c, n, oldPrc.typ.n, oldPrc, s)
       closeScope(c)
       popInfoContext()
+      popOwner(c)
+      popProcCon(c)
 
 proc sideEffectsCheck(c: PContext, s: PSym) =
   when false:
@@ -173,7 +182,7 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
   result = replaceTypeVarsT(cl, header)
 
 proc instantiateProcType(c: PContext, pt: TIdTable,
-                          prc: PSym, info: TLineInfo) =
+                         prc: PSym, info: TLineInfo) =
   # XXX: Instantiates a generic proc signature, while at the same
   # time adding the instantiated proc params into the current scope.
   # This is necessary, because the instantiation process may refer to
@@ -229,7 +238,6 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
   skipIntLiteralParams(result)
 
   prc.typ = result
-  maybeAddResult(c, prc, prc.ast)
   popInfoContext()
 
 proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
diff --git a/tests/generics/tforward_generic.nim b/tests/generics/tforward_generic.nim
index 169279cb3..f43e7455f 100644
--- a/tests/generics/tforward_generic.nim
+++ b/tests/generics/tforward_generic.nim
@@ -1,5 +1,6 @@
 discard """
   output: '''b()
+720 120.0
 720 120.0'''
 """
 
@@ -16,13 +17,12 @@ proc fac[T](x: T): T =
 
 echo fac(6), " ", fac(5.0)
 
-when false:
-  # This still doesn't work...
-  # test recursive generic with forwarding:
-  proc fac2[T](x: T): T
+# test recursive generic with forwarding:
+proc fac2[T](x: T): T
 
-  echo fac2(6), " ", fac2(5.0)
+echo fac2(6), " ", fac2(5.0)
+
+proc fac2[T](x: T): T =
+  if x == 0: return 1
+  else: return fac2(x-1)*x
 
-  proc fac2[T](x: T): T =
-    if x == 0: return 1
-    else: return fac2(x-1)*x
diff --git a/tests/generics/tforwardgeneric.nim b/tests/generics/tforwardgeneric.nim
index af0c7daf4..9f68bf332 100644
--- a/tests/generics/tforwardgeneric.nim
+++ b/tests/generics/tforwardgeneric.nim
@@ -1,7 +1,6 @@
 discard """
-  output: "1.1000000000000001e+00 11"
+  output: "1.1 11\n42\n0"
   ccodecheck: "!@'ClEnv'"
-  disabled: "true"
 """
 
 proc p[T](a, b: T): T
@@ -12,3 +11,18 @@ proc p[T](a, b: T): T =
   let c = b
   result = a + b + c
 
+# https://github.com/nim-lang/Nim/issues/4908
+proc foo(t: typedesc[int]): int
+proc bar(): int = foo(int)
+proc foo(t: typedesc[int]): int =
+  return 0
+
+# https://github.com/nim-lang/Nim/issues/4104
+proc print[T](t: T) # Error: implementation of 'print.print(t: int)' expected
+print 42 # moving this line after the implementation fixes the error,
+         # but such behaviour makes forward declaration pointless
+proc print[T](t: T) =
+  echo t
+
+echo bar()
+