the regression was caused by the introduction of "generic" lambdas
This commit is contained in:
Zahary Karadjov
2014-03-15 11:23:46 +02:00
parent 7080d02af4
commit cf8fe16a48
6 changed files with 29 additions and 4 deletions

View File

@@ -106,6 +106,8 @@ type
errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX,
errXCannotBeClosure, errXMustBeCompileTime,
errCannotInferTypeOfTheLiteral,
errCannotInferReturnType,
errGenericLambdaNotAllowed,
errUser,
warnCannotOpenFile,
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
@@ -355,6 +357,10 @@ const
errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
errXMustBeCompileTime: "'$1' can only be used in compile-time context",
errCannotInferTypeOfTheLiteral: "cannot infer the type of the $1",
errCannotInferReturnType: "cannot infer the return type of the proc",
errGenericLambdaNotAllowed: "A nested proc can have generic parameters only when " &
"it is used as an operand to another routine and the types " &
"of the generic paramers can be infered from the expected signature.",
errUser: "$1",
warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]",
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]",

View File

@@ -42,7 +42,7 @@ type
TExprFlag* = enum
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
efAllowDestructor, efWantValue
efAllowDestructor, efWantValue, efOperand
TExprFlags* = set[TExprFlag]
PContext* = ref TContext

View File

@@ -21,7 +21,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
# same as 'semExprWithType' but doesn't check for proc vars
result = semExpr(c, n, flags)
result = semExpr(c, n, flags + {efOperand})
if result.kind == nkEmpty:
# do not produce another redundant error message:
#raiseRecoverableError("")
@@ -1218,6 +1218,7 @@ 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
@@ -1241,6 +1242,10 @@ proc semProcBody(c: PContext, n: PNode): PNode =
result = semAsgn(c, a)
else:
discardCheck(c, result)
if c.p.resultSym != nil and c.p.resultSym.typ.isMetaType:
localError(c.p.resultSym.info, errCannotInferReturnType)
closeScope(c)
proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =

View File

@@ -944,13 +944,15 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
#if efDetermineType notin flags:
# XXX not good enough; see tnamedparamanonproc.nim
if n.sons[genericParamsPos].kind == nkEmpty:
if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
pushProcCon(c, s)
addResult(c, s.typ.sons[0], n.info, skProc)
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
n.sons[bodyPos] = transformBody(c.module, semBody, s)
addResultNode(c, n)
popProcCon(c)
elif efOperand notin flags:
localError(n.info, errGenericLambdaNotAllowed)
sideEffectsCheck(c, s)
else:
localError(n.info, errImplOfXexpected, s.name.s)

View File

@@ -0,0 +1,7 @@
discard """
msg: "nested proc can have generic parameters only when"
line: 6
"""
let x = proc (x, y): auto = x + y

View File

@@ -1,5 +1,5 @@
discard """
output: "10\n10\n1\n2\n3"
output: "10\n10\n1\n2\n3\n15"
"""
proc test(x: proc (a, b: int): int) =
@@ -16,3 +16,8 @@ proc foreach[T](s: seq[T], body: proc(x: T)) =
foreach(@[1,2,3]) do (x):
echo x
proc foo =
let x = proc (a, b: int): auto = a + b
echo x(5, 10)
foo()