mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-05 15:08:44 +00:00
IC: progress
This commit is contained in:
@@ -157,6 +157,14 @@ proc ownsRuntimeRoutine(s: PSym; modPos: int): bool =
|
||||
## - generic instances (`sfFromGeneric`): emitted by demand, deduped by merge;
|
||||
## - `importc`/`compileTime`/`error`/forward sentinels and meta signatures:
|
||||
## not real codegen targets.
|
||||
## - method DISPATCHERS (`sfDispatcher`): their bodies are (re)synthesized into
|
||||
## the main TU by `emitMethodDispatchers`/`generateIfMethodDispatchers`, never
|
||||
## per module. A dispatcher is a `copySym` clone of the method that shares the
|
||||
## method's body sub-tree (incl. its closure iterator); transforming it here
|
||||
## would lambda-lift that SHARED iterator a SECOND time under a different owner
|
||||
## identity, baking a conflicting `up` field → "up references do not agree"
|
||||
## (the divergence is impossible in non-IC, where the dispatcher body is empty
|
||||
## at lift time). So a dispatcher is never an owned runtime routine.
|
||||
## A `{.closure.}` iterator IS a standalone runtime routine (unlike an inline
|
||||
## iterator, which is expanded at each call site) and must be emitted by its
|
||||
## owner — else a cross-module `for` over it links to nothing.
|
||||
@@ -166,6 +174,7 @@ proc ownsRuntimeRoutine(s: PSym; modPos: int): bool =
|
||||
s.skipGenericOwner != nil and s.skipGenericOwner.kind == skModule and
|
||||
s.magic == mNone and
|
||||
sfFromGeneric notin s.flags and
|
||||
sfDispatcher notin s.flags and
|
||||
{sfForward, sfImportc, sfCompileTime, sfError} * s.flags == {} and
|
||||
s.typ != nil and not signatureHasMetaType(s.typ) and
|
||||
s.ast != nil and s.ast.safeLen > bodyPos and
|
||||
|
||||
2
koch.nim
2
koch.nim
@@ -619,7 +619,7 @@ proc runIcTestFile(inp: string) =
|
||||
const icSuite = ["thallo", "tconverter", "timp", "tmiscs", "tparseutils",
|
||||
"tcompiletimeglobal", "tsighashstable", "tpureenum", "tgenericoffer",
|
||||
"tconverterreexport", "ttypeoffer", "ttransitiveoffer",
|
||||
"tmodsymref"]
|
||||
"tmodsymref", "tmethupref"]
|
||||
|
||||
proc icTest(args: string) =
|
||||
temp("")
|
||||
|
||||
15
tests/ic/tmethupref.nim
Normal file
15
tests/ic/tmethupref.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
discard """
|
||||
output: '''42'''
|
||||
"""
|
||||
|
||||
# Regression test: a `{.base.}` method whose body holds a closure iterator with a
|
||||
# nested capturing closure must not crash the IC backend. The method's dispatcher
|
||||
# (a `copySym` clone sharing the iterator) must NOT be lambda-lifted per module;
|
||||
# otherwise the shared iterator's `up` field is baked twice under divergent owner
|
||||
# identities -> "up references do not agree" / "could not determine closure type"
|
||||
# (the real-world symptom: ~all libp2p async `{.base.}` methods failed under
|
||||
# `nim ic`). Fixed by excluding `sfDispatcher` from nifbackend.ownsRuntimeRoutine.
|
||||
|
||||
import mmethupref
|
||||
let b = Base(val: 40)
|
||||
echo b.compute()
|
||||
Reference in New Issue
Block a user