mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-27 07:18:15 +00:00
fixes #25140
This commit is contained in:
@@ -1559,6 +1559,8 @@ macro expandMacros*(body: typed): untyped =
|
||||
echo body.toStrLit
|
||||
result = body
|
||||
|
||||
proc getTypeInstSkipAlias(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.}
|
||||
|
||||
proc extractTypeImpl(n: NimNode): NimNode =
|
||||
## attempts to extract the type definition of the given symbol
|
||||
case n.kind
|
||||
@@ -1573,11 +1575,17 @@ proc extractTypeImpl(n: NimNode): NimNode =
|
||||
result = n[0].getImpl()
|
||||
of nnkTypeDef:
|
||||
result = n[2]
|
||||
if result.kind notin {nnkSym, nnkObjectTy, nnkRefTy, nnkPtrTy, nnkBracketExpr}:
|
||||
# Handle typeof() and similar unresolvable type expressions
|
||||
let typSym = if n[0].kind == nnkPragmaExpr: n[0][0] else: n[0]
|
||||
if typSym.kind == nnkSym:
|
||||
let resolved = typSym.getTypeInstSkipAlias()
|
||||
if resolved.kind == nnkSym:
|
||||
return resolved.getImpl.extractTypeImpl()
|
||||
error("Invalid node to retrieve type implementation of: " & $result.kind)
|
||||
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})
|
||||
@@ -1618,6 +1626,15 @@ proc customPragmaNode(n: NimNode): NimNode =
|
||||
var typDef = getImpl(typInst)
|
||||
while typDef != nil:
|
||||
typDef.expectKind(nnkTypeDef)
|
||||
# Resolve typeof() and similar unresolvable type expressions
|
||||
if typDef[2].kind notin {nnkSym, nnkObjectTy, nnkRefTy, nnkPtrTy, nnkBracketExpr}:
|
||||
let typSym = if typDef[0].kind == nnkPragmaExpr: typDef[0][0] else: typDef[0]
|
||||
if typSym.kind == nnkSym:
|
||||
let resolved = typSym.getTypeInstSkipAlias()
|
||||
if resolved.kind == nnkSym:
|
||||
typDef = getImpl(resolved)
|
||||
continue
|
||||
break
|
||||
let typ = typDef[2].extractTypeImpl()
|
||||
if typ.kind notin {nnkRefTy, nnkPtrTy, nnkObjectTy}: break
|
||||
let isRef = typ.kind in {nnkRefTy, nnkPtrTy}
|
||||
|
||||
@@ -549,3 +549,20 @@ block:
|
||||
|
||||
type X {.p.} = object
|
||||
doAssert foo(X())
|
||||
|
||||
block: # typeof() type alias preserves field pragmas
|
||||
template myFieldPragma {.pragma.}
|
||||
type Orig = object
|
||||
x {.myFieldPragma.}: int
|
||||
|
||||
var orig: Orig
|
||||
|
||||
# Direct typeof alias
|
||||
type TAlias = typeof(orig)
|
||||
var a: TAlias
|
||||
doAssert a.x.hasCustomPragma(myFieldPragma)
|
||||
|
||||
# Indirect alias of typeof alias
|
||||
type TAlias2 = TAlias
|
||||
var b: TAlias2
|
||||
doAssert b.x.hasCustomPragma(myFieldPragma)
|
||||
|
||||
Reference in New Issue
Block a user