summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/passes.nim6
-rw-r--r--compiler/semexprs.nim8
-rw-r--r--compiler/semtypes.nim29
-rw-r--r--compiler/sigmatch.nim7
-rw-r--r--compiler/types.nim5
-rw-r--r--tests/reject/tstmtexp.nim2
6 files changed, 35 insertions, 22 deletions
diff --git a/compiler/passes.nim b/compiler/passes.nim
index f1277b839..8d228fe9a 100644
--- a/compiler/passes.nim
+++ b/compiler/passes.nim
@@ -177,7 +177,6 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) =
       s = stream
     while true: 
       openParsers(p, fileIdx, s)
-      var code = p.parseAll
 
       if sfSystemModule notin module.flags:
         # XXX what about caching? no processing then? what if I change the 
@@ -187,7 +186,10 @@ proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) =
         processImplicits implicitImports, nkImportStmt, a
         processImplicits implicitIncludes, nkIncludeStmt, a
 
-      discard processTopLevelStmt(code, a)
+      while true: 
+        var n = parseTopLevelStmt(p)
+        if n.kind == nkEmpty: break 
+        if not processTopLevelStmt(n, a): break
 
       closeParsers(p)
       if s.kind != llsStdIn: break 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 1655da0fd..4f5c4fce5 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1671,11 +1671,17 @@ proc buildCall(n: PNode): PNode =
   else:
     result = n
 
+proc doBlockIsStmtList(n: PNode): bool =
+  result = n.kind == nkDo and
+           n[paramsPos].sonsLen == 1 and
+           n[paramsPos][0].kind == nkEmpty
+
 proc fixImmediateParams(n: PNode): PNode =
   # XXX: Temporary work-around until we carry out
   # the planned overload resolution reforms
   for i in 1 .. <safeLen(n):
-    if n[i].kind == nkDo: n.sons[i] = n[i][bodyPos]
+    if doBlockIsStmtList(n[i]):
+      n.sons[i] = n[i][bodyPos]
   result = n
 
 proc semExport(c: PContext, n: PNode): PNode =
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 2c526f676..cb46dad76 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -570,19 +570,17 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
   # if id is not nil, the generic param will bind just once (see below)
   case paramType.kind:
   of tyExpr:
-    if procKind notin {skTemplate, skMacro}:
-      if paramType.sonsLen == 0:
-        # proc(a, b: expr)
-        # no constraints, treat like generic param
-        result.typ = newTypeS(tyGenericParam, c)
-      else:
-        # proc(a: expr{string}, b: expr{nkLambda})
-        # overload on compile time values and AST trees
-        result.typ = newTypeS(tyExpr, c)
-        result.typ.sons = paramType.sons
+    if paramType.sonsLen == 0:
+      # proc(a, b: expr)
+      # no constraints, treat like generic param
+      result.typ = newTypeS(tyGenericParam, c)
+    else:
+      # proc(a: expr{string}, b: expr{nkLambda})
+      # overload on compile time values and AST trees
+      result.typ = newTypeS(tyExpr, c)
+      result.typ.sons = paramType.sons
   of tyTypeDesc:
-    if procKind notin {skTemplate, skMacro} and 
-       tfInstantiated notin paramType.flags:
+     if tfInstantiated notin paramType.flags:
       result.typ = newTypeS(tyTypeDesc, c)
       result.typ.sons = paramType.sons
   of tyDistinct:
@@ -604,11 +602,16 @@ proc paramTypeClass(c: PContext, paramType: PType, procKind: TSymKind):
 proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
                    paramType: PType, paramName: string,
                    info: TLineInfo): PType =
+  result = paramType
+  if procKind in {skMacro, skTemplate}:
+    # generic param types in macros and templates affect overload
+    # resolution, but don't work as generic params when it comes
+    # to proc instantiation. We don't need to lift such params here.  
+    return
   ## Params having implicit generic types or pseudo types such as 'expr'
   ## need to be added to the generic params lists. 
   ## 'expr' is different from 'expr{string}' so we must first call 
   ## paramTypeClass to get the actual type we are going to use.
-  result = paramType
   var (typeClass, paramTypId) = paramTypeClass(c, paramType, procKind)
   let isAnon = paramTypId == nil
   if typeClass != nil:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index e1882e1fb..0c6bb26e9 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -683,11 +683,12 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
 proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, 
                         arg, argOrig: PNode): PNode =
   var r: TTypeRelation
-  if f.kind == tyExpr:
-    if f.sonsLen == 0:
+  let fMaybeExpr = f.skipTypes({tyDistinct})
+  if fMaybeExpr.kind == tyExpr:
+    if fMaybeExpr.sonsLen == 0:
       r = isGeneric
     else:
-      let match = matchTypeClass(m, f, a)
+      let match = matchTypeClass(m, fMaybeExpr, a)
       if match != isGeneric: r = isNone
       else:
         # XXX: Ideally, this should happen much earlier somewhere near 
diff --git a/compiler/types.nim b/compiler/types.nim
index 6f47a7f2d..3096b73c8 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1016,8 +1016,9 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
   of tyExpr, tyStmt, tyTypeDesc:
     result = true
     # XXX er ... no? these should not be allowed!
-  of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation, 
-      tyTypeClass:
+  of tyTypeClass:
+    result = true
+  of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation:
     result = false
   of tyEmpty, tyNil:
     result = kind == skConst
diff --git a/tests/reject/tstmtexp.nim b/tests/reject/tstmtexp.nim
index 807a70897..7cbf2eb3d 100644
--- a/tests/reject/tstmtexp.nim
+++ b/tests/reject/tstmtexp.nim
@@ -1,6 +1,6 @@
 discard """
   file: "tstmtexp.nim"
-  line: 7
+  line: 8
   errormsg: "value returned by statement has to be discarded"
 """
 # Test 3