summary refs log tree commit diff stats
path: root/tests/lent
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lent')
-rw-r--r--tests/lent/t16898.nim31
-rw-r--r--tests/lent/t17621.nim15
-rw-r--r--tests/lent/tbasic_lent_check.nim62
-rw-r--r--tests/lent/tlent_from_var.nim107
-rw-r--r--tests/lent/tnot_allowed_lent.nim24
-rw-r--r--tests/lent/tnot_allowed_lent2.nim14
-rw-r--r--tests/lent/tvm.nim21
7 files changed, 274 insertions, 0 deletions
diff --git a/tests/lent/t16898.nim b/tests/lent/t16898.nim
new file mode 100644
index 000000000..a69c6d244
--- /dev/null
+++ b/tests/lent/t16898.nim
@@ -0,0 +1,31 @@
+discard """
+  errormsg: "invalid type: 'lent QuadraticExt' in this context: 'proc (r: var QuadraticExt, a: lent QuadraticExt, b: lent QuadraticExt){.noSideEffect, gcsafe.}' for proc"
+"""
+
+# bug #16898
+type
+  Fp[N: static int, T] = object
+    big: array[N, T]
+
+type
+  QuadraticExt* = concept x
+    ## Quadratic Extension concept (like complex)
+    type BaseField = auto
+    x.c0 is BaseField
+    x.c1 is BaseField
+
+{.experimental:"views".}
+
+func prod(r: var QuadraticExt, a, b: lent QuadraticExt) =
+  discard
+
+type
+  Fp2[N: static int, T] = object
+    c0, c1: Fp[N, T]
+
+# This should be passed by reference,
+# but concepts do not respect the 24 bytes rule
+# or `byref` pragma.
+var r, a, b: Fp2[6, uint64]
+
+prod(r, a, b)
diff --git a/tests/lent/t17621.nim b/tests/lent/t17621.nim
new file mode 100644
index 000000000..e324a963e
--- /dev/null
+++ b/tests/lent/t17621.nim
@@ -0,0 +1,15 @@
+discard """
+  errormsg: "invalid type: 'lent Test' in this context: 'proc (self: lent Test)' for proc"
+"""
+
+# bug #17621
+{.experimental: "views".}
+
+type Test = ref object
+  foo: int
+
+proc modify(self: lent Test) =
+  self.foo += 1
+
+let test = Test(foo: 12)
+modify(test)
diff --git a/tests/lent/tbasic_lent_check.nim b/tests/lent/tbasic_lent_check.nim
new file mode 100644
index 000000000..ce9b89adf
--- /dev/null
+++ b/tests/lent/tbasic_lent_check.nim
@@ -0,0 +1,62 @@
+discard """
+  targets: "c cpp js"
+  output: "1"
+"""
+
+proc viewInto(a: array[4, string]): lent string =
+  result = a[0]
+
+proc passToVar(x: var string) =
+  discard
+
+proc main =
+  let x = ["1", "2", "3", "4"]
+  echo viewInto(x)
+  doAssert(not compiles(passToVar(viewInto(x))))
+
+main()
+
+template main2 = # bug #15958
+  when defined(js):
+    proc sameAddress[T](a, b: T): bool {.importjs: "(# === #)".}
+  else:
+    template sameAddress(a, b): bool = a.unsafeAddr == b.unsafeAddr
+  proc byLent[T](a: T): lent T = a
+  let a = [11,12]
+  let b = @[21,23]
+  let ss = {1, 2, 3, 5}
+  doAssert byLent(a) == [11,12]
+  doAssert sameAddress(byLent(a), a)
+  doAssert byLent(b) == @[21,23]
+  # bug #16073
+  doAssert sameAddress(byLent(b), b)
+  doAssert byLent(ss) == {1, 2, 3, 5}
+  doAssert sameAddress(byLent(ss), ss)
+
+  let r = new(float)
+  r[] = 10.0
+  # bug #16073
+  doAssert byLent(r)[] == 10.0
+
+  when not defined(js): # pending bug https://github.com/timotheecour/Nim/issues/372
+    let p = create(float)
+    p[] = 20.0
+    doAssert byLent(p)[] == 20.0
+
+  proc byLent2[T](a: openArray[T]): lent T = a[0]
+  doAssert byLent2(a) == 11
+  doAssert sameAddress(byLent2(a), a[0])
+  doAssert byLent2(b) == 21
+  doAssert sameAddress(byLent2(b), b[0])
+
+  proc byLent3[T](a: varargs[T]): lent T = a[1]
+  let 
+    x = 10
+    y = 20
+    z = 30
+  doAssert byLent3(x, y, z) == 20
+
+main2()
+when false:
+  # bug: Error: unhandled exception: 'node' is not accessible using discriminant 'kind' of type 'TFullReg' [FieldDefect]
+  static: main2()
diff --git a/tests/lent/tlent_from_var.nim b/tests/lent/tlent_from_var.nim
new file mode 100644
index 000000000..1fb3d0c17
--- /dev/null
+++ b/tests/lent/tlent_from_var.nim
@@ -0,0 +1,107 @@
+discard """
+  output: '''x
+[10, 11, 12, 13]'''
+"""
+
+# bug #14805
+
+type Foo = object
+  a: string
+
+proc bar(f: var Foo): lent string =
+  result = f.a
+
+var foo = Foo(a: "x")
+echo bar(foo)
+
+
+# bug #14878
+
+# proc byLentImpl[T](a: T): lent T = a
+proc byLentVar[T](a: var T): lent T =
+  result = a
+  # result = a.byLentImpl # this doesn't help
+
+var x = 3 # error: cannot take the address of an rvalue of type 'NI *'
+
+var xs = [10,11,12,13] # SIGSEGV
+
+let x2 = x.byLentVar
+
+let xs2 = xs.byLentVar
+echo xs2
+
+# bug #22138
+
+type Xxx = object
+
+type
+  Opt[T] = object
+    case oResultPrivate*: bool
+    of false:
+      discard
+    of true:
+      vResultPrivate*: T
+
+func value*[T: not void](self: Opt[T]): lent T {.inline.} =
+  self.vResultPrivate
+template get*[T: not void](self: Opt[T]): T = self.value()
+
+method connect*(
+  self: Opt[(int, int)]) =
+  discard self.get()[0]
+
+block: # bug #23454
+  type
+    Letter = enum
+      A
+
+    LetterPairs = object
+      values: seq[(Letter, string)]
+
+  iterator items(list: var LetterPairs): lent (Letter, string) =
+    for item in list.values:
+      yield item
+
+  var instance = LetterPairs(values: @[(A, "foo")])
+
+  for (a, _) in instance:
+    case a
+    of A: discard
+
+block: # bug #23454
+  type
+    Letter = enum
+      A
+
+    LetterPairs = object
+      values: seq[(Letter, string)]
+
+  iterator items(list: var LetterPairs): var (Letter, string) =
+    for item in list.values.mItems:
+      yield item
+
+  var instance = LetterPairs(values: @[(A, "foo")])
+
+  for (a, _) in instance:
+    case a
+    of A: discard
+
+block: # bug #24034
+  type T = object
+    v: array[100, byte]
+
+
+  iterator pairs(t: T): (int, lent array[100, byte]) =
+    yield (0, t.v)
+
+
+  block:
+    for a, b in default(T):
+      doAssert a == 0
+      doAssert b.len == 100
+
+  block:
+    for (a, b) in pairs(default(T)):
+      doAssert a == 0
+      doAssert b.len == 100
diff --git a/tests/lent/tnot_allowed_lent.nim b/tests/lent/tnot_allowed_lent.nim
new file mode 100644
index 000000000..a1db6d184
--- /dev/null
+++ b/tests/lent/tnot_allowed_lent.nim
@@ -0,0 +1,24 @@
+discard """
+  errormsg: "expression has no address"
+"""
+type
+  MyObject = object
+    x: seq[string]
+
+proc mytest1(s: MyObject, i: int): lent string =
+  ## works fine
+  if i < s.x.len - 1 and s.x[i] != "":
+    result = s.x[i]
+  else: raise newException(KeyError, "err1")
+
+proc mytest2(s: MyObject, i: int): lent string =
+  ## reject due to if expr
+  if i < s.x.len - 1 and s.x[i] != "": s.x[i]
+  else: raise newException(KeyError, "err1")
+
+for i in 1..5:
+  var x = MyObject(x: @["1", "2", "3"])
+  echo mytest1(x, 1)
+  echo mytest2(x, 1)
+
+
diff --git a/tests/lent/tnot_allowed_lent2.nim b/tests/lent/tnot_allowed_lent2.nim
new file mode 100644
index 000000000..d0c958df3
--- /dev/null
+++ b/tests/lent/tnot_allowed_lent2.nim
@@ -0,0 +1,14 @@
+discard """
+  errormsg: "'x' cannot be assigned to"
+  line: 10
+"""
+
+proc bug14498 =
+  var a = @['a', 'b', 'c', 'd', 'e', 'f']
+
+  for x in a:
+    x = 'c'
+
+  echo a
+
+bug14498()
diff --git a/tests/lent/tvm.nim b/tests/lent/tvm.nim
new file mode 100644
index 000000000..5df1d1270
--- /dev/null
+++ b/tests/lent/tvm.nim
@@ -0,0 +1,21 @@
+block: # issue #17527
+  iterator items2[IX, T](a: array[IX, T]): lent T {.inline.} =
+    var i = low(IX)
+    if i <= high(IX):
+      while true:
+        yield a[i]
+        if i >= high(IX): break
+        inc(i)
+
+  proc main() =
+    var s: seq[string] = @[]
+    for i in 0..<3:
+      for (key, val) in items2([("any", "bar")]):
+        s.add $(i, key, val)
+    doAssert s == @[
+      "(0, \"any\", \"bar\")",
+      "(1, \"any\", \"bar\")",
+      "(2, \"any\", \"bar\")"
+    ]
+
+  static: main()