Add hasClosure to std/typetraits (#17501)
* fix nim js cmp fails at CT * Add `hasClosure` to `std/effecttraits` * type * Update changelog.md Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> * Update lib/std/effecttraits.nim Co-authored-by: Timothee Cour <timothee.cour2@gmail.com> Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
04520c0ce4
commit
81e54c1d30
4 changed files with 109 additions and 0 deletions
|
|
@ -246,6 +246,8 @@
|
|||
|
||||
- Added dollar `$` and `len` for `jsre.RegExp`.
|
||||
|
||||
- Added `hasClosure` to `std/typetraits`.
|
||||
|
||||
|
||||
## Language changes
|
||||
|
||||
|
|
|
|||
|
|
@ -316,3 +316,7 @@ proc registerAdditionalOps*(c: PCtx) =
|
|||
let fn = getNode(a, 0)
|
||||
setResult(a, (fn.typ != nil and tfNoSideEffect in fn.typ.flags) or
|
||||
(fn.kind == nkSym and fn.sym.kind == skFunc))
|
||||
|
||||
registerCallback c, "stdlib.typetraits.hasClosureImpl", proc (a: VmArgs) =
|
||||
let fn = getNode(a, 0)
|
||||
setResult(a, fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure))
|
||||
|
|
|
|||
|
|
@ -263,3 +263,14 @@ since (1, 1):
|
|||
|
||||
type T2 = T
|
||||
genericParamsImpl(T2)
|
||||
|
||||
|
||||
proc hasClosureImpl(n: NimNode): bool = discard "see compiler/vmops.nim"
|
||||
|
||||
proc hasClosure*(fn: NimNode): bool {.since: (1, 5, 1).} =
|
||||
## Return true if the func/proc/etc `fn` has `closure`.
|
||||
## `fn` has to be a resolved symbol of kind `nnkSym`. This
|
||||
## implies that the macro that calls this proc should accept `typed`
|
||||
## arguments and not `untyped` arguments.
|
||||
expectKind fn, nnkSym
|
||||
result = hasClosureImpl(fn)
|
||||
|
|
|
|||
92
tests/stdlib/ttypetraits.nim
Normal file
92
tests/stdlib/ttypetraits.nim
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
discard """
|
||||
targets: "c cpp js"
|
||||
"""
|
||||
|
||||
import std/typetraits
|
||||
|
||||
|
||||
|
||||
macro testClosure(fn: typed, flag: static bool) =
|
||||
if flag:
|
||||
doAssert hasClosure(fn)
|
||||
else:
|
||||
doAssert not hasClosure(fn)
|
||||
|
||||
block:
|
||||
proc h1() =
|
||||
echo 1
|
||||
|
||||
testClosure(h1, false)
|
||||
|
||||
proc h2() {.nimcall.} =
|
||||
echo 2
|
||||
|
||||
testClosure(h2, false)
|
||||
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
proc hello() {.nimcall.} =
|
||||
echo 3
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, false)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
proc hello() =
|
||||
echo 3
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, false)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
var x = 0
|
||||
proc hello() =
|
||||
echo 3
|
||||
inc x
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, true)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
var x = 0
|
||||
proc hello() {.closure.} =
|
||||
echo 3
|
||||
inc x
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, true)
|
||||
|
||||
block:
|
||||
proc fn(): auto =
|
||||
var x = 0
|
||||
proc hello() {.closure.} =
|
||||
echo 3
|
||||
inc x
|
||||
hello
|
||||
|
||||
let name = fn()
|
||||
testClosure(name, true)
|
||||
|
||||
let name2 = name
|
||||
testClosure(name2, true)
|
||||
|
||||
block:
|
||||
iterator hello(): int =
|
||||
yield 1
|
||||
|
||||
testClosure(hello, false)
|
||||
|
||||
when not defined(js):
|
||||
block:
|
||||
iterator hello(): int {.closure.}=
|
||||
yield 1
|
||||
|
||||
testClosure(hello, true)
|
||||
Loading…
Add table
Add a link
Reference in a new issue