mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-28 15:55:14 +00:00
normalizeTypedescMacroResult
This commit is contained in:
@@ -454,6 +454,25 @@ proc resetSemFlag(n: PNode) =
|
||||
for i in 0..<n.safeLen:
|
||||
resetSemFlag(n[i])
|
||||
|
||||
proc normalizeTypedescMacroResult(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
if result.kind == nkStmtList:
|
||||
result.transitionSonsKind(nkStmtListType)
|
||||
|
||||
# Resolve surviving compile-time branches so later passes don't walk
|
||||
# unevaluated type AST for a typedesc expression.
|
||||
while true:
|
||||
if result.kind == nkWhenStmt:
|
||||
result = semWhen(c, result, false)
|
||||
if result.kind == nkStmtList:
|
||||
result.transitionSonsKind(nkStmtListType)
|
||||
elif result.kind == nkStmtListType and result.len > 0 and result[^1].kind == nkWhenStmt:
|
||||
result[^1] = semWhen(c, result[^1], false)
|
||||
if result[^1].kind == nkStmtList:
|
||||
result[^1].transitionSonsKind(nkStmtListType)
|
||||
else:
|
||||
break
|
||||
|
||||
proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
s: PSym, flags: TExprFlags; expectedType: PType = nil): PNode =
|
||||
## Semantically check the output of a macro.
|
||||
@@ -484,19 +503,14 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
# More restrictive version.
|
||||
result = semExprWithType(c, result, flags, expectedType)
|
||||
of tyTypeDesc:
|
||||
if result.kind == nkStmtList: result.transitionSonsKind(nkStmtListType)
|
||||
result = normalizeTypedescMacroResult(c, result)
|
||||
var typ = semTypeNode(c, result, nil)
|
||||
if typ == nil:
|
||||
localError(c.config, result.info, "expression has no type: " &
|
||||
renderTree(result, {renderNoComments}))
|
||||
result = newSymNode(errorSym(c, result))
|
||||
else:
|
||||
# Replace with a clean nkType node so that complex expressions
|
||||
# (like `when` statements from template expansion) don't persist
|
||||
# in the AST with potentially uninitialized children that would
|
||||
# cause a SIGSEGV during the transform phase's constant folding.
|
||||
result = newNodeIT(nkType, result.info, makeTypeDesc(c, typ))
|
||||
#result = symNodeFromType(c, typ, n.info)
|
||||
result.typ = makeTypeDesc(c, typ)
|
||||
else:
|
||||
if s.ast[genericParamsPos] != nil and retType.isMetaType:
|
||||
# The return type may depend on the Macro arguments
|
||||
|
||||
Reference in New Issue
Block a user