diff options
-rw-r--r-- | compiler/astalgo.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 1 | ||||
-rw-r--r-- | compiler/seminst.nim | 14 | ||||
-rw-r--r-- | tests/generics/tforward_generic.nim | 16 | ||||
-rw-r--r-- | tests/generics/tforwardgeneric.nim | 18 |
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() + |