Skip to content

fixes #23564; hasCustomPragma skips alises types #24994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1873,7 +1873,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
else:
stackTrace(c, tos, pc, "node has no type")
else:
of 3:
# getTypeImpl opcode:
ensureKind(rkNode)
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
Expand All @@ -1882,6 +1882,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
else:
stackTrace(c, tos, pc, "node has no type")
else:
# getTypeInstSkipAlias opcode:
ensureKind(rkNode)
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc], c.idgen, skipAlias = true)
elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen, skipAlias = true)
else:
stackTrace(c, tos, pc, "node has no type")
of opcNGetSize:
decodeBImm(rkInt)
let n = regs[rb].node
Expand Down
16 changes: 9 additions & 7 deletions compiler/vmdeps.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ proc atomicTypeX(s: PSym; info: TLineInfo): PNode =
result.info = info

proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator;
inst=false; allowRecursionX=false): PNode
inst=false; allowRecursionX=false; skipAlias = false): PNode

proc mapTypeToBracketX(cache: IdentCache; name: string; m: TMagic; t: PType; info: TLineInfo;
idgen: IdGenerator;
Expand Down Expand Up @@ -70,7 +70,7 @@ proc objectNode(cache: IdentCache; n: PNode; idgen: IdGenerator): PNode =

proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
idgen: IdGenerator;
inst=false; allowRecursionX=false): PNode =
inst=false; allowRecursionX=false; skipAlias = false): PNode =
var allowRecursion = allowRecursionX
template atomicType(name, m): untyped = atomicTypeX(cache, name, m, t, info, idgen)
template atomicType(s): untyped = atomicTypeX(s, info)
Expand All @@ -91,7 +91,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
id
template newIdentDefs(s): untyped = newIdentDefs(s, s.typ)

if inst and not allowRecursion and t.sym != nil:
if inst and not allowRecursion and t.sym != nil and
not (skipAlias and t.kind == tyAlias):
# getTypeInst behavior: return symbol
return atomicType(t.sym)

Expand Down Expand Up @@ -124,7 +125,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
if t.base != nil:
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
result.add atomicType("typeDesc", mTypeDesc)
result.add mapTypeToAst(t.base, info)
result.add mapTypeToAstX(cache, t.base, info, idgen, inst, skipAlias = skipAlias)
else:
result = atomicType("typeDesc", mTypeDesc)
of tyGenericInvocation:
Expand Down Expand Up @@ -153,7 +154,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
else:
result = mapTypeToAst(t.typeBodyImpl, info)
of tyAlias:
result = mapTypeToAstX(cache, t.skipModifier, info, idgen, inst, allowRecursion)
result = mapTypeToAstX(cache, t.skipModifier, info, idgen, inst, allowRecursion, skipAlias = skipAlias)
of tyOrdinal:
result = mapTypeToAst(t.skipModifier, info)
of tyDistinct:
Expand Down Expand Up @@ -325,8 +326,9 @@ proc opMapTypeToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGene

# the "Inst" version includes generic parameters in the resulting type tree
# and also tries to look like the corresponding Nim type declaration
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator): PNode =
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false)
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator; skipAlias = false): PNode =
# skipAlias: skips aliases and typedesc
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false, skipAlias = skipAlias)

# the "Impl" version includes generic parameters in the resulting type tree
# and also tries to look like the corresponding Nim type implementation
Expand Down
3 changes: 2 additions & 1 deletion compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1337,7 +1337,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMag
of "getType": 0
of "typeKind": 1
of "getTypeInst": 2
else: 3 # "getTypeImpl"
of "getTypeImpl": 3 # "getTypeImpl"
else: 4 # getTypeInstSkipAlias
c.gABC(n, opcNGetType, dest, tmp, rc)
c.freeTemp(tmp)
#genUnaryABC(c, n, dest, opcNGetType)
Expand Down
7 changes: 5 additions & 2 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1575,11 +1575,14 @@ proc extractTypeImpl(n: NimNode): NimNode =
result = n[2]
else: error("Invalid node to retrieve type implementation of: " & $n.kind)


proc getTypeInstSkipAlias(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}

proc customPragmaNode(n: NimNode): NimNode =
result = nil
expectKind(n, {nnkSym, nnkDotExpr, nnkBracketExpr, nnkTypeOfExpr, nnkType, nnkCheckedFieldExpr})
let
typ = n.getTypeInst()

let typ = n.getTypeInstSkipAlias()

if typ.kind == nnkBracketExpr and typ.len > 1 and typ[1].kind == nnkProcTy:
return typ[1][1]
Expand Down
11 changes: 11 additions & 0 deletions tests/pragmas/tcustom_pragma.nim
Original file line number Diff line number Diff line change
Expand Up @@ -538,3 +538,14 @@ block: # https://forum.nim-lang.org/t/12522, backticks
type Test = object
field {.`mypragma`.}: int
doAssert Test().field.hasCustomPragma(mypragma)


block:
template p {.pragma.}

func foo[T0](v: T0): bool =
type T = T0
T.hasCustomPragma(p)

type X {.p.} = object
doAssert foo(X())