fix #715 again
the regression was caused by the introduction of "generic" lambdas
This commit is contained in:
parent
7080d02af4
commit
cf8fe16a48
6 changed files with 29 additions and 4 deletions
|
|
@ -106,6 +106,8 @@ type
|
||||||
errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX,
|
errThreadvarCannotInit, errWrongSymbolX, errIllegalCaptureX,
|
||||||
errXCannotBeClosure, errXMustBeCompileTime,
|
errXCannotBeClosure, errXMustBeCompileTime,
|
||||||
errCannotInferTypeOfTheLiteral,
|
errCannotInferTypeOfTheLiteral,
|
||||||
|
errCannotInferReturnType,
|
||||||
|
errGenericLambdaNotAllowed,
|
||||||
errUser,
|
errUser,
|
||||||
warnCannotOpenFile,
|
warnCannotOpenFile,
|
||||||
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
|
||||||
|
|
@ -355,6 +357,10 @@ const
|
||||||
errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
|
errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
|
||||||
errXMustBeCompileTime: "'$1' can only be used in compile-time context",
|
errXMustBeCompileTime: "'$1' can only be used in compile-time context",
|
||||||
errCannotInferTypeOfTheLiteral: "cannot infer the type of the $1",
|
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",
|
errUser: "$1",
|
||||||
warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]",
|
warnCannotOpenFile: "cannot open \'$1\' [CannotOpenFile]",
|
||||||
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]",
|
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored [OctalEscape]",
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type
|
||||||
|
|
||||||
TExprFlag* = enum
|
TExprFlag* = enum
|
||||||
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
|
efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
|
||||||
efAllowDestructor, efWantValue
|
efAllowDestructor, efWantValue, efOperand
|
||||||
TExprFlags* = set[TExprFlag]
|
TExprFlags* = set[TExprFlag]
|
||||||
|
|
||||||
PContext* = ref TContext
|
PContext* = ref TContext
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
|
||||||
|
|
||||||
proc semOperand(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
|
# 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:
|
if result.kind == nkEmpty:
|
||||||
# do not produce another redundant error message:
|
# do not produce another redundant error message:
|
||||||
#raiseRecoverableError("")
|
#raiseRecoverableError("")
|
||||||
|
|
@ -1218,6 +1218,7 @@ proc semReturn(c: PContext, n: PNode): PNode =
|
||||||
|
|
||||||
proc semProcBody(c: PContext, n: PNode): PNode =
|
proc semProcBody(c: PContext, n: PNode): PNode =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
|
|
||||||
result = semExpr(c, n)
|
result = semExpr(c, n)
|
||||||
if c.p.resultSym != nil and not isEmptyType(result.typ):
|
if c.p.resultSym != nil and not isEmptyType(result.typ):
|
||||||
# transform ``expr`` to ``result = expr``, but not if the expr is already
|
# 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)
|
result = semAsgn(c, a)
|
||||||
else:
|
else:
|
||||||
discardCheck(c, result)
|
discardCheck(c, result)
|
||||||
|
|
||||||
|
if c.p.resultSym != nil and c.p.resultSym.typ.isMetaType:
|
||||||
|
localError(c.p.resultSym.info, errCannotInferReturnType)
|
||||||
|
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
|
|
||||||
proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
||||||
|
|
|
||||||
|
|
@ -944,13 +944,15 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
|
localError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s)
|
||||||
#if efDetermineType notin flags:
|
#if efDetermineType notin flags:
|
||||||
# XXX not good enough; see tnamedparamanonproc.nim
|
# 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)
|
pushProcCon(c, s)
|
||||||
addResult(c, s.typ.sons[0], n.info, skProc)
|
addResult(c, s.typ.sons[0], n.info, skProc)
|
||||||
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos]))
|
||||||
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
||||||
addResultNode(c, n)
|
addResultNode(c, n)
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
|
elif efOperand notin flags:
|
||||||
|
localError(n.info, errGenericLambdaNotAllowed)
|
||||||
sideEffectsCheck(c, s)
|
sideEffectsCheck(c, s)
|
||||||
else:
|
else:
|
||||||
localError(n.info, errImplOfXexpected, s.name.s)
|
localError(n.info, errImplOfXexpected, s.name.s)
|
||||||
|
|
|
||||||
7
tests/generics/tbadgenericlambda.nim
Normal file
7
tests/generics/tbadgenericlambda.nim
Normal 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
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
output: "10\n10\n1\n2\n3"
|
output: "10\n10\n1\n2\n3\n15"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc test(x: proc (a, b: int): int) =
|
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):
|
foreach(@[1,2,3]) do (x):
|
||||||
echo x
|
echo x
|
||||||
|
|
||||||
|
proc foo =
|
||||||
|
let x = proc (a, b: int): auto = a + b
|
||||||
|
echo x(5, 10)
|
||||||
|
|
||||||
|
foo()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue