mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
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>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
@@ -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.}
|
||||
|
||||
@@ -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)[])
|
||||
|
||||
|
||||
51
tests/system/tcomparisons.nim
Normal file
51
tests/system/tcomparisons.nim
Normal file
@@ -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()
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user