Allow void macro result (#11286)
* allow void macro result * add test for void macro result type
This commit is contained in:
parent
68b5e3e3fe
commit
f94ec363ab
25 changed files with 143 additions and 60 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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':
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue