summary refs log tree commit diff stats
path: root/tests/concepts
diff options
context:
space:
mode:
Diffstat (limited to 'tests/concepts')
-rw-r--r--tests/concepts/t3414.nim22
-rw-r--r--tests/concepts/t4982.nim18
-rw-r--r--tests/concepts/t5888.nim26
-rw-r--r--tests/concepts/t5888lib/ca.nim4
-rw-r--r--tests/concepts/t5888lib/opt.nim6
-rw-r--r--tests/concepts/t5968.nim20
-rw-r--r--tests/concepts/t5983.nim22
-rw-r--r--tests/concepts/templatesinconcepts.nim56
-rw-r--r--tests/concepts/texplain.nim18
-rw-r--r--tests/concepts/tgraph.nim39
-rw-r--r--tests/concepts/trandomvars.nim61
-rw-r--r--tests/concepts/twrapconcept.nim22
12 files changed, 288 insertions, 26 deletions
diff --git a/tests/concepts/t3414.nim b/tests/concepts/t3414.nim
new file mode 100644
index 000000000..d45973034
--- /dev/null
+++ b/tests/concepts/t3414.nim
@@ -0,0 +1,22 @@
+type
+  View[T] = concept v
+    v.empty is bool
+    v.front is T
+    popFront v
+
+proc find(view: View; target: View.T): View =
+  result = view
+
+  while not result.empty:
+    if view.front == target:
+      return
+
+    mixin popFront
+    popFront result
+
+proc popFront[T](s: var seq[T]) = discard
+proc empty[T](s: seq[T]): bool = false
+
+var s1 = @[1, 2, 3]
+let s2 = s1.find(10)
+
diff --git a/tests/concepts/t4982.nim b/tests/concepts/t4982.nim
new file mode 100644
index 000000000..9d82c83c9
--- /dev/null
+++ b/tests/concepts/t4982.nim
@@ -0,0 +1,18 @@
+discard """
+errormsg: "undeclared identifier: 'x'"
+line: 10
+"""
+
+import typetraits # without this import the program compiles (and echos false)
+
+type
+  SomeTestConcept = concept t
+    x.name is string # typo: t.name was intended (which would result in echo true)
+
+type
+  TestClass = ref object of RootObj
+    name: string
+
+var test = TestClass(name: "mytest")
+echo $(test is SomeTestConcept)
+
diff --git a/tests/concepts/t5888.nim b/tests/concepts/t5888.nim
new file mode 100644
index 000000000..dbbab8c4c
--- /dev/null
+++ b/tests/concepts/t5888.nim
@@ -0,0 +1,26 @@
+discard """
+output: '''
+true
+true
+true
+f
+0
+'''
+"""
+
+import t5888lib/ca, t5888lib/opt
+
+type LocalCA = ca.CA
+
+proc f(c: CA) =
+  echo "f"
+  echo c.x
+
+var o = new(Opt)
+
+echo o is CA
+echo o is LocalCA
+echo o is ca.CA
+
+o.f()
+
diff --git a/tests/concepts/t5888lib/ca.nim b/tests/concepts/t5888lib/ca.nim
new file mode 100644
index 000000000..4a811f797
--- /dev/null
+++ b/tests/concepts/t5888lib/ca.nim
@@ -0,0 +1,4 @@
+type
+  CA* = concept c
+    c.x is int
+
diff --git a/tests/concepts/t5888lib/opt.nim b/tests/concepts/t5888lib/opt.nim
new file mode 100644
index 000000000..65d16addc
--- /dev/null
+++ b/tests/concepts/t5888lib/opt.nim
@@ -0,0 +1,6 @@
+import ca
+
+type
+  Opt* = object
+    x*: int
+
diff --git a/tests/concepts/t5968.nim b/tests/concepts/t5968.nim
new file mode 100644
index 000000000..adb374c65
--- /dev/null
+++ b/tests/concepts/t5968.nim
@@ -0,0 +1,20 @@
+discard """
+  exitcode: 0
+"""
+
+type
+  Enumerable[T] = concept e
+    for it in e:
+      it is T
+
+proc cmap[T, G](e: Enumerable[T], fn: proc(t: T): G): seq[G] =
+  result = @[]
+  for it in e: result.add(fn(it))
+
+import json
+
+var x = %["hello", "world"]
+
+var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!")
+assert z == @["hello!", "world!"]
+
diff --git a/tests/concepts/t5983.nim b/tests/concepts/t5983.nim
new file mode 100644
index 000000000..e69647448
--- /dev/null
+++ b/tests/concepts/t5983.nim
@@ -0,0 +1,22 @@
+discard """
+  output: "20.0 USD"
+"""
+
+import typetraits
+
+const currencies = ["USD", "EUR"] # in real code 120 currencies
+
+type USD* = distinct float # in real code 120 types generates using macro
+type EUR* = distinct float
+
+type CurrencyAmount = concept c
+  type t = c.type
+  const name = c.type.name
+  name in currencies
+
+proc `$`(x: CurrencyAmount): string =
+  $float(x) & " " & x.name
+
+let amount = 20.USD
+echo amount
+
diff --git a/tests/concepts/templatesinconcepts.nim b/tests/concepts/templatesinconcepts.nim
new file mode 100644
index 000000000..292b97ea6
--- /dev/null
+++ b/tests/concepts/templatesinconcepts.nim
@@ -0,0 +1,56 @@
+import typetraits
+
+template typeLen(x): int = x.type.name.len
+
+template bunchOfChecks(x) =
+  x.typeLen > 3
+  x != 10 is bool
+
+template stmtListExprTmpl(x: untyped): untyped =
+  x is int
+  x
+
+type
+  Obj = object
+    x: int
+
+  Gen[T] = object
+    x: T
+
+  Eq = concept x, y
+    (x == y) is bool
+
+  NotEq = concept x, y
+    (x != y) is bool
+
+  ConceptUsingTemplate1 = concept x
+    echo x
+    sizeof(x) is int
+    bunchOfChecks x
+
+  ConceptUsingTemplate2 = concept x
+    stmtListExprTmpl x
+
+template ok(x) =
+  static: assert(x)
+
+template no(x) =
+  static: assert(not(x))
+
+ok int is Eq
+ok int is NotEq
+ok string is Eq
+ok string is NotEq
+ok Obj is Eq
+ok Obj is NotEq
+ok Gen[string] is Eq
+ok Gen[int] is NotEq
+
+no int is ConceptUsingTemplate1
+ok float is ConceptUsingTemplate1
+no string is ConceptUsingTemplate1
+
+ok int is ConceptUsingTemplate2
+no float is ConceptUsingTemplate2
+no string is ConceptUsingTemplate2
+
diff --git a/tests/concepts/texplain.nim b/tests/concepts/texplain.nim
index 25a075fd1..417d1e502 100644
--- a/tests/concepts/texplain.nim
+++ b/tests/concepts/texplain.nim
@@ -9,33 +9,33 @@ proc e(o: ExplainedConcept): int
 texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo'
 texplain.nim(65, 6) ExplainedConcept: undeclared field: '.'
 texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called
-texplain.nim(65, 5) ExplainedConcept: type class predicate failed
+texplain.nim(65, 5) ExplainedConcept: concept predicate failed
 texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar'
 texplain.nim(66, 6) ExplainedConcept: undeclared field: '.'
 texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called
-texplain.nim(65, 5) ExplainedConcept: type class predicate failed
+texplain.nim(65, 5) ExplainedConcept: concept predicate failed
 
 texplain.nim(105, 10) Hint: Non-matching candidates for e(10)
 proc e(o: ExplainedConcept): int
 texplain.nim(65, 6) ExplainedConcept: undeclared field: 'foo'
 texplain.nim(65, 6) ExplainedConcept: undeclared field: '.'
 texplain.nim(65, 6) ExplainedConcept: expression '.' cannot be called
-texplain.nim(65, 5) ExplainedConcept: type class predicate failed
+texplain.nim(65, 5) ExplainedConcept: concept predicate failed
 texplain.nim(66, 6) ExplainedConcept: undeclared field: 'bar'
 texplain.nim(66, 6) ExplainedConcept: undeclared field: '.'
 texplain.nim(66, 6) ExplainedConcept: expression '.' cannot be called
-texplain.nim(65, 5) ExplainedConcept: type class predicate failed
+texplain.nim(65, 5) ExplainedConcept: concept predicate failed
 
 texplain.nim(109, 20) Error: type mismatch: got (NonMatchingType)
 but expected one of: 
 proc e(o: ExplainedConcept): int
-texplain.nim(65, 5) ExplainedConcept: type class predicate failed
+texplain.nim(65, 5) ExplainedConcept: concept predicate failed
 proc e(i: int): int
 
 texplain.nim(110, 20) Error: type mismatch: got (NonMatchingType)
 but expected one of: 
 proc r(o: RegularConcept): int
-texplain.nim(69, 5) RegularConcept: type class predicate failed
+texplain.nim(69, 5) RegularConcept: concept predicate failed
 proc r[T](a: SomeNumber; b: T; c: auto)
 proc r(i: string): int
 
@@ -49,12 +49,12 @@ proc f(o: NestedConcept)
 texplain.nim(69, 6) RegularConcept: undeclared field: 'foo'
 texplain.nim(69, 6) RegularConcept: undeclared field: '.'
 texplain.nim(69, 6) RegularConcept: expression '.' cannot be called
-texplain.nim(69, 5) RegularConcept: type class predicate failed
+texplain.nim(69, 5) RegularConcept: concept predicate failed
 texplain.nim(70, 6) RegularConcept: undeclared field: 'bar'
 texplain.nim(70, 6) RegularConcept: undeclared field: '.'
 texplain.nim(70, 6) RegularConcept: expression '.' cannot be called
-texplain.nim(69, 5) RegularConcept: type class predicate failed
-texplain.nim(73, 5) NestedConcept: type class predicate failed
+texplain.nim(69, 5) RegularConcept: concept predicate failed
+texplain.nim(73, 5) NestedConcept: concept predicate failed
 '''
   line: 119
   errormsg: "type mismatch: got (MatchingType)"
diff --git a/tests/concepts/tgraph.nim b/tests/concepts/tgraph.nim
index a0177a043..985f04a61 100644
--- a/tests/concepts/tgraph.nim
+++ b/tests/concepts/tgraph.nim
@@ -1,29 +1,34 @@
-discard """
-  output: '''XY is Node
-MyGraph is Graph'''
-"""
 # bug #3452
 import math
 
 type
-    Node* = concept n
-        `==`(n, n) is bool
+  Node* = concept n
+    `==`(n, n) is bool
 
-    Graph* = concept g
-        var x: Node
-        distance(g, x, x) is float
+  Graph1* = concept g
+    type N = Node
+    distance(g, N, N) is float
 
-    XY* = tuple[x, y: int]
+  Graph2 = concept g
+    distance(g, Node, Node) is float
 
-    MyGraph* = object
-        points: seq[XY]
+  Graph3 = concept g
+    var x: Node
+    distance(g, x, x) is float
 
-if XY is Node:
-    echo "XY is Node"
+  XY* = tuple[x, y: int]
+
+  MyGraph* = object
+    points: seq[XY]
+
+static:
+  assert XY is Node
 
 proc distance*( g: MyGraph, a, b: XY): float =
-    sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) )
+  sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) )
 
-if MyGraph is Graph:
-    echo "MyGraph is Graph"
+static:
+  assert MyGraph is Graph1
+  assert MyGraph is Graph2
+  assert MyGraph is Graph3
 
diff --git a/tests/concepts/trandomvars.nim b/tests/concepts/trandomvars.nim
new file mode 100644
index 000000000..db41aa901
--- /dev/null
+++ b/tests/concepts/trandomvars.nim
@@ -0,0 +1,61 @@
+discard """
+output: '''
+true
+true
+true
+3
+18.0
+324.0
+'''
+"""
+
+type RNG = object
+
+proc random(rng: var RNG): float = 1.0
+
+type
+  RandomVar[A] = concept x
+    var rng: RNG
+    rng.sample(x) is A
+
+  Constant[A] = object
+    value: A
+
+  Uniform = object
+    a, b: float
+
+  ClosureVar[A] = proc(rng: var RNG): A
+
+proc sample[A](rng: var RNG, c: Constant[A]): A = c.value
+
+proc sample(rng: var RNG, u: Uniform): float = u.a + (u.b - u.a) * rng.random()
+
+proc sample[A](rng: var RNG, c: ClosureVar[A]): A = c(rng)
+
+proc constant[A](a: A): Constant[A] = Constant[A](value: a)
+
+proc uniform(a, b: float): Uniform = Uniform(a: a, b: b)
+
+proc lift1[A, B](f: proc(a: A): B, r: RandomVar[A]): ClosureVar[B] =
+  proc inner(rng: var RNG): B = f(rng.sample(r))
+
+  return inner
+
+when isMainModule:
+  proc sq(x: float): float = x * x
+
+  let
+    c = constant(3)
+    u = uniform(2, 18)
+    t = lift1(sq, u)
+
+  var rng: RNG
+
+  echo(c is RandomVar[int])
+  echo(u is RandomVar[float])
+  echo(t is RandomVar[float])
+
+  echo rng.sample(c)
+  echo rng.sample(u)
+  echo rng.sample(t)
+
diff --git a/tests/concepts/twrapconcept.nim b/tests/concepts/twrapconcept.nim
new file mode 100644
index 000000000..25a855e34
--- /dev/null
+++ b/tests/concepts/twrapconcept.nim
@@ -0,0 +1,22 @@
+discard """
+  errormsg: "type mismatch: got (string)"
+  line: 21
+  nimout: "twrapconcept.nim(11, 5) Foo: concept predicate failed"
+"""
+
+# https://github.com/nim-lang/Nim/issues/5127
+
+type
+  Foo = concept foo
+    foo.get is int
+  
+  FooWrap[F: Foo] = object
+    foo: F
+
+proc get(x: int): int = x
+
+proc wrap[F: Foo](foo: F): FooWrap[F] = FooWrap[F](foo: foo)
+
+let x = wrap(12)
+let y = wrap "string"
+