Skip to content

Commit

Permalink
* fix nim-lang#9855, fix nim-lang#9855, new: getTypeId, fix genericHead
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Jun 8, 2021
1 parent 51ab7cc commit 7bdd1a7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
9 changes: 9 additions & 0 deletions compiler/semmagic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
result = newIntNode(nkIntLit, operand.len - ord(operand.kind==tyProc))
result.typ = newType(tyInt, nextTypeId c.idgen, context)
result.info = traitCall.info
of "getTypeid":
var arg = operand
if arg.kind in NumberLikeTypes:
# needed otherwise we could get different ids, see tests
arg = getSysType(c.graph, traitCall[1].info, arg.kind)
result = newIntNode(nkIntLit, arg.id)
# `id` better than cast[int](arg) so that it's reproducible across compiles
result.typ = getSysType(c.graph, traitCall[1].info, tyInt)
result.info = traitCall.info
of "genericHead":
var arg = operand
case arg.kind
Expand Down
5 changes: 2 additions & 3 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1456,7 +1456,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
elif t.kind != tyGenericBody:
# we likely got code of the form TypeA[TypeB] where TypeA is
# not generic.
localError(c.config, n.info, errNoGenericParamsAllowedForX % s.name.s)
localError(c.config, n.info, errNoGenericParamsAllowedForX % $(s.name.s, t.kind))
return newOrPrevType(tyError, prev, c)
else:
var m = newCandidate(c, t)
Expand Down Expand Up @@ -1927,8 +1927,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
else:
assignType(prev, s.typ)
# bugfix: keep the fresh id for aliases to integral types:
if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
tyUInt..tyUInt64}:
if s.typ.kind notin NumberLikeTypes:
prev.itemId = s.typ.itemId
result = prev
of nkSym:
Expand Down
12 changes: 11 additions & 1 deletion lib/pure/typetraits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@ runnableExamples:
type C[T] = enum h0 = 2, h1 = 4
assert C[float] is HoleyEnum

proc name*(t: typedesc): string {.magic: "TypeTrait".} =
proc getTypeid*(t: typedesc): int {.magic: "TypeTrait", since: (1, 1).} =
## returns a unique id representing a type; the id is stable across
## recompilations of the same program, but may differ if the program source
## changes.
runnableExamples:
type Foo[T] = object
type Foo2 = Foo
doAssert Foo[int].getTypeid == Foo2[type(1)].getTypeid
doAssert Foo[int].getTypeid != Foo[float].getTypeid

proc name*(t: typedesc): string {.magic: "TypeTrait".}
## Returns the name of the given type.
##
## Alias for `system.\`$\`(t) <dollars.html#$,typedesc>`_ since Nim v0.20.
Expand Down
26 changes: 26 additions & 0 deletions tests/metatype/ttypetraits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,29 @@ block: # enum.len
doAssert MyEnum.enumLen == 4
doAssert OtherEnum.enumLen == 3
doAssert MyFlag.enumLen == 4

block: # getTypeid
const c1 = getTypeid(type(12))
const a1 = getTypeid(type(12))
const a2 = getTypeid(type(12))
let a3 = getTypeid(type(12))
doAssert a1 == a2
# we need to check that because nim uses different id's
# for different instances of tyInt (etc), so we make sure implementation of
# `getTypeid` is robust to that
doAssert a1 == a3
doAssert getTypeid(type(12.0)) != getTypeid(type(12))
doAssert getTypeid(type(12.0)) == getTypeid(float)

type Foo = object
x1: int

type FooT[T] = object
x1: int
type Foo2 = Foo
type FooT2 = FooT
doAssert Foo.getTypeid == Foo2.getTypeid
doAssert FooT2.getTypeid == FooT.getTypeid
doAssert FooT2[float].getTypeid == FooT[type(1.2)].getTypeid
doAssert FooT2[float].getTypeid != FooT[type(1)].getTypeid
doAssert Foo.x1.type.getTypeid == int.getTypeid

0 comments on commit 7bdd1a7

Please sign in to comment.