diff options
author | metagn <metagngn@gmail.com> | 2023-04-23 12:43:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-23 17:43:59 +0800 |
commit | 380dafcc32abed83148f5da78a2aaef608831f8a (patch) | |
tree | c39cb15fa3eb4533e6d6a2a5c140ec7ae2292dc9 | |
parent | 265a340e807a44c63c31ba7ffda1f68f6f887624 (diff) | |
download | Nim-380dafcc32abed83148f5da78a2aaef608831f8a.tar.gz |
fix iterator equality + add test for proc equality + fix sameType (#21707)
* fix iterator equality + add test also for procs fixes #21706 * all targets * and isNil and repr * separate overloads, fix sameType * more restricted sameType? * merge overloads again?? * remove sametype change for now * fix sameType anyway (CI failure was not related) --------- Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
-rw-r--r-- | compiler/sigmatch.nim | 2 | ||||
-rw-r--r-- | compiler/types.nim | 6 | ||||
-rw-r--r-- | lib/system.nim | 2 | ||||
-rw-r--r-- | lib/system/comparisons.nim | 2 | ||||
-rw-r--r-- | lib/system/repr_v2.nim | 2 | ||||
-rw-r--r-- | tests/system/tcomparisons.nim | 51 | ||||
-rw-r--r-- | tests/typerel/tproctypeclass.nim | 13 |
7 files changed, 73 insertions, 5 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ad88ed7b2..19fa0b599 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -372,7 +372,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType = of tyOwned: # bug #11257: the comparison system.`==`[T: proc](x, y: T) works # better without the 'owned' type: - if f != nil and f.len > 0 and f[0].skipTypes({tyBuiltInTypeClass}).kind == tyProc: + if f != nil and f.len > 0 and f[0].skipTypes({tyBuiltInTypeClass, tyOr}).kind == tyProc: result = t.lastSon else: result = t diff --git a/compiler/types.nim b/compiler/types.nim index 387429567..d2517127a 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1235,7 +1235,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = assert a[0].len == 0 assert b.len == 1 assert b[0].len == 0 - result = a[0].kind == b[0].kind + result = a[0].kind == b[0].kind and sameFlags(a[0], b[0]) + if result and a[0].kind == tyProc and IgnoreCC notin c.flags: + let ecc = a[0].flags * {tfExplicitCallConv} + result = ecc == b[0].flags * {tfExplicitCallConv} and + (ecc == {} or a[0].callConv == b[0].callConv) of tyGenericInvocation, tyGenericBody, tySequence, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyLent, tySink, tyUncheckedArray, tyArray, tyProc, tyVarargs, tyOrdinal, tyCompositeTypeClass, tyUserTypeClass, tyUserTypeClassInst, diff --git a/lib/system.nim b/lib/system.nim index dcf09d604..f23242315 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1405,7 +1405,7 @@ proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".} proc isNil*[T](x: ptr T): bool {.noSideEffect, magic: "IsNil".} proc isNil*(x: pointer): bool {.noSideEffect, magic: "IsNil".} proc isNil*(x: cstring): bool {.noSideEffect, magic: "IsNil".} -proc isNil*[T: proc](x: T): bool {.noSideEffect, magic: "IsNil".} +proc isNil*[T: proc | iterator {.closure.}](x: T): bool {.noSideEffect, magic: "IsNil".} ## Fast check whether `x` is nil. This is sometimes more efficient than ## `== nil`. diff --git a/lib/system/comparisons.nim b/lib/system/comparisons.nim index 36d4d06a8..9759c3c99 100644 --- a/lib/system/comparisons.nim +++ b/lib/system/comparisons.nim @@ -35,7 +35,7 @@ proc `==`*[T](x, y: ref T): bool {.magic: "EqRef", noSideEffect.} ## Checks that two `ref` variables refer to the same item. proc `==`*[T](x, y: ptr T): bool {.magic: "EqRef", noSideEffect.} ## Checks that two `ptr` variables refer to the same item. -proc `==`*[T: proc](x, y: T): bool {.magic: "EqProc", noSideEffect.} +proc `==`*[T: proc | iterator](x, y: T): bool {.magic: "EqProc", noSideEffect.} ## Checks that two `proc` variables refer to the same procedure. proc `<=`*[Enum: enum](x, y: Enum): bool {.magic: "LeEnum", noSideEffect.} diff --git a/lib/system/repr_v2.nim b/lib/system/repr_v2.nim index 206b5c5f5..e9a6596fd 100644 --- a/lib/system/repr_v2.nim +++ b/lib/system/repr_v2.nim @@ -94,7 +94,7 @@ proc repr*(p: pointer): string = result[j] = HexChars[n and 0xF] n = n shr 4 -proc repr*(p: proc): string = +proc repr*(p: proc | iterator {.closure.}): string = ## repr of a proc as its address repr(cast[ptr pointer](unsafeAddr p)[]) diff --git a/tests/system/tcomparisons.nim b/tests/system/tcomparisons.nim new file mode 100644 index 000000000..a661b14a1 --- /dev/null +++ b/tests/system/tcomparisons.nim @@ -0,0 +1,51 @@ +discard """ + targets: "c cpp js" +""" + +template main = + block: # proc equality + var prc: proc(): int {.closure.} + prc = nil + doAssert prc == nil + doAssert prc.isNil + prc = proc(): int = + result = 123 + doAssert prc != nil + doAssert not prc.isNil + doAssert prc == prc + let prc2 = prc + doAssert prc == prc2 + doAssert prc2 != nil + doAssert not prc2.isNil + doAssert not prc.isNil + prc = proc(): int = + result = 456 + doAssert prc != nil + doAssert not prc.isNil + doAssert prc != prc2 + block: # iterator equality + when nimvm: discard # vm does not support closure iterators + else: + when not defined(js): # js also does not support closure iterators + var iter: iterator(): int {.closure.} + iter = nil + doAssert iter == nil + doAssert iter.isNil + iter = iterator(): int = + yield 123 + doAssert iter != nil + doAssert not iter.isNil + doAssert iter == iter + let iter2 = iter + doAssert iter == iter2 + doAssert iter2 != nil + doAssert not iter2.isNil + doAssert not iter.isNil + iter = iterator(): int = + yield 456 + doAssert iter != nil + doAssert not iter.isNil + doAssert iter != iter2 + +static: main() +main() diff --git a/tests/typerel/tproctypeclass.nim b/tests/typerel/tproctypeclass.nim index 4df9c558b..e8fab9780 100644 --- a/tests/typerel/tproctypeclass.nim +++ b/tests/typerel/tproctypeclass.nim @@ -73,4 +73,17 @@ proc main = doAssert closureProc is proc takesAnyProc(closureProc) + block: # supposed to test that sameType works + template ensureNotRedefine(Ty): untyped = + proc foo[T: Ty](x: T) = discard + doAssert not (compiles do: + proc bar[T: Ty](x: T) = discard + proc bar[T: Ty](x: T) = discard) + ensureNotRedefine proc + ensureNotRedefine iterator + ensureNotRedefine proc {.nimcall.} + ensureNotRedefine iterator {.nimcall.} + ensureNotRedefine proc {.closure.} + ensureNotRedefine iterator {.closure.} + main() |