remove the need for the .procvar annotation

This commit is contained in:
Andreas Rumpf
2017-04-03 16:35:41 +02:00
parent e8cfa14354
commit 08f5087d2c
4 changed files with 37 additions and 30 deletions

View File

@@ -514,8 +514,17 @@ proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
markSideEffect(tracked, s)
mergeLockLevels(tracked, n, s.getLockLevel)
proc procVarcheck(n: PNode) =
if n.kind in nkSymChoices:
for x in n: procVarCheck(x)
elif n.kind == nkSym and n.sym.magic != mNone:
localError(n.info, errXCannotBePassedToProcVar, n.sym.name.s)
proc notNilCheck(tracked: PEffects, n: PNode, paramType: PType) =
let n = n.skipConv
procVarcheck skipConvAndClosure(n)
#elif n.kind in nkSymChoices:
# echo "came here"
if paramType != nil and tfNotNil in paramType.flags and
n.typ != nil and tfNotNil notin n.typ.flags:
if n.kind == nkAddr:

View File

@@ -71,27 +71,29 @@ proc toCover(t: PType): BiggestInt =
else:
result = lengthOrd(skipTypes(t, abstractVar-{tyTypeDesc}))
proc performProcvarCheck(c: PContext, info: TLineInfo, s: PSym) =
## Checks that the given symbol is a proper procedure variable, meaning
## that it
var smoduleId = getModule(s).id
if sfProcvar notin s.flags and s.typ.callConv == ccDefault and
smoduleId != c.module.id:
block outer:
for module in c.friendModules:
if smoduleId == module.id:
break outer
localError(info, errXCannotBePassedToProcVar, s.name.s)
when false:
proc performProcvarCheck(c: PContext, info: TLineInfo, s: PSym) =
## Checks that the given symbol is a proper procedure variable, meaning
## that it
var smoduleId = getModule(s).id
if sfProcvar notin s.flags and s.typ.callConv == ccDefault and
smoduleId != c.module.id:
block outer:
for module in c.friendModules:
if smoduleId == module.id:
break outer
localError(info, errXCannotBePassedToProcVar, s.name.s)
proc semProcvarCheck(c: PContext, n: PNode) =
var n = n.skipConv
if n.kind in nkSymChoices:
for x in n:
if x.sym.kind in {skProc, skMethod, skConverter, skIterator}:
performProcvarCheck(c, n.info, x.sym)
elif n.kind == nkSym and n.sym.kind in {skProc, skMethod, skConverter,
skIterator}:
performProcvarCheck(c, n.info, n.sym)
template semProcvarCheck(c: PContext, n: PNode) =
when false:
var n = n.skipConv
if n.kind in nkSymChoices:
for x in n:
if x.sym.kind in {skProc, skMethod, skConverter, skIterator}:
performProcvarCheck(c, n.info, x.sym)
elif n.kind == nkSym and n.sym.kind in {skProc, skMethod, skConverter,
skIterator}:
performProcvarCheck(c, n.info, n.sym)
proc semProc(c: PContext, n: PNode): PNode

View File

@@ -1003,16 +1003,6 @@ Nim supports these `calling conventions`:idx:\:
Most calling conventions exist only for the Windows 32-bit platform.
Assigning/passing a procedure to a procedural variable is only allowed if one
of the following conditions hold:
1) The procedure that is accessed resides in the current module.
2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma <#pragmas-procvar-pragma>`_).
3) The procedure has a calling convention that differs from ``nimcall``.
4) The procedure is anonymous.
The rules' purpose is to prevent the case that extending a non-``procvar``
procedure with default parameters breaks client code.
The default calling convention is ``nimcall``, unless it is an inner proc (a
proc inside of a proc). For an inner proc an analysis is performed whether it
accesses its environment. If it does so, it has the calling convention

View File

@@ -112,6 +112,12 @@ found `here <http://nim-lang.org/docs/manual.html#pragmas-used-pragma>`_.
This is particularly useful for DSLs that help in tree construction.
Language changes
----------------
- The ``.procvar`` annotation is not required anymore. That doesn't mean you
can pass ``system.$`` to ``map`` just yet though.
Bugfixes
--------