diff --git a/tests/sandwich/config.nims b/tests/sandwich/config.nims new file mode 100644 index 000000000000..85506fdcadb6 --- /dev/null +++ b/tests/sandwich/config.nims @@ -0,0 +1 @@ +switch("experimental", "typeBoundOps") diff --git a/tests/sandwich/mcontext_thread_local.nim b/tests/sandwich/mcontext_thread_local.nim new file mode 100644 index 000000000000..718888328d53 --- /dev/null +++ b/tests/sandwich/mcontext_thread_local.nim @@ -0,0 +1,15 @@ +# context_thread_local +import ./mtasks, ./mlistdeques + +export mlistdeques # Exporting the type with destructor doesn't help +# export tasks # solution 1. Exporting the inner type + +type MagicCompile = object + dq: ListDeque[Task] + +# var x: MagicCompile # solution 2. Instantiating the type with destructors +echo "Success" + +type + TLContext* = object + deque*: ListDeque[Task] diff --git a/tests/sandwich/mfiles.nim b/tests/sandwich/mfiles.nim new file mode 100644 index 000000000000..fb36ecf5a920 --- /dev/null +++ b/tests/sandwich/mfiles.nim @@ -0,0 +1,11 @@ +import mhandles + +type + File* = ref object + handle: Handle[FD] + +proc close*[T: File](f: T) = + f.handle.close() + +proc newFile*(fd: FD): File = + File(handle: initHandle(FD -1)) diff --git a/tests/sandwich/mhandles.nim b/tests/sandwich/mhandles.nim new file mode 100644 index 000000000000..45b143e2c5da --- /dev/null +++ b/tests/sandwich/mhandles.nim @@ -0,0 +1,19 @@ +type + FD* = distinct cint + +type + AnyFD* = concept fd + close(fd) + +proc close*(fd: FD) = + discard + +type + Handle*[T: AnyFD] = object + fd: T + +proc close*[T: AnyFD](h: var Handle[T]) = + close h.fd + +proc initHandle*[T: AnyFD](fd: T): Handle[T] = + Handle[T](fd: fd) diff --git a/tests/sandwich/mitems.nim b/tests/sandwich/mitems.nim new file mode 100644 index 000000000000..ea9d7e7246d7 --- /dev/null +++ b/tests/sandwich/mitems.nim @@ -0,0 +1,52 @@ +import sets, hashes + +type + Fruit* = ref object + id*: int + + # Generic implementation. This doesn't work + EntGroup*[T] = ref object + freed*: HashSet[T] + +proc hash*(self: Fruit): Hash = hash(self.id) + +## +## VVV The Generic implementation. This doesn't work VVV +## + +proc initEntGroup*[T: Fruit](): EntGroup[T] = + result = EntGroup[T]() + result.freed = initHashSet[Fruit]() + var apple = Fruit(id: 20) + result.freed.incl(apple) + +proc get*[T: Fruit](fg: EntGroup[T]): T = + if len(fg.freed) == 0: return + # vvv It errors here + # type mismatch: ([1] fg.freed: HashSet[grouptest.Fruit]) + for it in fg.freed: + return it + +## +## VVV The Non-Generic implementation works VVV +## +type + # Non-generic implementation. This works. + FruitGroup* = ref object + freed*: HashSet[Fruit] + +proc initFruitGroup*(): FruitGroup = + result = FruitGroup() + result.freed = initHashSet[Fruit]() + var apple = Fruit(id: 20) + result.freed.incl(apple) + +proc getNoGeneric*(fg: FruitGroup): Fruit = + if len(fg.freed) == 0: return + for it in fg.freed: + return it + +proc `$`*(self: Fruit): string = + # For echo + if self == nil: return "Fruit()" + return "Fruit(" & $(self.id) & ")" diff --git a/tests/sandwich/mlistdeques.nim b/tests/sandwich/mlistdeques.nim new file mode 100644 index 000000000000..ae18ffaa42fa --- /dev/null +++ b/tests/sandwich/mlistdeques.nim @@ -0,0 +1,35 @@ +# listdeques + +# needed, type bound ops aren't considered for undeclared procs +type Placeholder = object +proc allocate(_: Placeholder) = discard +proc delete(_: Placeholder) = discard + +type + StealableTask* = concept task, var mutTask, type T + task is ptr + task.prev is T + task.next is T + task.parent is T + task.fn is proc (param: pointer) {.nimcall.} + allocate(mutTask) + delete(task) + + ListDeque*[T: StealableTask] = object + head, tail: T + +func isEmpty*(dq: ListDeque): bool {.inline.} = + discard + +func popFirst*[T](dq: var ListDeque[T]): T = + discard + +proc `=destroy`*[T: StealableTask](dq: var ListDeque[T]) = + mixin delete + if dq.isEmpty(): + return + + while (let task = dq.popFirst(); not task.isNil): + delete(task) + + delete(dq.head) diff --git a/tests/sandwich/mobjhash.nim b/tests/sandwich/mobjhash.nim index 409c31ff9095..ec342f5f6997 100644 --- a/tests/sandwich/mobjhash.nim +++ b/tests/sandwich/mobjhash.nim @@ -67,3 +67,14 @@ proc `==`*(a, b: GenericObj4): bool = proc hash*(a: GenericObj4): Hash = !$(hash(a.x) !& hash(a.y)) + +type + GenericRefObj*[T] = ref object + x*, y*: T + z*: string # to be ignored for equality + +proc `==`*[T](a, b: GenericRefObj[T]): bool = + a.x == b.x and a.y == b.y + +proc hash*[T](a: GenericRefObj[T]): Hash = + !$(hash(a.x) !& hash(a.y)) diff --git a/tests/sandwich/mqueuecontainer.nim b/tests/sandwich/mqueuecontainer.nim new file mode 100644 index 000000000000..3ddbc5a3a94b --- /dev/null +++ b/tests/sandwich/mqueuecontainer.nim @@ -0,0 +1,13 @@ +# original example used queues +import deques + +type + QueueContainer*[T] = object + q: ref Deque[T] + +proc init*[T](c: var QueueContainer[T]) = + new(c.q) + c.q[] = initDeque[T](64) + +proc addToQ*[T](c: var QueueContainer[T], item: T) = + c.q[].addLast(item) diff --git a/tests/sandwich/msetin.nim b/tests/sandwich/msetin.nim new file mode 100644 index 000000000000..7aa44df6c554 --- /dev/null +++ b/tests/sandwich/msetin.nim @@ -0,0 +1,10 @@ +import std/sets +template foo*[T](a: T) = +# proc foo*[T](a: T) = # works + var s: HashSet[T] + # echo contains(s, a) # works + let x = a in s # BUG + doAssert not x + doAssert not (a in s) + doAssert a notin s +when isMainModule: foo(1) # works diff --git a/tests/sandwich/msetiter1.nim b/tests/sandwich/msetiter1.nim new file mode 100644 index 000000000000..8049dcf9c848 --- /dev/null +++ b/tests/sandwich/msetiter1.nim @@ -0,0 +1,7 @@ +import sets + +proc initH*[V]: HashSet[V] = + result = initHashSet[V]() + +proc foo*[V](h: var HashSet[V], c: seq[V]) = + h = h + c.toHashSet() diff --git a/tests/sandwich/msetiter2.nim b/tests/sandwich/msetiter2.nim new file mode 100644 index 000000000000..b78175b31089 --- /dev/null +++ b/tests/sandwich/msetiter2.nim @@ -0,0 +1,4 @@ +import sets, sequtils + +proc dedupe*[T](arr: openArray[T]): seq[T] = + arr.toHashSet.toSeq diff --git a/tests/sandwich/mtasks.nim b/tests/sandwich/mtasks.nim new file mode 100644 index 000000000000..f585f4f7b4ff --- /dev/null +++ b/tests/sandwich/mtasks.nim @@ -0,0 +1,14 @@ +# tasks.nim +type + Task* = ptr object + parent*: Task + prev*: Task + next*: Task + fn*: proc (param: pointer) {.nimcall.} + +# StealableTask API +proc allocate*(task: var Task) = + discard + +proc delete*(task: Task) = + discard diff --git a/tests/sandwich/tcontext_thread_local.nim b/tests/sandwich/tcontext_thread_local.nim new file mode 100644 index 000000000000..f015014b8e8f --- /dev/null +++ b/tests/sandwich/tcontext_thread_local.nim @@ -0,0 +1,12 @@ +discard """ + output: ''' +Success +''' +""" + +# modified issue #12620, see placeholder procs in mlistdeques + +# runtime.nim +import ./mcontext_thread_local + +var localCtx* : TLContext diff --git a/tests/sandwich/tfilehandles.nim b/tests/sandwich/tfilehandles.nim new file mode 100644 index 000000000000..3bed18dfae8d --- /dev/null +++ b/tests/sandwich/tfilehandles.nim @@ -0,0 +1,8 @@ +# issue #16755 + +import mfiles +from mhandles import FD +#import handles <- do this and it works + +let wr = newFile(FD -1) +close wr diff --git a/tests/sandwich/titems.nim b/tests/sandwich/titems.nim new file mode 100644 index 000000000000..0c3b41026abb --- /dev/null +++ b/tests/sandwich/titems.nim @@ -0,0 +1,13 @@ +# issue #22984 +# import sets # <<-- Uncomment this to make the error go away + +import mitems + +## The generic implementation +var grp: EntGroup[Fruit] = initEntGroup[Fruit]() +doAssert $get(grp) == "Fruit(20)" ## Errors here + + +## This works though (Non-generic) +var fruitGroup: FruitGroup = initFruitGroup() +doAssert $getNoGeneric(fruitGroup) == "Fruit(20)" diff --git a/tests/sandwich/tobjhash.nim b/tests/sandwich/tobjhash.nim index 6443a99823c3..6c82407e773d 100644 --- a/tests/sandwich/tobjhash.nim +++ b/tests/sandwich/tobjhash.nim @@ -1,6 +1,6 @@ # https://github.com/nim-lang/RFCs/issues/380 -from mobjhash import Obj, RefObj, GenericObj1, GenericObj2, GenericObj3, GenericObj4 +from mobjhash import Obj, RefObj, GenericObj1, GenericObj2, GenericObj3, GenericObj4, GenericRefObj import tables block: @@ -44,3 +44,16 @@ block: t[GenericObj4[float](x: 3, y: 4, z: "debug")] = 34 doAssert t[GenericObj4[float](x: 3, y: 4, z: "ignored")] == 34 doAssert GenericObj4[float](x: 4, y: 3, z: "debug") notin t + +block: + var t: Table[GenericRefObj[float], int] + t[GenericRefObj[float](x: 3, y: 4, z: "debug")] = 34 + doAssert t[GenericRefObj[float](x: 3, y: 4, z: "ignored")] == 34 + doAssert GenericRefObj[float](x: 4, y: 3, z: "debug") notin t + +block: + type LocalAlias[T] = GenericObj4[T] + var t: Table[LocalAlias[float], int] + t[LocalAlias[float](x: 3, y: 4, z: "debug")] = 34 + doAssert t[LocalAlias[float](x: 3, y: 4, z: "ignored")] == 34 + doAssert LocalAlias[float](x: 4, y: 3, z: "debug") notin t diff --git a/tests/sandwich/tqueuecontainer.nim b/tests/sandwich/tqueuecontainer.nim new file mode 100644 index 000000000000..863e44cb7479 --- /dev/null +++ b/tests/sandwich/tqueuecontainer.nim @@ -0,0 +1,10 @@ +# issue #4773 + +import mqueuecontainer + +# works if this is uncommented (or if the `queuecontainer` exports `queues`): +# import queues + +var c: QueueContainer[int] +c.init() +c.addToQ(1) diff --git a/tests/sandwich/tsethash.nim b/tests/sandwich/tsethash.nim new file mode 100644 index 000000000000..ad244d1e66c4 --- /dev/null +++ b/tests/sandwich/tsethash.nim @@ -0,0 +1,24 @@ +# issue #14729 + +import sets, hashes + +type + Iterable[T] = concept x + for value in items(x): + type(value) is T + + Foo[T] = object + t: T + +proc myToSet[T](keys: Iterable[T]): HashSet[T] = + for x in items(keys): result.incl(x) + +proc hash[T](foo: Foo[T]): Hash = + echo "specific hash" + +proc `==`[T](lhs, rhs: Foo[T]): bool = + echo "specific equals" + +let + f = Foo[string](t: "test") + hs = [f, f].myToSet() diff --git a/tests/sandwich/tsetin.nim b/tests/sandwich/tsetin.nim new file mode 100644 index 000000000000..1dd3d2bd9e7c --- /dev/null +++ b/tests/sandwich/tsetin.nim @@ -0,0 +1,4 @@ +# issue #18150 + +import msetin +foo(1) diff --git a/tests/sandwich/tsetiter1.nim b/tests/sandwich/tsetiter1.nim new file mode 100644 index 000000000000..0fa629b079a5 --- /dev/null +++ b/tests/sandwich/tsetiter1.nim @@ -0,0 +1,17 @@ +# comment on issue #11167 + +import hashes + +import msetiter + +type + Choice = object + i: int + +proc hash(c: Choice): Hash = + result = Hash(c.i) + +var h = initH[Choice]() +let c = @[Choice(i: 1)] + +foo(h, c) diff --git a/tests/sandwich/tsetiter2.nim b/tests/sandwich/tsetiter2.nim new file mode 100644 index 000000000000..f89eac075f6d --- /dev/null +++ b/tests/sandwich/tsetiter2.nim @@ -0,0 +1,9 @@ +# comment on issue #11167 + +import msetiter2 + +let x = dedupe([1, 2, 3]) +doAssert x.len == 3 +doAssert 1 in x +doAssert 2 in x +doAssert 3 in x