allow typed/untyped in magic procs (#12911)

This commit is contained in:
Timothee Cour 2019-12-17 10:07:32 +00:00 • committed by Andreas Rumpf
commit e8f4586c68
2 changed files with 20 additions and 6 deletions

View file

@ -1119,6 +1119,10 @@ proc newProcType(c: PContext; info: TLineInfo; prev: PType = nil): PType =
# usual we desperately try to save memory: # usual we desperately try to save memory:
result.n.add newNodeI(nkEffectList, info) result.n.add newNodeI(nkEffectList, info)
proc isMagic(sym: PSym): bool =
let nPragmas = sym.ast[pragmasPos]
return hasPragma(nPragmas, wMagic)
proc semProcTypeNode(c: PContext, n, genericParams: PNode, proc semProcTypeNode(c: PContext, n, genericParams: PNode,
prev: PType, kind: TSymKind; isType=false): PType = prev: PType, kind: TSymKind; isType=false): PType =
# for historical reasons (code grows) this is invoked for parameter # for historical reasons (code grows) this is invoked for parameter
@ -1148,11 +1152,13 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
if hasType: if hasType:
typ = semParamType(c, a[^2], constraint) typ = semParamType(c, a[^2], constraint)
var owner = getCurrOwner(c).owner let sym = getCurrOwner(c)
var owner = sym.owner
# TODO: Disallow typed/untyped in procs in the compiler/stdlib # TODO: Disallow typed/untyped in procs in the compiler/stdlib
if (owner.kind != skModule or owner.owner.name.s != "stdlib") and if kind == skProc and (typ.kind == tyTyped or typ.kind == tyUntyped):
kind == skProc and (typ.kind == tyTyped or typ.kind == tyUntyped): if not isMagic(sym):
localError(c.config, a[^2].info, "'" & typ.sym.name.s & "' is only allowed in templates and macros") if (owner.kind != skModule or (owner.owner.name.s != "stdlib")):
localError(c.config, a[^2].info, "'" & typ.sym.name.s & "' is only allowed in templates and macros or magic procs")
if hasDefault: if hasDefault:
def = a[^1] def = a[^1]

View file

@ -1,7 +1,15 @@
discard """ discard """
errormsg: "'untyped' is only allowed in templates and macros" errormsg: "'untyped' is only allowed in templates and macros or magic procs"
line: 6 line: 14
""" """
# magic procs are allowed with `untyped`
proc declaredInScope2*(x: untyped): bool {.magic: "DefinedInScope", noSideEffect, compileTime.}
proc bar(): bool =
var x = 1
declaredInScope2(x)
static: doAssert bar()
# but not non-magic procs
proc fun(x:untyped)=discard proc fun(x:untyped)=discard
fun(10) fun(10)