mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-14 03:25:54 +00:00
fixes #25637 This pull request refactors the way the `sfInjectDestructors` flag is set on symbols during lambda lifting in the Nim compiler. The main change is the introduction of a helper procedure to encapsulate the logic for marking symbols that require destructor injection, improving code clarity and maintainability. Refactoring and code quality improvements: * Introduced the `markInjectDestructors` procedure to encapsulate the logic for marking a symbol with the `sfInjectDestructors` flag, ensuring that `backendEnsureMutable` is always called before modifying the symbol's flags. * Replaced direct flag manipulation (`owner.incl sfInjectDestructors` and `prc.incl sfInjectDestructors`) with calls to the new `markInjectDestructors` procedure in multiple locations, including `makeClosure`, `createTypeBoundOpsLL`, and `rawClosureCreation`. [[1]](diffhunk://#diff-19193904ba011a2bcc1e1a9768a7eb57cac57a274cad73d388149776ec2901e6L231-R235) [[2]](diffhunk://#diff-19193904ba011a2bcc1e1a9768a7eb57cac57a274cad73d388149776ec2901e6L243-R247) [[3]](diffhunk://#diff-19193904ba011a2bcc1e1a9768a7eb57cac57a274cad73d388149776ec2901e6L639-R643)
This commit is contained in:
@@ -216,6 +216,10 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
|
||||
result[0] = le
|
||||
result[1] = ri
|
||||
|
||||
proc markInjectDestructors(s: PSym) {.inline.} =
|
||||
backendEnsureMutable s
|
||||
s.flagsImpl.incl sfInjectDestructors
|
||||
|
||||
proc makeClosure*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; env: PNode; info: TLineInfo): PNode =
|
||||
result = newNodeIT(nkClosure, info, prc.typ)
|
||||
result.add(newSymNode(prc))
|
||||
@@ -228,7 +232,7 @@ proc makeClosure*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; env: PNode; inf
|
||||
#if isClosureIterator(result.typ):
|
||||
createTypeBoundOps(g, nil, result.typ, info, idgen)
|
||||
if tfHasAsgn in result.typ.flags or optSeqDestructors in g.config.globalOptions:
|
||||
prc.incl sfInjectDestructors
|
||||
markInjectDestructors(prc)
|
||||
|
||||
template liftingHarmful(conf: ConfigRef; owner: PSym): bool =
|
||||
## lambda lifting can be harmful for JS-like code generators.
|
||||
@@ -240,7 +244,7 @@ proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; idgen
|
||||
createTypeBoundOps(g, nil, refType.elementType, info, idgen)
|
||||
createTypeBoundOps(g, nil, refType, info, idgen)
|
||||
if tfHasAsgn in refType.flags or optSeqDestructors in g.config.globalOptions:
|
||||
owner.incl sfInjectDestructors
|
||||
markInjectDestructors(owner)
|
||||
|
||||
proc genCreateEnv(env: PNode): PNode =
|
||||
var c = newNodeIT(nkObjConstr, env.info, env.typ)
|
||||
@@ -636,7 +640,7 @@ proc rawClosureCreation(owner: PSym;
|
||||
if owner.kind != skMacro:
|
||||
createTypeBoundOps(d.graph, nil, fieldAccess.typ, env.info, d.idgen)
|
||||
if tfHasAsgn in fieldAccess.typ.flags or optSeqDestructors in d.graph.config.globalOptions:
|
||||
owner.incl sfInjectDestructors
|
||||
markInjectDestructors(owner)
|
||||
|
||||
let upField = lookupInRecord(env.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
|
||||
if upField != nil:
|
||||
|
||||
@@ -7,6 +7,7 @@ discard """
|
||||
1.0
|
||||
2.0
|
||||
55
|
||||
@[1, 2]
|
||||
'''
|
||||
"""
|
||||
|
||||
@@ -79,3 +80,14 @@ let x = compute:
|
||||
|
||||
echo x
|
||||
|
||||
# Crash: bridge.nim(206, 5) `allowEmpty` unexpected nkEmpty [AssertionDefect]
|
||||
# Bare closure iterator type alias
|
||||
type IntIter = iterator(): int {.closure.}
|
||||
proc run(it: IntIter): seq[int] =
|
||||
result = @[]
|
||||
for x in it():
|
||||
result.add(x)
|
||||
let gen: IntIter = iterator(): int {.closure.} =
|
||||
yield 1
|
||||
yield 2
|
||||
echo run(gen)
|
||||
|
||||
Reference in New Issue
Block a user