Made generic type classes work with types using static parameters (#21528)

This commit is contained in:
Jason Beetham
2023-03-17 03:17:08 -06:00
committed by GitHub
parent fd4e3ae3e4
commit a9d0124b5d
2 changed files with 53 additions and 4 deletions

View File

@@ -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]

View File

@@ -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 == @[]