mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-14 23:53:47 +00:00
progress
This commit is contained in:
@@ -176,9 +176,6 @@ type
|
||||
#writtenTypes: seq[PType] # types written in this module, to be unloaded later
|
||||
#writtenSyms: seq[PSym] # symbols written in this module, to be unloaded later
|
||||
writtenPackages: HashSet[string]
|
||||
writtenTypeNames: HashSet[string] # NIF names of type defs already emitted;
|
||||
# `exactReplica` copies share the canonical
|
||||
# type's uniqueId and thus its NIF name
|
||||
|
||||
proc isLocalSym(sym: PSym): bool {.inline.} =
|
||||
## Every symbol is emitted as a *global* (module-suffixed) name so that its
|
||||
@@ -351,17 +348,7 @@ proc writeType(w: var Writer; dest: var TokenBuf; typ: PType) =
|
||||
# module (or nowhere), leaving dangling references (e.g. `symbol has no
|
||||
# offset` for a `pointer` type whose itemId.module drifted away).
|
||||
typ.state = Sealed
|
||||
let name = typeToNifSym(typ, w.infos.config)
|
||||
if w.writtenTypeNames.containsOrIncl(name):
|
||||
# BACKSTOP: uniqueId is unique per instance since `exactReplica` mints
|
||||
# fresh ones, so two defs should never share a NIF name anymore.
|
||||
# Should an id collision slip through regardless, duplicate defs are
|
||||
# load-order POISON (the loader keys types by name; results.nim's
|
||||
# Result body was once shadowed by a meta replica, silently nil-ing
|
||||
# return types downstream) — degrade to a reference to the first def.
|
||||
dest.addSymUse pool.syms.getOrIncl(name), NoLineInfo
|
||||
else:
|
||||
writeTypeDef(w, dest, typ)
|
||||
writeTypeDef(w, dest, typ)
|
||||
else:
|
||||
dest.addSymUse pool.syms.getOrIncl(typeToNifSym(typ, w.infos.config)), NoLineInfo
|
||||
|
||||
@@ -456,29 +443,7 @@ proc shouldWriteSymDef(w: var Writer; sym: PSym): bool {.inline.} =
|
||||
return true # Normal case for global symbols
|
||||
return false
|
||||
|
||||
proc canonicalRoutine(sym: PSym): PSym {.inline.} =
|
||||
## A forward declaration and its implementation are merged in sem into a single
|
||||
## surviving symbol (the prototype). The discarded impl symbol is orphaned but
|
||||
## can still be reachable from the surviving routine's AST — e.g. as the `owner`
|
||||
## of a `[T: tuple]`-style generic-param constraint type created while the impl
|
||||
## header was being processed. If we serialized that dead symbol it would get
|
||||
## its own module-global sdef, be indexed, and the importer would then see two
|
||||
## identical overloads -> "ambiguous call". The dead symbol is recognisable
|
||||
## because its `ast` is the shared routine node whose name no longer points back
|
||||
## at it (it points at the survivor). Collapse to the survivor. Writer-only /
|
||||
## IC-specific: from-source compilation never serialises, so this cannot affect
|
||||
## the non-IC path.
|
||||
result = sym
|
||||
if sym != nil and sym.kindImpl in routineKinds:
|
||||
let a = sym.astImpl
|
||||
if a != nil and a.len > namePos and a[namePos].kind == nkSym:
|
||||
let canon = a[namePos].sym
|
||||
if canon != nil and canon != sym and canon.name.id == sym.name.id and
|
||||
canon.itemId.module == sym.itemId.module:
|
||||
result = canon
|
||||
|
||||
proc writeSym(w: var Writer; dest: var TokenBuf; sym: PSym) =
|
||||
let sym = canonicalRoutine(sym)
|
||||
if sym == nil:
|
||||
dest.addDotToken()
|
||||
elif shouldWriteSymDef(w, sym):
|
||||
@@ -1502,17 +1467,9 @@ proc createTypeStub(c: var DecodeContext; t: SymId): PType =
|
||||
let id = itemId(moduleId(c, suffix).int32, itemVal)
|
||||
let ii = addr c.mods[id.module.FileIndex].index
|
||||
let offs = ii[].getOrDefault(name)
|
||||
if offs.offset == 0 and k == ord(tyNone):
|
||||
# A `tyNone` placeholder (e.g. the type of a symbol-choice node) that is
|
||||
# not present in its owning module's index. Such types are copied during
|
||||
# template/generic instantiation in another module but keep their original
|
||||
# owner, so the owner never serialised them. They carry no information, so
|
||||
# synthesise a fresh, fully-loaded empty type instead of failing.
|
||||
result = PType(itemId: id, uniqueId: id, kind: TTypeKind(k), state: Complete)
|
||||
else:
|
||||
if offs.offset == 0:
|
||||
raiseAssert "symbol has no offset: " & name
|
||||
result = PType(itemId: id, uniqueId: id, kind: TTypeKind(k), state: Partial)
|
||||
if offs.offset == 0:
|
||||
raiseAssert "symbol has no offset: " & name
|
||||
result = PType(itemId: id, uniqueId: id, kind: TTypeKind(k), state: Partial)
|
||||
c.types[name] = (result, offs)
|
||||
|
||||
proc extractLocalSymsFromTree(c: var DecodeContext; n: var Cursor; thisModule: string;
|
||||
|
||||
@@ -455,12 +455,14 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||
of cmdUnknown, cmdNone, cmdIdeTools:
|
||||
rawMessage(conf, errGenerated, "invalid command: " & conf.command)
|
||||
|
||||
if conf.errorCounter == 0 and conf.cmd notin {cmdTcc, cmdDump, cmdNop} and
|
||||
if conf.errorCounter == 0 and conf.cmd notin {cmdTcc, cmdDump, cmdNop, cmdM} and
|
||||
not (conf.cmd == cmdNifC and conf.icBackendStage.len > 0):
|
||||
# Per-module backend stages (cg/emit/merge/link) run as many parallel child
|
||||
# processes; each would print a `[SuccessX]` summary line that misleadingly
|
||||
# reports `out: <the whole compiler>` for a step that only wrote one
|
||||
# `.c.nif`/`.c`. The driving `nim ic` (and koch) reports the real result.
|
||||
# The IC build runs hundreds of internal per-module child processes — the
|
||||
# frontend `nim m` (cmdM) and the per-module backend stages (cg/emit/merge/
|
||||
# link). Each would print a `[SuccessX]` summary that is pure noise (and
|
||||
# misleading: `out: unknownOutput`, or `out: <the whole compiler>` for a
|
||||
# step that only wrote one `.c.nif`/`.c`). The driving `nim ic` (and koch)
|
||||
# reports the real result.
|
||||
if optProfileVM in conf.globalOptions:
|
||||
echo conf.dump(conf.vmProfileData)
|
||||
genSuccessX(conf)
|
||||
|
||||
@@ -2625,6 +2625,14 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
n[genericParamsPos] = proto.ast[genericParamsPos]
|
||||
n[paramsPos] = proto.ast[paramsPos]
|
||||
n[pragmasPos] = proto.ast[pragmasPos]
|
||||
# miscPos holds this definition's *original* generic-param node (kept for
|
||||
# error messages, see setGenericParamsMisc / issue #1713). For an impl that
|
||||
# resolves to a forward decl, that node was analysed under the now-discarded
|
||||
# impl symbol and its generic-param constraint types are owned by it. Adopt
|
||||
# the prototype's miscPos so the discarded impl sym is fully unreachable —
|
||||
# otherwise it leaks (via `proto.ast = n` below) as a type owner and gets
|
||||
# serialized as a phantom duplicate overload under IC.
|
||||
n[miscPos] = proto.ast[miscPos]
|
||||
if n[namePos].kind != nkSym: internalError(c.config, n.info, "semProcAux")
|
||||
n[namePos].sym = proto
|
||||
if importantComments(c.config) and proto.ast.comment.len > 0:
|
||||
|
||||
Reference in New Issue
Block a user