diff --git a/compiler/ast.nim b/compiler/ast.nim index fcd248b203..c2673549c3 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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 diff --git a/compiler/concepts.nim b/compiler/concepts.nim index a16b2fbfa2..b808c6608b 100644 --- a/compiler/concepts.nim +++ b/compiler/concepts.nim @@ -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) diff --git a/compiler/ic/ic.nim b/compiler/ic/ic.nim index 340193641c..7ab159bb87 100644 --- a/compiler/ic/ic.nim +++ b/compiler/ic/ic.nim @@ -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) = diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 0fca8b980f..47783667e6 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -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 diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index b4b2fd28da..ef8ccfc49a 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -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! diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 95359c6a66..831ffcef34 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -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) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index afddf24299..a6e33d18e4 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -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'. diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 7e0bdf448b..5f26d2d6e7 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -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 diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 451d675188..f5acbe66ca 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -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: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 1b4b15ac3e..b0463e76c3 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -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): diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 5e62242342..598e677730 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 28ebcda23a..79fd0f5d34 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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 diff --git a/compiler/spawn.nim b/compiler/spawn.nim index 7702e26221..c769d17dad 100644 --- a/compiler/spawn.nim +++ b/compiler/spawn.nim @@ -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) diff --git a/compiler/transf.nim b/compiler/transf.nim index 43605f505b..cc97d6839e 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -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)) diff --git a/compiler/types.nim b/compiler/types.nim index bd65c3f331..6fcf2e14e2 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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.