mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-01 10:52:14 +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>
(cherry picked from commit 380dafcc32)
This commit is contained in:
@@ -362,7 +362,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
|
||||
|
||||
@@ -1223,7 +1223,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,
|
||||
|
||||
@@ -1619,7 +1619,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.}
|
||||
|
||||
@@ -88,7 +88,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()
|
||||
Reference in New Issue
Block a user