summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/extccomp.nim2
-rw-r--r--compiler/sem.nim7
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--compiler/semstmts.nim19
-rw-r--r--compiler/semtempl.nim5
-rw-r--r--compiler/semtypes.nim15
-rw-r--r--compiler/vm.nim2
7 files changed, 29 insertions, 23 deletions
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index ae2971b65..473911b84 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -759,7 +759,7 @@ proc getLinkCmd(conf: ConfigRef; output: AbsoluteFile,
 template getLinkCmd(conf: ConfigRef; output: AbsoluteFile, objfiles: string): string =
   getLinkCmd(conf, output, objfiles, optGenDynLib in conf.globalOptions)
 
-template tryExceptOSErrorMessage(conf: ConfigRef; errorPrefix: string = "", body: untyped): typed =
+template tryExceptOSErrorMessage(conf: ConfigRef; errorPrefix: string = "", body: untyped) =
   try:
     body
   except OSError:
diff --git a/compiler/sem.nim b/compiler/sem.nim
index d4e944028..a4e6a427b 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -407,12 +407,11 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
   else:
     case s.typ.sons[0].kind
     of tyUntyped:
-      # BUGFIX: we cannot expect a type here, because module aliases would not
-      # work then (see the ``tmodulealias`` test)
-      # semExprWithType(c, result)
+      # Not expecting a type here allows templates like in ``tmodulealias.in``.
       result = semExpr(c, result, flags)
     of tyTyped:
-      result = semStmt(c, result, flags)
+      # More restrictive version.
+      result = semExprWithType(c, result, flags)
     of tyTypeDesc:
       if result.kind == nkStmtList: result.kind = nkStmtListType
       var typ = semTypeNode(c, result, nil)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 6261efaaa..767a13f3e 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1985,7 +1985,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
 
   if ids.len > 0:
     dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info)
-    dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "typed").newSymNode # return type
+    dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "untyped").newSymNode # return type
     ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type
     ids.add c.graph.emptyNode # no default value
     dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids)
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 7f0910429..be7d9a1bf 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1356,7 +1356,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
     localError(c.config, n.info, errNoSymbolToBorrowFromFound)
 
 proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) =
-  if t != nil:
+  if owner == skMacro or t != nil:
     var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), info)
     s.typ = t
     incl(s.flags, sfUsed)
@@ -1550,17 +1550,17 @@ proc activate(c: PContext, n: PNode) =
       discard
 
 proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
-  if s.typ.sons[0] != nil and not isInlineIterator(s):
+  if s.kind == skMacro:
     let resultType =
-      if s.kind == skMacro:
-        if s.typ.sons[0].kind == tyTypeDesc:
-          s.typ.sons[0]
-        else:
-          sysTypeFromName(c.graph, n.info, "NimNode")
-      else:
+      if s.typ.sons[0] != nil and s.typ.sons[0].kind == tyTypeDesc:
         s.typ.sons[0]
+      else:
+        sysTypeFromName(c.graph, n.info, "NimNode")
     addResult(c, resultType, n.info, s.kind)
     addResultNode(c, n)
+  elif s.typ.sons[0] != nil and not isInlineIterator(s):
+    addResult(c, s.typ.sons[0], n.info, s.kind)
+    addResultNode(c, n)
 
 proc canonType(c: PContext, t: PType): PType =
   if t.kind == tySequence:
@@ -1888,7 +1888,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
           # context as it may even be evaluated in 'system.compiles':
           trackProc(c, s, s.ast[bodyPos])
       else:
-        if s.typ.sons[0] != nil and kind != skIterator:
+        if (s.typ.sons[0] != nil and kind != skIterator) or kind == skMacro:
           addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nil, n.info))
 
         openScope(c)
@@ -2015,7 +2015,6 @@ proc semMacroDef(c: PContext, n: PNode): PNode =
     let param = t.n.sons[i].sym
     if param.typ.kind != tyUntyped: allUntyped = false
   if allUntyped: incl(s.flags, sfAllUntyped)
-  if t.sons[0] == nil: localError(c.config, n.info, "macro needs a return type")
   if n.sons[bodyPos].kind == nkEmpty:
     localError(c.config, n.info, errImplOfXexpected % s.name.s)
 
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 2cbbd7b54..7a56f8c45 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -606,11 +606,6 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
       if n.sons[genericParamsPos].kind == nkEmpty:
         # we have a list of implicit type parameters:
         n.sons[genericParamsPos] = gp
-    # no explicit return type? -> use tyTyped
-    if n.sons[paramsPos].sons[0].kind == nkEmpty:
-      # use ``stmt`` as implicit result type
-      s.typ.sons[0] = newTypeS(tyTyped, c)
-      s.typ.n.sons[0] = newNodeIT(nkType, n.info, s.typ.sons[0])
   else:
     s.typ = newTypeS(tyProc, c)
     # XXX why do we need tyTyped as a return type again?
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 86cb0f35b..dd9aea0f8 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -855,6 +855,7 @@ proc findEnforcedStaticType(t: PType): PType =
   # This handles types such as `static[T] and Foo`,
   # which are subset of `static[T]`, hence they could
   # be treated in the same way
+  if t == nil: return nil
   if t.kind == tyStatic: return t
   if t.kind == tyAnd:
     for s in t.sons:
@@ -868,7 +869,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
       var a = copySym(param)
       a.typ = staticType.base
       addDecl(c, a)
-    elif param.typ.kind == tyTypeDesc:
+    elif param.typ != nil and param.typ.kind == tyTypeDesc:
       addDecl(c, param)
     else:
       # within a macro, every param has the type NimNode!
@@ -1194,6 +1195,18 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
   if n.sons[0].kind != nkEmpty:
     r = semTypeNode(c, n.sons[0], nil)
 
+  if r != nil and kind in {skMacro, skTemplate} and r.kind == tyTyped:
+    # XXX: To implement the propesed change in the warning, just
+    # delete this entire if block. The rest is (at least at time of
+    # writing this comment) already implemented.
+    let info = n.sons[0].info
+    const msg = "`typed` will change its meaning in future versions of Nim. " &
+                "`void` or no return type declaration at all has the same " &
+                "meaning as the current meaning of `typed` as return type " &
+                "declaration."
+    message(c.config, info, warnDeprecated, msg)
+    r = nil
+
   if r != nil:
     # turn explicit 'void' return type into 'nil' because the rest of the
     # compiler only checks for 'nil':
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 6fc2626f7..aa8203a92 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1104,7 +1104,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         #echo "new pc ", newPc, " calling: ", prc.name.s
         var newFrame = PStackFrame(prc: prc, comesFrom: pc, next: tos)
         newSeq(newFrame.slots, prc.offset+ord(isClosure))
-        if not isEmptyType(prc.typ.sons[0]) or prc.kind == skMacro:
+        if not isEmptyType(prc.typ.sons[0]):
           putIntoReg(newFrame.slots[0], getNullValue(prc.typ.sons[0], prc.info, c.config))
         for i in 1 .. rc-1:
           newFrame.slots[i] = regs[rb+i]