summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/generics/tmacroinjectedsym.nim29
-rw-r--r--tests/generics/tmacroinjectedsymwarning.nim50
2 files changed, 79 insertions, 0 deletions
diff --git a/tests/generics/tmacroinjectedsym.nim b/tests/generics/tmacroinjectedsym.nim
index a98c1edb1..d36d34cdd 100644
--- a/tests/generics/tmacroinjectedsym.nim
+++ b/tests/generics/tmacroinjectedsym.nim
@@ -1,3 +1,5 @@
+{.experimental: "genericsOpenSym".}
+
 block: # issue #22605, normal call syntax
   const error = "bad"
 
@@ -16,6 +18,15 @@ block: # issue #22605, normal call syntax
 
   doAssert g(int) == "good"
 
+  proc g2(T: type): string =
+    bind error # use the bad version on purpose
+    let x = valueOr 123:
+      return $error
+
+    "ok"
+
+  doAssert g2(int) == "bad"
+
 block: # issue #22605, method call syntax
   const error = "bad"
 
@@ -34,6 +45,15 @@ block: # issue #22605, method call syntax
 
   doAssert g(int) == "good"
 
+  proc g2(T: type): string =
+    bind error # use the bad version on purpose
+    let x = 123.valueOr:
+      return $error
+
+    "ok"
+
+  doAssert g2(int) == "bad"
+
 block: # issue #22605, original complex example
   type Xxx = enum
     error
@@ -84,3 +104,12 @@ block: # issue #22605, original complex example
     "ok"
 
   doAssert g(int) == "f"
+
+  proc g2(T: type): string =
+    bind error # use the bad version on purpose
+    let x = f().valueOr:
+      return $error
+
+    "ok"
+
+  doAssert g2(int) == "error"
diff --git a/tests/generics/tmacroinjectedsymwarning.nim b/tests/generics/tmacroinjectedsymwarning.nim
new file mode 100644
index 000000000..7adb759e8
--- /dev/null
+++ b/tests/generics/tmacroinjectedsymwarning.nim
@@ -0,0 +1,50 @@
+type Xxx = enum
+  error
+  value
+
+type
+  Result[T, E] = object
+    when T is void:
+      when E is void:
+        oResultPrivate*: bool
+      else:
+        case oResultPrivate*: bool
+        of false:
+          eResultPrivate*: E
+        of true:
+          discard
+    else:
+      when E is void:
+        case oResultPrivate*: bool
+        of false:
+          discard
+        of true:
+          vResultPrivate*: T
+      else:
+        case oResultPrivate*: bool
+        of false:
+          eResultPrivate*: E
+        of true:
+          vResultPrivate*: T
+
+template valueOr[T: not void, E](self: Result[T, E], def: untyped): untyped =
+  let s = (self) # TODO avoid copy
+  case s.oResultPrivate
+  of true:
+    s.vResultPrivate
+  of false:
+    when E isnot void:
+      template error: untyped {.used, inject.} = s.eResultPrivate
+    def
+
+proc f(): Result[int, cstring] =
+  Result[int, cstring](oResultPrivate: false, eResultPrivate: "f")
+
+proc g(T: type): string =
+  let x = f().valueOr:
+    return $error #[tt.Warning
+            ^ a new symbol 'error' has been injected during instantiation of g, however 'error' [enumField declared in tmacroinjectedsymwarning.nim(2, 3)] captured at the proc declaration will be used instead; either enable --experimental:genericsOpenSym to use the injected symbol or `bind` this captured symbol explicitly [GenericsIgnoredInjection]]#
+
+  "ok"
+
+discard g(int)