summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semtypinst.nim27
-rw-r--r--tests/metatype/tstatic_generic_typeclass.nim30
2 files changed, 53 insertions, 4 deletions
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 0a0ac1704..0ef1d0898 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -193,6 +193,24 @@ proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode =
     for i in 0..<n.len:
       n[i] = replaceObjBranches(cl, n[i])
 
+proc hasValuelessStatics(n: PNode): bool =
+  # We should only attempt to call an expression that has no tyStatics
+  # As those are unresolved generic parameters, which means in the following
+  # The compiler attempts to do `T == 300` which errors since the typeclass `MyThing` lacks a parameter
+  #[
+    type MyThing[T: static int] = object
+      when T == 300:
+        a
+    proc doThing(_: MyThing)
+  ]#
+  if n.safeLen == 0:
+    n.typ.kind == tyStatic
+  else:
+    for x in n:
+      if hasValuelessStatics(x):
+        return true
+    false
+
 proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
   if n == nil: return
   result = copyNode(n)
@@ -217,10 +235,11 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
       of nkElifBranch:
         checkSonsLen(it, 2, cl.c.config)
         var cond = prepareNode(cl, it[0])
-        var e = cl.c.semConstExpr(cl.c, cond)
-        if e.kind != nkIntLit:
-          internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool")
-        if e.intVal != 0 and branch == nil: branch = it[1]
+        if not cond.hasValuelessStatics:
+          var e = cl.c.semConstExpr(cl.c, cond)
+          if e.kind != nkIntLit:
+            internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool")
+          if e.intVal != 0 and branch == nil: branch = it[1]
       of nkElse:
         checkSonsLen(it, 1, cl.c.config)
         if branch == nil: branch = it[0]
diff --git a/tests/metatype/tstatic_generic_typeclass.nim b/tests/metatype/tstatic_generic_typeclass.nim
new file mode 100644
index 000000000..0e9256a62
--- /dev/null
+++ b/tests/metatype/tstatic_generic_typeclass.nim
@@ -0,0 +1,30 @@
+type MyThing[T: static int] = object
+  when T == 300:
+    a: int
+
+var a = MyThing[300]()
+proc doThing(myThing: MyThing): string = $myThing
+proc doOtherThing[T](myThing: MyThing[T]): string = $myThing
+assert doThing(a) == $a
+assert doThing(MyThing[0]()) == $MyThing[0]()
+assert doOtherThing(a) == "(a: 0)"
+
+type
+  Backend* = enum
+    Cpu,
+    Cuda
+
+  Tensor*[B: static[Backend]; T] = object
+    shape: seq[int]
+    strides: seq[int]
+    offset: int
+    when B == Backend.Cpu:
+      data: seq[T]
+    else:
+      data_ptr: ptr T
+
+template shape*(t: Tensor): seq[int] =
+  t.shape
+
+
+assert Tensor[Cpu, int]().shape == @[]