mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
fixes #23564 perhaps handle generic aliases (tyGenericInst for aliases types) if needed
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user