This commit is contained in:
araq
2025-11-11 17:04:02 +01:00
parent d4439a1771
commit f5e004376c
15 changed files with 68 additions and 62 deletions

View File

@@ -1212,6 +1212,11 @@ proc excl*(t: PType; flag: TTypeFlag) {.inline.} =
if t.state == Partial: loadType(t)
t.flagsImpl.excl(flag)
proc excl*(t: PType; flags: set[TTypeFlag]) {.inline.} =
assert t.state != Sealed
if t.state == Partial: loadType(t)
t.flagsImpl.excl(flags)
type Gconfig = object
# we put comments in a side channel to avoid increasing `sizeof(TNode)`, which
# reduces memory usage given that `PNode` is the most allocated type by far.
@@ -2114,7 +2119,8 @@ proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) =
owner.incl tfHasGCedMem
proc rawAddSon*(father, son: PType; propagateHasAsgn = true) =
father.sons.add(son)
ensureMutable father
father.sonsImpl.add(son)
if not son.isNil: propagateToOwner(father, son, propagateHasAsgn)
proc addSonNilAllowed*(father, son: PNode) =
@@ -2147,7 +2153,7 @@ proc copyNode*(src: PNode): PNode =
when defined(nimsuggest):
result.endInfo = src.endInfo
template transitionNodeKindCommon(k: TNodeKind) =
template transitionNodeKindCommon(k: TNodeKind) {.dirty.} =
let obj {.inject.} = n[]
n[] = TNode(kind: k, typField: n.typ, info: obj.info, flags: obj.flags)
# n.comment = obj.comment # shouldn't be needed, the address doesnt' change

View File

@@ -29,7 +29,7 @@ proc declareSelf(c: PContext; info: TLineInfo) =
let ow = getCurrOwner(c)
let s = newSym(skType, getIdent(c.cache, "Self"), c.idgen, ow, info)
s.typ = newType(tyTypeDesc, c.idgen, ow)
s.typ.flags.incl {tfUnresolved, tfPacked}
s.typ.incl {tfUnresolved, tfPacked}
s.typ.add newType(tyEmpty, c.idgen, ow)
addDecl(c, s, info)

View File

@@ -990,10 +990,10 @@ proc loadSym(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; s:
proc typeHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
t: PackedType; si, item: int32): PType =
result = PType(itemId: ItemId(module: si, item: t.nonUniqueId), kind: t.kind,
flags: t.flags, size: t.size, align: t.align,
paddingAtEnd: t.paddingAtEnd,
flagsImpl: t.flags, sizeImpl: t.size, alignImpl: t.align,
paddingAtEndImpl: t.paddingAtEnd,
uniqueId: ItemId(module: si, item: item),
callConv: t.callConv)
callConvImpl: t.callConv)
proc typeBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
t: PackedType; si, item: int32; result: PType) =

View File

@@ -150,7 +150,7 @@ template isIterator*(owner: PSym): bool =
proc createEnvObj(g: ModuleGraph; idgen: IdGenerator; owner: PSym; info: TLineInfo): PType =
result = createObj(g, idgen, owner, info, final=false)
result.flags.incl tfFinal
result.incl tfFinal
if owner.isIterator:
rawAddField(result, createStateField(g, owner, idgen))
@@ -290,7 +290,7 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
elif not (owner.typ.isClosure or owner.isNimcall and not owner.isExplicitCallConv or isEnv):
localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" %
[s.name.s, owner.name.s, $owner.typ.callConv])
incl(owner.typ.flags, tfCapturesEnv)
incl(owner.typ, tfCapturesEnv)
if not isEnv:
owner.typ.callConv = ccClosure
@@ -336,7 +336,7 @@ proc asOwnedRef(c: var DetectionPass; t: PType): PType =
if optOwnedRefs in c.graph.config.globalOptions:
assert t.kind == tyRef
result = newType(tyOwned, c.idgen, t.owner)
result.flags.incl tfHasOwned
result.incl tfHasOwned
result.rawAddSon t
else:
result = t

View File

@@ -1168,7 +1168,7 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
incl result.flagsImpl, sfGeneratedOp
if kind == attachedWasMoved:
incl result.flagsImpl, sfNoSideEffect
incl result.typ.flags, tfNoSideEffect
incl result.typ, tfNoSideEffect
proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let xx = genBuiltin(c, mAccessTypeField, "accessTypeField", x)
@@ -1303,11 +1303,11 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
## to ensure we lift assignment, destructors and moves properly.
## The later 'injectdestructors' pass depends on it.
if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.flags != {}: return
incl orig.flags, tfCheckedForDestructor
incl orig, tfCheckedForDestructor
# for user defined generic destructors:
let origRoot = genericRoot(orig)
if origRoot != nil:
incl origRoot.flags, tfGenericHasDestructor
incl origRoot, tfGenericHasDestructor
let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
if isEmptyContainer(skipped) or skipped.kind == tyStatic: return
@@ -1352,5 +1352,5 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
if not isTrivial(getAttachedOp(g, orig, attachedDestructor)):
#or not isTrivial(orig.assignment) or
# not isTrivial(orig.sink):
orig.flags.incl tfHasAsgn
orig.incl tfHasAsgn
# ^ XXX Breaks IC!

View File

@@ -147,7 +147,7 @@ proc createObj*(g: ModuleGraph; idgen: IdGenerator; owner: PSym, info: TLineInfo
result = newType(tyObject, idgen, owner)
if final:
rawAddSon(result, nil)
incl result.flags, tfFinal
incl result, tfFinal
else:
rawAddSon(result, getCompilerProc(g, "RootObj").typ)
result.n = newNodeI(nkRecList, info)

View File

@@ -757,7 +757,7 @@ proc typeBorrow(c: PContext; sym: PSym, n: PNode) =
let it = n[1]
if it.kind != nkAccQuoted:
localError(c.config, n.info, "a type can only borrow `.` for now")
incl(sym.typ.flags, tfBorrowDot)
incl(sym.typ, tfBorrowDot)
proc markCompilerProc(c: PContext; s: PSym) =
# minor hack ahead: FlowVar is the only generic .compilerproc type which
@@ -1026,7 +1026,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
noVal(c, it)
if sym != nil:
incl(sym, sfNoSideEffect)
if sym.typ != nil: incl(sym.typ.flags, tfNoSideEffect)
if sym.typ != nil: incl(sym.typ, tfNoSideEffect)
of wSideEffect:
noVal(c, it)
incl(sym, sfSideEffect)
@@ -1074,7 +1074,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
of wVarargs:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfVarargs)
else: incl(sym.typ, tfVarargs)
of wBorrow:
if sym.kind == skType:
typeBorrow(c, sym, it)
@@ -1084,11 +1084,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
of wFinal:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfFinal)
else: incl(sym.typ, tfFinal)
of wInheritable:
noVal(c, it)
if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(c, it)
else: incl(sym.typ.flags, tfInheritable)
else: incl(sym.typ, tfInheritable)
of wPackage:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
@@ -1096,35 +1096,35 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
of wAcyclic:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfAcyclic)
else: incl(sym.typ, tfAcyclic)
of wShallow:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfShallow)
else: incl(sym.typ, tfShallow)
of wThread:
noVal(c, it)
incl(sym, sfThread)
if sym.typ != nil:
incl(sym.typ.flags, tfThread)
incl(sym.typ, tfThread)
if sym.typ.callConv == ccClosure: sym.typ.callConv = ccNimCall
of wSendable:
noVal(c, it)
if sym != nil and sym.typ != nil:
incl(sym.typ.flags, tfSendable)
incl(sym.typ, tfSendable)
else:
invalidPragma(c, it)
of wGcSafe:
noVal(c, it)
if sym != nil:
if sym.kind != skType: incl(sym, sfThread)
if sym.typ != nil: incl(sym.typ.flags, tfGcSafe)
if sym.typ != nil: incl(sym.typ, tfGcSafe)
else: invalidPragma(c, it)
else:
discard "no checking if used as a code block"
of wPacked:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfPacked)
else: incl(sym.typ, tfPacked)
of wHint:
let s = expectStrLit(c, it)
recordPragma(c, it, "hint", s)
@@ -1208,7 +1208,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
if sym.typ == nil: invalidPragma(c, it)
else:
sym.typ.callConv = wordToCallConv(k)
sym.typ.flags.incl tfExplicitCallConv
sym.typ.incl tfExplicitCallConv
of wEmit: pragmaEmit(c, it)
of wUnroll: pragmaUnroll(c, it)
of wLinearScanEnd, wComputedGoto: noVal(c, it)
@@ -1218,11 +1218,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
of wIncompleteStruct:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfIncompleteStruct)
else: incl(sym.typ, tfIncompleteStruct)
of wCompleteStruct:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfCompleteStruct)
else: incl(sym.typ, tfCompleteStruct)
of wUnchecked:
noVal(c, it)
if sym.typ == nil or sym.typ.kind notin {tyArray, tyUncheckedArray}:
@@ -1235,13 +1235,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
else:
noVal(c, it)
if sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfUnion)
else: incl(sym.typ, tfUnion)
of wRequiresInit:
noVal(c, it)
if sym.kind == skField:
sym.incl sfRequiresInit
elif sym.typ != nil:
incl(sym.typ.flags, tfNeedsFullInit)
incl(sym.typ, tfNeedsFullInit)
else:
invalidPragma(c, it)
of wByRef:
@@ -1252,18 +1252,18 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
elif sym == nil or sym.typ == nil:
processOption(c, it, c.config.options)
else:
incl(sym.typ.flags, tfByRef)
incl(sym.typ, tfByRef)
of wByCopy:
noVal(c, it)
if sym.kind == skParam:
incl(sym, sfByCopy)
elif sym.kind != skType or sym.typ == nil: invalidPragma(c, it)
else: incl(sym.typ.flags, tfByCopy)
else: incl(sym.typ, tfByCopy)
of wPartial:
noVal(c, it)
if sym.kind != skType or sym.typ == nil: invalidPragma(c, it)
else:
incl(sym.typ.flags, tfPartial)
incl(sym.typ, tfPartial)
of wInject, wGensym:
# We check for errors, but do nothing with these pragmas otherwise
# as they are handled directly in 'evalTemplate'.

View File

@@ -434,7 +434,7 @@ proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
let typedesc = newTypeS(tyTypeDesc, c)
incl typedesc.flags, tfCheckedForDestructor
incl typedesc.flagsImpl, tfCheckedForDestructor
internalAssert(c.config, typ != nil)
typedesc.addSonSkipIntLit(typ, c.idgen)
let sym = newSym(skType, c.cache.idAnon, c.idgen, getCurrOwner(c), info,
@@ -467,8 +467,8 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType =
result.rawAddSon t2
propagateToOwner(result, t1)
propagateToOwner(result, t2)
result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
result.flags.incl tfHasMeta
result.flagsImpl.incl((t1.flags + t2.flags) * {tfHasStatic})
result.flagsImpl.incl tfHasMeta
proc makeOrType*(c: PContext, t1, t2: PType): PType =
if t1.kind != tyOr and t2.kind != tyOr:
@@ -486,14 +486,14 @@ proc makeOrType*(c: PContext, t1, t2: PType): PType =
addOr(t2)
propagateToOwner(result, t1)
propagateToOwner(result, t2)
result.flags.incl((t1.flags + t2.flags) * {tfHasStatic})
result.flags.incl tfHasMeta
result.incl((t1.flags + t2.flags) * {tfHasStatic})
result.incl tfHasMeta
proc makeNotType*(c: PContext, t1: PType): PType =
result = newTypeS(tyNot, c, son = t1)
propagateToOwner(result, t1)
result.flags.incl(t1.flags * {tfHasStatic})
result.flags.incl tfHasMeta
result.flagsImpl.incl(t1.flags * {tfHasStatic})
result.flagsImpl.incl tfHasMeta
proc nMinusOne(c: PContext; n: PNode): PNode =
result = newTreeI(nkCall, n.info, newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n)
@@ -503,7 +503,7 @@ proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
let intType = getSysType(c.graph, n.info, tyInt)
result = newTypeS(tyRange, c, son = intType)
if n.typ != nil and n.typ.n == nil:
result.flags.incl tfUnresolved
result.incl tfUnresolved
result.n = newTreeI(nkRange, n.info, newIntTypeNode(0, intType),
makeStaticExpr(c, nMinusOne(c, n)))
@@ -513,7 +513,7 @@ template rangeHasUnresolvedStatic*(t: PType): bool =
proc errorType*(c: PContext): PType =
## creates a type representing an error state
result = newTypeS(tyError, c)
result.flags.incl tfCheckedForDestructor
result.flagsImpl.incl tfCheckedForDestructor
proc errorNode*(c: PContext, n: PNode): PNode =
result = newNodeI(nkEmpty, n.info)
@@ -563,7 +563,7 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
result = typ
else:
result = newTypeS(tyTypeDesc, c, skipIntLit(typ, c.idgen))
incl result.flags, tfCheckedForDestructor
incl result, tfCheckedForDestructor
proc symFromType*(c: PContext; t: PType, info: TLineInfo): PSym =
if t.sym != nil: return t.sym

View File

@@ -24,7 +24,7 @@ when defined(nimPreviewSlimSystem):
proc errorType*(g: ModuleGraph): PType =
## creates a type representing an error state
result = newType(tyError, g.idgen, g.owners[^1])
result.flags.incl tfCheckedForDestructor
result.flagsImpl.incl tfCheckedForDestructor
proc getIntLitTypeG(g: ModuleGraph; literal: PNode; idgen: IdGenerator): PType =
# we cache some common integer literal types for performance:

View File

@@ -1627,7 +1627,7 @@ proc setEffectsForProcType*(g: ModuleGraph; t: PType, n: PNode; s: PSym = nil) =
effects[pragmasEffects] = n
if s != nil and s.magic != mNone:
if s.magic != mEcho:
t.flags.incl tfNoSideEffect
t.incl tfNoSideEffect
proc rawInitEffects(g: ModuleGraph; effects: PNode) =
newSeq(effects.sons, effectListLen)
@@ -1769,9 +1769,9 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
else:
localError(g.config, s.info, "") # simple error for `system.compiles` context
if not t.gcUnsafe:
s.typ.flags.incl tfGcSafe
s.typ.incl tfGcSafe
if not t.hasSideEffect and sfSideEffect notin s.flags:
s.typ.flags.incl tfNoSideEffect
s.typ.incl tfNoSideEffect
when defined(drnim):
if c.graph.strongSemCheck != nil: c.graph.strongSemCheck(c.graph, s, body)
when defined(useDfa):

View File

@@ -263,7 +263,7 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PT
if n.typ != nil:
if n.typ.kind == tyFromExpr:
# type of node should not be evaluated as a static value
n.typ.flags.incl tfNonConstExpr
n.typ.incl tfNonConstExpr
result.typ() = replaceTypeVarsT(cl, n.typ)
checkMetaInvariants(cl, result.typ)
case n.kind
@@ -396,12 +396,12 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
#cl.typeMap.topLayer.idTablePut(result, t)
if cl.allowMetaTypes: return
result.flags.incl tfFromGeneric
result.incl tfFromGeneric
if not (t.kind in tyMetaTypes or
(t.kind == tyStatic and t.n == nil)):
result.flags.excl tfInstClearedFlags
result.excl tfInstClearedFlags
else:
result.flags.excl tfHasAsgn
result.excl tfHasAsgn
when false:
if newDestructors:
result.assignment = nil
@@ -526,13 +526,13 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
let mm = skipTypes(bbody, abstractPtrs)
if tfFromGeneric notin mm.flags:
# bug #5479, prevent endless recursions here:
incl mm.flags, tfFromGeneric
incl mm.flagsImpl, tfFromGeneric
for col, meth in methodsForGeneric(cl.c.graph, mm):
# we instantiate the known methods belonging to that type, this causes
# them to be registered and that's enough, so we 'discard' the result.
discard cl.c.instTypeBoundOp(cl.c, meth, result, cl.info,
attachedAsgn, col)
excl mm.flags, tfFromGeneric
excl mm.flagsImpl, tfFromGeneric
proc eraseVoidParams*(t: PType) =
# transform '(): void' into '()' because old parts of the compiler really
@@ -756,7 +756,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false):
of tyObject, tyTuple:
propagateFieldFlags(result, result.n)
if result.kind == tyObject and cl.c.computeRequiresInit(cl.c, result):
result.flags.incl tfRequiresInit
result.incl tfRequiresInit
of tyProc:
eraseVoidParams(result)

View File

@@ -897,7 +897,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
param.typ = typ.exactReplica
#copyType(typ, c.idgen, typ.owner)
if typ.n == nil:
param.typ.flags.incl tfInferrableStatic
param.typ.incl tfInferrableStatic
else:
param.ast = typ.n
of tyFromExpr:
@@ -1989,7 +1989,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
var concrete = a
if tfWildcard in a.flags:
a.sym.transitionGenericParamToType()
a.flags.excl tfWildcard
a.excl tfWildcard
elif doBind:
# careful: `trDontDont` (set by `checkGeneric`) is not always respected in this call graph.
# typRel having two different modes (binding and non-binding) can make things harder to
@@ -2339,7 +2339,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
result.add param
if dest.kind in {tyVar, tyLent}:
dest.flags.incl tfVarIsPtr
dest.incl tfVarIsPtr
result = newDeref(result)
inc(m.convMatches)
@@ -2435,7 +2435,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
if m.callee.kind == tyGenericBody:
if f.kind == tyStatic and typeRel(m, f.base, a) != isNone:
result = makeStaticExpr(m.c, arg)
result.typ.flags.incl tfUnresolved
result.typ.incl tfUnresolved
result.typ.n = arg
return
@@ -2995,7 +2995,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
#assert(container == nil)
if container.isNil:
container = newNodeIT(nkBracket, n[a].info, arrayConstr(c, arg))
container.typ.flags.incl tfVarargs
container.typ.incl tfVarargs
else:
incrIndexType(container.typ)
container.add arg

View File

@@ -366,7 +366,7 @@ proc wrapProcForSpawn*(g: ModuleGraph; idgen: IdGenerator; owner: PSym; spawnExp
argsParam.position = 1
var objType = createObj(g, idgen, owner, n.info)
incl(objType.flags, tfFinal)
incl(objType, tfFinal)
let castExpr = createCastExpr(argsParam, objType, idgen)
var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), idgen, owner, n.info, g.config.options)

View File

@@ -853,7 +853,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
of paViaIndirection:
let t = formal.typ
let vt = makeVarType(t.owner, t, c.idgen)
vt.flags.incl tfVarIsPtr
vt.incl tfVarIsPtr
var temp = newTemp(c, vt, formal.info)
addVar(v, temp)
var addrExp = newNodeIT(nkHiddenAddr, formal.info, makeVarType(t.owner, t, c.idgen, tyPtr))

View File

@@ -498,7 +498,7 @@ const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo,
template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) =
tc.add concrete
tc.flags.incl tfResolved
tc.incl tfResolved
# TODO: It would be a good idea to kill the special state of a resolved
# concept by switching to tyAlias within the instantiated procs.