Fix VM's sametype impl to work for generics/typedescs (#19073)
* Fix vm's sametype implementation to properly handle generics and typedescs * actually fixed sametype + have test * added comments and removed unsafe code
This commit is contained in:
parent
24a7584299
commit
cc984217a9
3 changed files with 65 additions and 1 deletions
|
|
@ -1128,6 +1128,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
|
||||||
a = a.skipTypes({tyDistinct, tyGenericInst})
|
a = a.skipTypes({tyDistinct, tyGenericInst})
|
||||||
if a.kind != b.kind: return false
|
if a.kind != b.kind: return false
|
||||||
|
|
||||||
|
#[
|
||||||
|
The following code should not run in the case either side is an generic alias,
|
||||||
|
but it's not presently possible to distinguish the genericinsts from aliases of
|
||||||
|
objects ie `type A[T] = SomeObject`
|
||||||
|
]#
|
||||||
# this is required by tunique_type but makes no sense really:
|
# this is required by tunique_type but makes no sense really:
|
||||||
if tyDistinct notin {x.kind, y.kind} and x.kind == tyGenericInst and IgnoreTupleFields notin c.flags:
|
if tyDistinct notin {x.kind, y.kind} and x.kind == tyGenericInst and IgnoreTupleFields notin c.flags:
|
||||||
let
|
let
|
||||||
|
|
|
||||||
|
|
@ -1044,7 +1044,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
strictSymEquality=true))
|
strictSymEquality=true))
|
||||||
of opcSameNodeType:
|
of opcSameNodeType:
|
||||||
decodeBC(rkInt)
|
decodeBC(rkInt)
|
||||||
regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil regs[rc].node.typ)
|
regs[ra].intVal = ord(regs[rb].node.typ.sameTypeOrNil(regs[rc].node.typ, {ExactTypeDescValues, ExactGenericParams}))
|
||||||
|
# The types should exactly match which is why we pass `{ExactTypeDescValues..ExactGcSafety}`.
|
||||||
of opcXor:
|
of opcXor:
|
||||||
decodeBC(rkInt)
|
decodeBC(rkInt)
|
||||||
regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
|
regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
|
||||||
|
|
|
||||||
|
|
@ -66,3 +66,61 @@ block: # unpackVarargs
|
||||||
doAssert call1(toString) == ""
|
doAssert call1(toString) == ""
|
||||||
doAssert call1(toString, 10) == "10"
|
doAssert call1(toString, 10) == "10"
|
||||||
doAssert call1(toString, 10, 11) == "1011"
|
doAssert call1(toString, 10, 11) == "1011"
|
||||||
|
|
||||||
|
block: # SameType
|
||||||
|
type
|
||||||
|
A = int
|
||||||
|
B = distinct int
|
||||||
|
C = object
|
||||||
|
Generic[T, Y] = object
|
||||||
|
macro isSameType(a, b: typed): untyped =
|
||||||
|
newLit(sameType(a, b))
|
||||||
|
|
||||||
|
static:
|
||||||
|
assert Generic[int, int].isSameType(Generic[int, int])
|
||||||
|
assert Generic[A, string].isSameType(Generic[int, string])
|
||||||
|
assert not Generic[A, string].isSameType(Generic[B, string])
|
||||||
|
assert not Generic[int, string].isSameType(Generic[int, int])
|
||||||
|
assert isSameType(int, A)
|
||||||
|
assert isSameType(10, 20)
|
||||||
|
assert isSameType("Hello", "world")
|
||||||
|
assert not isSameType("Hello", cstring"world")
|
||||||
|
assert not isSameType(int, B)
|
||||||
|
assert not isSameType(int, Generic[int, int])
|
||||||
|
assert not isSameType(C, string)
|
||||||
|
assert not isSameType(C, int)
|
||||||
|
|
||||||
|
|
||||||
|
#[
|
||||||
|
# compiler sameType fails for the following, read more in `types.nim`'s `sameTypeAux`.
|
||||||
|
type
|
||||||
|
D[T] = C
|
||||||
|
G[T] = T
|
||||||
|
static:
|
||||||
|
assert isSameType(D[int], C)
|
||||||
|
assert isSameType(D[int], D[float])
|
||||||
|
assert isSameType(G[float](1.0), float(1.0))
|
||||||
|
assert isSameType(float(1.0), G[float](1.0))
|
||||||
|
]#
|
||||||
|
|
||||||
|
type Tensor[T] = object
|
||||||
|
data: T
|
||||||
|
|
||||||
|
macro testTensorInt(x: typed): untyped =
|
||||||
|
let
|
||||||
|
tensorIntType = getTypeInst(Tensor[int])[1]
|
||||||
|
xTyp = x.getTypeInst
|
||||||
|
|
||||||
|
newLit(xTyp.sameType(tensorIntType))
|
||||||
|
|
||||||
|
var
|
||||||
|
x: Tensor[int]
|
||||||
|
x1 = Tensor[float]()
|
||||||
|
x2 = Tensor[A]()
|
||||||
|
x3 = Tensor[B]()
|
||||||
|
|
||||||
|
static:
|
||||||
|
assert testTensorInt(x)
|
||||||
|
assert not testTensorInt(x1)
|
||||||
|
assert testTensorInt(x2)
|
||||||
|
assert not testTensorInt(x3)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue