Fix generic forward declarations; fixes #4104; fixes #4908 (#5566)

This commit is contained in:
zah
2017-03-23 13:40:57 +02:00
committed by Andreas Rumpf
parent 70237e1fdd
commit be174fc3c7
5 changed files with 36 additions and 15 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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()