summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2014-03-15 11:23:46 +0200
committerZahary Karadjov <zahary@gmail.com>2014-03-16 20:42:06 +0200
commitcf8fe16a48d79d149f6ce85e229d23c1513c2497 (patch)
treefa231d9755120954f4f9b66b7e32528e98f3b1cc /compiler
parent7080d02af47cdc459aa441baa76d06f32af2f1c3 (diff)
downloadNim-cf8fe16a48d79d149f6ce85e229d23c1513c2497.tar.gz
fix #715 again
the regression was caused by the introduction of "generic" lambdas
Diffstat (limited to 'compiler')
-rw-r--r--compiler/msgs.nim6
-rw-r--r--compiler/semdata.nim2
-rw-r--r--compiler/semexprs.nim7
-rw-r--r--compiler/semstmts.nim4
4 files changed, 16 insertions, 3 deletions
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index c75876843..3e5a56e1e 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -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]", 
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 84e017050..088b93fae 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -42,7 +42,7 @@ type
 
   TExprFlag* = enum 
     efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
-    efAllowDestructor, efWantValue
+    efAllowDestructor, efWantValue, efOperand
   TExprFlags* = set[TExprFlag]
 
   PContext* = ref TContext
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 62a816a50..ba2847835 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -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) =
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index edce7c9bd..15bfaab10 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -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)