fixes #23564; hasCustomPragma skips alises types (#24994)

fixes #23564

perhaps handle generic aliases (tyGenericInst for aliases types) if
needed
This commit is contained in:
ringabout
2025-06-27 16:18:12 +08:00
committed by GitHub
parent 3ce38f2959
commit 7e6fa9e2d6
5 changed files with 37 additions and 11 deletions

View File

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

View File

@@ -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;
@@ -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)
@@ -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)
@@ -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:
@@ -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:
@@ -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

View File

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

View File

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

View File

@@ -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())