summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-12-15 15:13:25 +0800
committerGitHub <noreply@github.com>2023-12-15 08:13:25 +0100
commitcca5684a17e654a13ddac046f1e76873d8c19f55 (patch)
treeafda8a5c8a114bbb85db9a2e743e6e88b4f899fb
parenta4628532b27857d095e69b7b162b453fc2b8373c (diff)
downloadNim-cca5684a17e654a13ddac046f1e76873d8c19f55.tar.gz
fixes yet another strictdefs bug (#23069)
-rw-r--r--compiler/ccgcalls.nim6
-rw-r--r--compiler/ccgexprs.nim9
-rw-r--r--compiler/ccgtrav.nim13
-rw-r--r--compiler/closureiters.nim7
-rw-r--r--compiler/docgen.nim10
-rw-r--r--compiler/evaltempl.nim16
-rw-r--r--compiler/guards.nim2
-rw-r--r--compiler/ic/ic.nim7
-rw-r--r--compiler/ic/packed_ast.nim2
-rw-r--r--compiler/importer.nim3
-rw-r--r--compiler/int128.nim16
-rw-r--r--compiler/lexer.nim3
-rw-r--r--compiler/modulegraphs.nim28
-rw-r--r--compiler/msgs.nim14
-rw-r--r--compiler/nilcheck.nim18
-rw-r--r--compiler/nimblecmd.nim2
-rw-r--r--compiler/nimconf.nim2
-rw-r--r--compiler/parser.nim2
-rw-r--r--compiler/patterns.nim5
-rw-r--r--compiler/procfind.nim2
-rw-r--r--compiler/semfields.nim25
-rw-r--r--compiler/semgnrc.nim14
-rw-r--r--compiler/semobjconstr.nim2
-rw-r--r--compiler/semparallel.nim8
-rw-r--r--compiler/sempass2.nim3
-rw-r--r--compiler/semtempl.nim26
-rw-r--r--compiler/sigmatch.nim2
-rw-r--r--compiler/sourcemap.nim5
-rw-r--r--lib/pure/collections/tables.nim3
29 files changed, 138 insertions, 117 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index 175100ff4..53c147024 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -237,8 +237,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) =
           optSeqDestructors in p.config.globalOptions:
         linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
       if ntyp.kind in {tyVar} and not compileToCpp(p.module):
-        var t: TLoc
-        t.r = "(*$1)" % [a.rdLoc]
+        var t = TLoc(r: "(*$1)" % [a.rdLoc])
         result.add "($4) ? ((*$1)$3) : NIM_NIL, $2" %
                      [a.rdLoc, lenExpr(p, t), dataField(p),
                       dataFieldAccessor(p, "*" & a.rdLoc)]
@@ -250,8 +249,7 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode; result: var Rope) =
     of tyPtr, tyRef:
       case elementType(a.t).kind
       of tyString, tySequence:
-        var t: TLoc
-        t.r = "(*$1)" % [a.rdLoc]
+        var t = TLoc(r: "(*$1)" % [a.rdLoc])
         result.add "($4) ? ((*$1)$3) : NIM_NIL, $2" %
                      [a.rdLoc, lenExpr(p, t), dataField(p),
                       dataFieldAccessor(p, "*" & a.rdLoc)]
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 7757c9419..28f75f994 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -221,10 +221,11 @@ proc asgnComplexity(n: PNode): int =
 
 proc optAsgnLoc(a: TLoc, t: PType, field: Rope): TLoc =
   assert field != ""
-  result.k = locField
-  result.storage = a.storage
-  result.lode = lodeTyp t
-  result.r = rdLoc(a) & "." & field
+  result = TLoc(k: locField,
+    storage: a.storage,
+    lode: lodeTyp t,
+    r: rdLoc(a) & "." & field
+  )
 
 proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
   let newflags =
diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim
index d4db16018..a7470c44f 100644
--- a/compiler/ccgtrav.nim
+++ b/compiler/ccgtrav.nim
@@ -134,7 +134,6 @@ proc genTraverseProcSeq(c: TTraversalClosure, accessor: Rope, typ: PType) =
     lineF(p, cpsStmts, "}$n", [])
 
 proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
-  var c: TTraversalClosure
   var p = newProc(nil, m)
   result = "Marker_" & getTypeName(m, origTyp, sig)
   let
@@ -147,8 +146,9 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
   lineF(p, cpsLocals, "$1 a;$n", [t])
   lineF(p, cpsInit, "a = ($1)p;$n", [t])
 
-  c.p = p
-  c.visitorFrmt = "op" # "#nimGCvisit((void*)$1, op);$n"
+  var c = TTraversalClosure(p: p,
+    visitorFrmt: "op" # "#nimGCvisit((void*)$1, op);$n"
+    )
 
   assert typ.kind != tyTypeDesc
   if typ.kind == tySequence:
@@ -174,7 +174,6 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
 proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope =
   discard genTypeInfoV1(m, s.loc.t, info)
 
-  var c: TTraversalClosure
   var p = newProc(nil, m)
   var sLoc = rdLoc(s.loc)
   result = getTempName(m)
@@ -183,8 +182,10 @@ proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope =
     accessThreadLocalVar(p, s)
     sLoc = "NimTV_->" & sLoc
 
-  c.visitorFrmt = "0" # "#nimGCvisit((void*)$1, 0);$n"
-  c.p = p
+  var c = TTraversalClosure(p: p,
+    visitorFrmt: "0" # "#nimGCvisit((void*)$1, 0);$n"
+  )
+
   let header = "static N_NIMCALL(void, $1)(void)" % [result]
   genTraverseProc(c, sLoc, s.loc.t)
 
diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim
index 122a69da6..9e97fbf4d 100644
--- a/compiler/closureiters.nim
+++ b/compiler/closureiters.nim
@@ -413,7 +413,7 @@ proc hasYieldsInExpressions(n: PNode): bool =
 
 proc exprToStmtList(n: PNode): tuple[s, res: PNode] =
   assert(n.kind == nkStmtListExpr)
-  result.s = newNodeI(nkStmtList, n.info)
+  result = (newNodeI(nkStmtList, n.info), nil)
   result.s.sons = @[]
 
   var n = n
@@ -1431,10 +1431,7 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode =
       result[i] = preprocess(c, n[i])
 
 proc transformClosureIterator*(g: ModuleGraph; idgen: IdGenerator; fn: PSym, n: PNode): PNode =
-  var ctx: Ctx
-  ctx.g = g
-  ctx.fn = fn
-  ctx.idgen = idgen
+  var ctx = Ctx(g: g, fn: fn, idgen: idgen)
 
   if getEnvParam(fn).isNil:
     # Lambda lifting was not done yet. Use temporary :state sym, which will
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index a8bbe5b64..bf8bdde14 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -289,7 +289,7 @@ template declareClosures(currentFilename: AbsoluteFile, destFile: string) =
     let outDirPath: RelativeFile =
         presentationPath(conf, AbsoluteFile(basedir / targetRelPath))
           # use presentationPath because `..` path can be be mangled to `_._`
-    result.targetPath = string(conf.outDir / outDirPath)
+    result = (string(conf.outDir / outDirPath), "")
     if not fileExists(result.targetPath):
       # this can happen if targetRelPath goes to parent directory `OUTDIR/..`.
       # Trying it, this may cause ambiguities, but allows us to insert
@@ -1000,8 +1000,9 @@ proc getTypeKind(n: PNode): string =
 proc toLangSymbol(k: TSymKind, n: PNode, baseName: string): LangSymbol =
   ## Converts symbol info (names/types/parameters) in `n` into format
   ## `LangSymbol` convenient for ``rst.nim``/``dochelpers.nim``.
-  result.name = baseName.nimIdentNormalize
-  result.symKind = k.toHumanStr
+  result = LangSymbol(name: baseName.nimIdentNormalize,
+      symKind: k.toHumanStr
+  )
   if k in routineKinds:
     var
       paramTypes: seq[string] = @[]
@@ -1166,8 +1167,9 @@ proc genJsonItem(d: PDoc, n, nameNode: PNode, k: TSymKind, nonExports = false):
   if nonExports:
     renderFlags.incl renderNonExportedFields
   r = initTokRender(n, renderFlags)
-  result.json = %{ "name": %name, "type": %($k), "line": %n.info.line.int,
+  result = JsonItem(json: %{ "name": %name, "type": %($k), "line": %n.info.line.int,
                    "col": %n.info.col}
+  )
   if comm != nil:
     result.rst = comm
     result.rstField = "description"
diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim
index 5ebb4fa55..d87505102 100644
--- a/compiler/evaltempl.nim
+++ b/compiler/evaltempl.nim
@@ -182,14 +182,14 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
 
   # replace each param by the corresponding node:
   var args = evalTemplateArgs(n, tmpl, conf, fromHlo)
-  var ctx: TemplCtx
-  ctx.owner = tmpl
-  ctx.genSymOwner = genSymOwner
-  ctx.config = conf
-  ctx.ic = ic
-  ctx.mapping = initIdTable()
-  ctx.instID = instID[]
-  ctx.idgen = idgen
+  var ctx = TemplCtx(owner: tmpl,
+    genSymOwner: genSymOwner,
+    config: conf,
+    ic: ic,
+    mapping: initIdTable(),
+    instID: instID[],
+    idgen: idgen
+  )
 
   let body = tmpl.ast[bodyPos]
   #echo "instantion of ", renderTree(body, {renderIds})
diff --git a/compiler/guards.nim b/compiler/guards.nim
index 87dbfdf6f..bbb239867 100644
--- a/compiler/guards.nim
+++ b/compiler/guards.nim
@@ -1063,7 +1063,7 @@ proc pleViaModel(model: TModel; aa, bb: PNode): TImplication =
       let b = fact[2]
       if a.kind == nkSym: replacements.add((a,b))
       else: replacements.add((b,a))
-  var m: TModel
+  var m = TModel()
   var a = aa
   var b = bb
   if replacements.len > 0:
diff --git a/compiler/ic/ic.nim b/compiler/ic/ic.nim
index a7d3ed81c..e85621910 100644
--- a/compiler/ic/ic.nim
+++ b/compiler/ic/ic.nim
@@ -383,10 +383,9 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI
 proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib =
   ## the plib hangs off the psym via the .annex field
   if l.isNil: return
-  result.kind = l.kind
-  result.generated = l.generated
-  result.isOverridden = l.isOverridden
-  result.name = toLitId($l.name, m)
+  result = PackedLib(kind: l.kind, generated: l.generated,
+    isOverridden: l.isOverridden, name: toLitId($l.name, m)
+  )
   storeNode(result, l, path)
 
 proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId =
diff --git a/compiler/ic/packed_ast.nim b/compiler/ic/packed_ast.nim
index 8971d72be..2599e07d1 100644
--- a/compiler/ic/packed_ast.nim
+++ b/compiler/ic/packed_ast.nim
@@ -124,7 +124,7 @@ proc `==`*(a, b: NodePos): bool {.borrow.}
 proc `==`*(a, b: NodeId): bool {.borrow.}
 
 proc newTreeFrom*(old: PackedTree): PackedTree =
-  result.nodes = @[]
+  result = PackedTree(nodes: @[])
   when false: result.sh = old.sh
 
 proc addIdent*(tree: var PackedTree; s: LitId; info: PackedLineInfo) =
diff --git a/compiler/importer.nim b/compiler/importer.nim
index a8de1e8bc..57cbbb847 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -251,7 +251,8 @@ proc importModuleAs(c: PContext; n: PNode, realModule: PSym, importHidden: bool)
   c.importModuleLookup.mgetOrPut(result.name.id, @[]).addUnique realModule.id
 
 proc transformImportAs(c: PContext; n: PNode): tuple[node: PNode, importHidden: bool] =
-  var ret: typeof(result)
+  result = (nil, false)
+  var ret = default(typeof(result))
   proc processPragma(n2: PNode): PNode =
     let (result2, kws) = splitPragmas(c, n2)
     result = result2
diff --git a/compiler/int128.nim b/compiler/int128.nim
index ca06a3a97..74e581cd5 100644
--- a/compiler/int128.nim
+++ b/compiler/int128.nim
@@ -34,6 +34,7 @@ proc `$`*(a: Int128): string
 
 proc toInt128*[T: SomeInteger | bool](arg: T): Int128 =
   {.noSideEffect.}:
+    result = Zero
     when T is bool: result.sdata(0) = int32(arg)
     elif T is SomeUnsignedInt:
       when sizeof(arg) <= 4:
@@ -208,30 +209,35 @@ proc `==`*(a, b: Int128): bool =
   return true
 
 proc bitnot*(a: Int128): Int128 =
+  result = Zero
   result.udata[0] = not a.udata[0]
   result.udata[1] = not a.udata[1]
   result.udata[2] = not a.udata[2]
   result.udata[3] = not a.udata[3]
 
 proc bitand*(a, b: Int128): Int128 =
+  result = Zero
   result.udata[0] = a.udata[0] and b.udata[0]
   result.udata[1] = a.udata[1] and b.udata[1]
   result.udata[2] = a.udata[2] and b.udata[2]
   result.udata[3] = a.udata[3] and b.udata[3]
 
 proc bitor*(a, b: Int128): Int128 =
+  result = Zero
   result.udata[0] = a.udata[0] or b.udata[0]
   result.udata[1] = a.udata[1] or b.udata[1]
   result.udata[2] = a.udata[2] or b.udata[2]
   result.udata[3] = a.udata[3] or b.udata[3]
 
 proc bitxor*(a, b: Int128): Int128 =
+  result = Zero
   result.udata[0] = a.udata[0] xor b.udata[0]
   result.udata[1] = a.udata[1] xor b.udata[1]
   result.udata[2] = a.udata[2] xor b.udata[2]
   result.udata[3] = a.udata[3] xor b.udata[3]
 
 proc `shr`*(a: Int128, b: int): Int128 =
+  result = Zero
   let b = b and 127
   if b < 32:
     result.sdata(3) = a.sdata(3) shr b
@@ -258,6 +264,7 @@ proc `shr`*(a: Int128, b: int): Int128 =
     result.sdata(0) = a.sdata(3) shr (b and 31)
 
 proc `shl`*(a: Int128, b: int): Int128 =
+  result = Zero
   let b = b and 127
   if b < 32:
     result.udata[0] = a.udata[0] shl b
@@ -281,6 +288,7 @@ proc `shl`*(a: Int128, b: int): Int128 =
     result.udata[3] = a.udata[0] shl (b and 31)
 
 proc `+`*(a, b: Int128): Int128 =
+  result = Zero
   let tmp0 = uint64(a.udata[0]) + uint64(b.udata[0])
   result.udata[0] = cast[uint32](tmp0)
   let tmp1 = uint64(a.udata[1]) + uint64(b.udata[1]) + (tmp0 shr 32)
@@ -313,6 +321,7 @@ proc abs(a: int32): int =
   if a < 0: -a else: a
 
 proc `*`(a: Int128, b: uint32): Int128 =
+  result = Zero
   let tmp0 = uint64(a.udata[0]) * uint64(b)
   let tmp1 = uint64(a.udata[1]) * uint64(b)
   let tmp2 = uint64(a.udata[2]) * uint64(b)
@@ -335,6 +344,7 @@ proc `*=`(a: var Int128, b: int32) =
   a = a * b
 
 proc makeInt128(high, low: uint64): Int128 =
+  result = Zero
   result.udata[0] = cast[uint32](low)
   result.udata[1] = cast[uint32](low shr 32)
   result.udata[2] = cast[uint32](high)
@@ -373,6 +383,8 @@ proc fastLog2*(a: Int128): int =
 
 proc divMod*(dividend, divisor: Int128): tuple[quotient, remainder: Int128] =
   assert(divisor != Zero)
+  result = (Zero, Zero)
+
   let isNegativeA = isNegative(dividend)
   let isNegativeB = isNegative(divisor)
 
@@ -539,24 +551,28 @@ proc toInt128*(arg: float64): Int128 =
     return res
 
 proc maskUInt64*(arg: Int128): Int128 {.noinit, inline.} =
+  result = Zero
   result.udata[0] = arg.udata[0]
   result.udata[1] = arg.udata[1]
   result.udata[2] = 0
   result.udata[3] = 0
 
 proc maskUInt32*(arg: Int128): Int128 {.noinit, inline.} =
+  result = Zero
   result.udata[0] = arg.udata[0]
   result.udata[1] = 0
   result.udata[2] = 0
   result.udata[3] = 0
 
 proc maskUInt16*(arg: Int128): Int128 {.noinit, inline.} =
+  result = Zero
   result.udata[0] = arg.udata[0] and 0xffff
   result.udata[1] = 0
   result.udata[2] = 0
   result.udata[3] = 0
 
 proc maskUInt8*(arg: Int128): Int128 {.noinit, inline.} =
+  result = Zero
   result.udata[0] = arg.udata[0] and 0xff
   result.udata[1] = 0
   result.udata[2] = 0
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 1ef0ce879..ad5dd560c 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -300,8 +300,7 @@ proc getNumber(L: var Lexer, result: var Token) =
     # Used to get slightly human friendlier err messages.
     const literalishChars = {'A'..'Z', 'a'..'z', '0'..'9', '_', '.', '\''}
     var msgPos = L.bufpos
-    var t: Token
-    t.literal = ""
+    var t = Token(literal: "")
     L.bufpos = startpos # Use L.bufpos as pos because of matchChars
     matchChars(L, t, literalishChars)
     # We must verify +/- specifically so that we're not past the literal
diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim
index 95fa193dc..89ed4967f 100644
--- a/compiler/modulegraphs.nim
+++ b/compiler/modulegraphs.nim
@@ -477,19 +477,21 @@ proc registerModuleById*(g: ModuleGraph; m: FileIndex) =
 proc initOperators*(g: ModuleGraph): Operators =
   # These are safe for IC.
   # Public because it's used by DrNim.
-  result.opLe = createMagic(g, "<=", mLeI)
-  result.opLt = createMagic(g, "<", mLtI)
-  result.opAnd = createMagic(g, "and", mAnd)
-  result.opOr = createMagic(g, "or", mOr)
-  result.opIsNil = createMagic(g, "isnil", mIsNil)
-  result.opEq = createMagic(g, "==", mEqI)
-  result.opAdd = createMagic(g, "+", mAddI)
-  result.opSub = createMagic(g, "-", mSubI)
-  result.opMul = createMagic(g, "*", mMulI)
-  result.opDiv = createMagic(g, "div", mDivI)
-  result.opLen = createMagic(g, "len", mLengthSeq)
-  result.opNot = createMagic(g, "not", mNot)
-  result.opContains = createMagic(g, "contains", mInSet)
+  result = Operators(
+    opLe: createMagic(g, "<=", mLeI),
+    opLt: createMagic(g, "<", mLtI),
+    opAnd: createMagic(g, "and", mAnd),
+    opOr: createMagic(g, "or", mOr),
+    opIsNil: createMagic(g, "isnil", mIsNil),
+    opEq: createMagic(g, "==", mEqI),
+    opAdd: createMagic(g, "+", mAddI),
+    opSub: createMagic(g, "-", mSubI),
+    opMul: createMagic(g, "*", mMulI),
+    opDiv: createMagic(g, "div", mDivI),
+    opLen: createMagic(g, "len", mLengthSeq),
+    opNot: createMagic(g, "not", mNot),
+    opContains: createMagic(g, "contains", mInSet)
+  )
 
 proc initModuleGraphFields(result: ModuleGraph) =
   # A module ID of -1 means that the symbol is not attached to a module at all,
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 5c30acff3..1d6781182 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -61,14 +61,12 @@ proc makeCString*(s: string): Rope =
   result.add('\"')
 
 proc newFileInfo(fullPath: AbsoluteFile, projPath: RelativeFile): TFileInfo =
-  result.fullPath = fullPath
-  #shallow(result.fullPath)
-  result.projPath = projPath
-  #shallow(result.projPath)
-  result.shortName = fullPath.extractFilename
+  result = TFileInfo(fullPath: fullPath, projPath: projPath,
+                    shortName: fullPath.extractFilename,
+                    quotedFullName: fullPath.string.makeCString,
+                    lines: @[]
+  )
   result.quotedName = result.shortName.makeCString
-  result.quotedFullName = fullPath.string.makeCString
-  result.lines = @[]
   when defined(nimpretty):
     if not result.fullPath.isEmpty:
       try:
@@ -136,7 +134,7 @@ proc fileInfoIdx*(conf: ConfigRef; filename: RelativeFile): FileIndex =
   fileInfoIdx(conf, AbsoluteFile expandFilename(filename.string), dummy)
 
 proc newLineInfo*(fileInfoIdx: FileIndex, line, col: int): TLineInfo =
-  result.fileIndex = fileInfoIdx
+  result = TLineInfo(fileIndex: fileInfoIdx)
   if line < int high(uint16):
     result.line = uint16(line)
   else:
diff --git a/compiler/nilcheck.nim b/compiler/nilcheck.nim
index 6261c8fda..932cffba8 100644
--- a/compiler/nilcheck.nim
+++ b/compiler/nilcheck.nim
@@ -498,7 +498,7 @@ proc checkCall(n, ctx, map): Check =
   # check args and handle possible mutations
 
   var isNew = false
-  result.map = map
+  result = Check(map: map)
   for i, child in n:
     discard check(child, ctx, map)
 
@@ -753,6 +753,7 @@ proc checkReturn(n, ctx, map): Check =
 
 proc checkIf(n, ctx, map): Check =
   ## check branches based on condition
+  result = default(Check)
   var mapIf: NilMap = map
 
   # first visit the condition
@@ -825,7 +826,7 @@ proc checkFor(n, ctx, map): Check =
   var check2 = check(n.sons[2], ctx, m)
   var map2 = check2.map
 
-  result.map = ctx.union(map0, m)
+  result = Check(map: ctx.union(map0, m))
   result.map = ctx.union(result.map, map2)
   result.nilability = Safe
 
@@ -853,7 +854,7 @@ proc checkWhile(n, ctx, map): Check =
   var check2 = check(n.sons[1], ctx, m)
   var map2 = check2.map
 
-  result.map = ctx.union(map0, map1)
+  result = Check(map: ctx.union(map0, map1))
   result.map = ctx.union(result.map, map2)
   result.nilability = Safe
 
@@ -899,7 +900,7 @@ proc checkInfix(n, ctx, map): Check =
 proc checkIsNil(n, ctx, map; isElse: bool = false): Check =
   ## check isNil calls
   ## update the map depending on if it is not isNil or isNil
-  result.map = newNilMap(map)
+  result = Check(map: newNilMap(map))
   let value = n[1]
   result.map.store(ctx, ctx.index(n[1]), if not isElse: Nil else: Safe, TArg, n.info, n)
 
@@ -947,7 +948,7 @@ proc checkCase(n, ctx, map): Check =
   #   c2
   # also a == true is a , a == false is not a
   let base = n[0]
-  result.map = map.copyMap()
+  result = Check(map: map.copyMap())
   result.nilability = Safe
   var a: PNode = nil
   for child in n:
@@ -1219,7 +1220,7 @@ proc check(n: PNode, ctx: NilCheckerContext, map: NilMap): Check =
     result = check(n.sons[1], ctx, map)
   of nkStmtList, nkStmtListExpr, nkChckRangeF, nkChckRange64, nkChckRange,
      nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr, nkElse:
-    result.map = map
+    result = Check(map: map)
     if n.kind in {nkObjConstr, nkTupleConstr}:
       # TODO deeper nested elements?
       # A(field: B()) #
@@ -1247,7 +1248,7 @@ proc check(n: PNode, ctx: NilCheckerContext, map: NilMap): Check =
   of nkAsgn, nkFastAsgn, nkSinkAsgn:
     result = checkAsgn(n[0], n[1], ctx, map)
   of nkVarSection:
-    result.map = map
+    result = Check(map: map)
     for child in n:
       result = checkAsgn(child[0], child[2], ctx, result.map)
   of nkForStmt:
@@ -1273,8 +1274,7 @@ proc check(n: PNode, ctx: NilCheckerContext, map: NilMap): Check =
   else:
 
     var elementMap = map.copyMap()
-    var elementCheck: Check
-    elementCheck.map = elementMap
+    var elementCheck = Check(map: elementMap)
     for element in n:
       elementCheck = check(element, ctx, elementCheck.map)
 
diff --git a/compiler/nimblecmd.nim b/compiler/nimblecmd.nim
index 4b6e22bc9..a5324ea76 100644
--- a/compiler/nimblecmd.nim
+++ b/compiler/nimblecmd.nim
@@ -79,6 +79,8 @@ proc getPathVersionChecksum*(p: string): tuple[name, version, checksum: string]
   ## ``/home/user/.nimble/pkgs/package-0.1-febadeaea2345e777f0f6f8433f7f0a52edd5d1b`` into
   ## ``("/home/user/.nimble/pkgs/package", "0.1", "febadeaea2345e777f0f6f8433f7f0a52edd5d1b")``
 
+  result = ("", "", "")
+
   const checksumSeparator = '-'
   const versionSeparator = '-'
   const specialVersionSepartator = "-#"
diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim
index 1e7d62b4d..5417cd1e9 100644
--- a/compiler/nimconf.nim
+++ b/compiler/nimconf.nim
@@ -223,7 +223,7 @@ proc readConfigFile*(filename: AbsoluteFile; cache: IdentCache;
   stream = llStreamOpen(filename, fmRead)
   if stream != nil:
     openLexer(L, filename, stream, cache, config)
-    tok.tokType = tkEof       # to avoid a pointless warning
+    tok = Token(tokType: tkEof)       # to avoid a pointless warning
     var condStack: seq[bool] = @[]
     confTok(L, tok, config, condStack)           # read in the first token
     while tok.tokType != tkEof: parseAssignment(L, tok, config, filename, condStack)
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 4ed38f739..1017759a9 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -2574,7 +2574,7 @@ proc parseString*(s: string; cache: IdentCache; config: ConfigRef;
   var stream = llStreamOpen(s)
   stream.lineOffset = line
 
-  var p: Parser
+  var p = Parser()
   p.lex.errorHandler = errorHandler
   openParser(p, AbsoluteFile filename, stream, cache, config)
 
diff --git a/compiler/patterns.nim b/compiler/patterns.nim
index 7b0d7e4fb..04d8593cc 100644
--- a/compiler/patterns.nim
+++ b/compiler/patterns.nim
@@ -276,10 +276,7 @@ proc addToArgList(result, n: PNode) =
 
 proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
   ## returns a tree to semcheck if the rule triggered; nil otherwise
-  var ctx: TPatternContext
-  ctx.owner = s
-  ctx.c = c
-  ctx.formals = s.typ.len-1
+  var ctx = TPatternContext(owner: s, c: c, formals: s.typ.len-1)
   var m = matchStmtList(ctx, s.ast[patternPos], n)
   if isNil(m): return nil
   # each parameter should have been bound; we simply setup a call and
diff --git a/compiler/procfind.nim b/compiler/procfind.nim
index 468879ba2..65266201a 100644
--- a/compiler/procfind.nim
+++ b/compiler/procfind.nim
@@ -54,7 +54,7 @@ proc searchForProcAux(c: PContext, scope: PScope, fn: PSym): PSym =
 
 proc searchForProc*(c: PContext, scope: PScope, fn: PSym): tuple[proto: PSym, comesFromShadowScope: bool] =
   var scope = scope
-  result.proto = searchForProcAux(c, scope, fn)
+  result = (searchForProcAux(c, scope, fn), false)
   while result.proto == nil and scope.isShadowScope:
     scope = scope.parent
     result.proto = searchForProcAux(c, scope, fn)
diff --git a/compiler/semfields.nim b/compiler/semfields.nim
index d1637e1f2..874055cdc 100644
--- a/compiler/semfields.nim
+++ b/compiler/semfields.nim
@@ -64,10 +64,12 @@ type
 proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
   case typ.kind
   of nkSym:
-    var fc: TFieldInstCtx  # either 'tup[i]' or 'field' is valid
-    fc.c = c.c
-    fc.field = typ.sym
-    fc.replaceByFieldName = c.m == mFieldPairs
+    # either 'tup[i]' or 'field' is valid
+    var fc = TFieldInstCtx(
+      c: c.c,
+      field: typ.sym,
+      replaceByFieldName: c.m == mFieldPairs
+    )
     openScope(c.c)
     inc c.c.inUnrolledContext
     let body = instFieldLoopBody(fc, lastSon(forLoop), forLoop)
@@ -139,20 +141,19 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
     var loopBody = n[^1]
     for i in 0..<tupleTypeA.len:
       openScope(c)
-      var fc: TFieldInstCtx
-      fc.tupleType = tupleTypeA
-      fc.tupleIndex = i
-      fc.c = c
-      fc.replaceByFieldName = m == mFieldPairs
+      var fc = TFieldInstCtx(
+          tupleType: tupleTypeA,
+          tupleIndex: i,
+          c: c,
+          replaceByFieldName: m == mFieldPairs
+      )
       var body = instFieldLoopBody(fc, loopBody, n)
       inc c.inUnrolledContext
       stmts.add(semStmt(c, body, {}))
       dec c.inUnrolledContext
       closeScope(c)
   else:
-    var fc: TFieldsCtx
-    fc.m = m
-    fc.c = c
+    var fc = TFieldsCtx(m: m, c: c)
     var t = tupleTypeA
     while t.kind == tyObject:
       semForObjectFields(fc, t.n, n, stmts)
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index eebf11c0a..cae823a8f 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -575,16 +575,18 @@ proc semGenericStmt(c: PContext, n: PNode,
     if withinTypeDesc in flags: dec c.inTypeContext
 
 proc semGenericStmt(c: PContext, n: PNode): PNode =
-  var ctx: GenericCtx
-  ctx.toMixin = initIntSet()
-  ctx.toBind = initIntSet()
+  var ctx = GenericCtx(
+    toMixin: initIntSet(),
+    toBind: initIntSet()
+  )
   result = semGenericStmt(c, n, {}, ctx)
   semIdeForTemplateOrGeneric(c, result, ctx.cursorInBody)
 
 proc semConceptBody(c: PContext, n: PNode): PNode =
-  var ctx: GenericCtx
-  ctx.toMixin = initIntSet()
-  ctx.toBind = initIntSet()
+  var ctx = GenericCtx(
+    toMixin: initIntSet(),
+    toBind: initIntSet()
+  )
   result = semGenericStmt(c, n, {withinConcept}, ctx)
   semIdeForTemplateOrGeneric(c, result, ctx.cursorInBody)
 
diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim
index 96f7658df..e29d723d7 100644
--- a/compiler/semobjconstr.nim
+++ b/compiler/semobjconstr.nim
@@ -405,7 +405,7 @@ proc semConstructFields(c: PContext, n: PNode, constrCtx: var ObjConstrContext,
 proc semConstructTypeAux(c: PContext,
                          constrCtx: var ObjConstrContext,
                          flags: TExprFlags): tuple[status: InitStatus, defaults: seq[PNode]] =
-  result.status = initUnknown
+  result = (initUnknown, @[])
   var t = constrCtx.typ
   while true:
     let (status, defaults) = semConstructFields(c, t.n, constrCtx, flags)
diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim
index e9ba04e8b..23a8e6362 100644
--- a/compiler/semparallel.nim
+++ b/compiler/semparallel.nim
@@ -77,12 +77,12 @@ type
     graph: ModuleGraph
 
 proc initAnalysisCtx(g: ModuleGraph): AnalysisCtx =
-  result.locals = @[]
-  result.slices = @[]
-  result.args = @[]
+  result = AnalysisCtx(locals: @[],
+    slices: @[],
+    args: @[],
+    graph: g)
   result.guards.s = @[]
   result.guards.g = g
-  result.graph = g
 
 proc lookupSlot(c: AnalysisCtx; s: PSym): int =
   for i in 0..<c.locals.len:
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 36611fd27..9b386cf5c 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -1168,7 +1168,10 @@ proc track(tracked: PEffects, n: PNode) =
     trackCall(tracked, n)
   of nkDotExpr:
     guardDotAccess(tracked, n)
+    let oldLeftPartOfAsgn = tracked.leftPartOfAsgn
+    tracked.leftPartOfAsgn = 0
     for i in 0..<n.len: track(tracked, n[i])
+    tracked.leftPartOfAsgn = oldLeftPartOfAsgn
   of nkCheckedFieldExpr:
     track(tracked, n[0])
     if tracked.config.hasWarn(warnProveField) or strictCaseObjects in tracked.c.features:
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 20c8f57bd..e572efdc0 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -688,12 +688,13 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
   if n[patternPos].kind != nkEmpty:
     n[patternPos] = semPattern(c, n[patternPos], s)
 
-  var ctx: TemplCtx
-  ctx.toBind = initIntSet()
-  ctx.toMixin = initIntSet()
-  ctx.toInject = initIntSet()
-  ctx.c = c
-  ctx.owner = s
+  var ctx = TemplCtx(
+    toBind: initIntSet(),
+    toMixin: initIntSet(),
+    toInject: initIntSet(),
+    c: c,
+    owner: s
+  )
   if sfDirty in s.flags:
     n[bodyPos] = semTemplBodyDirty(ctx, n[bodyPos])
   else:
@@ -844,12 +845,13 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
 
 proc semPattern(c: PContext, n: PNode; s: PSym): PNode =
   openScope(c)
-  var ctx: TemplCtx
-  ctx.toBind = initIntSet()
-  ctx.toMixin = initIntSet()
-  ctx.toInject = initIntSet()
-  ctx.c = c
-  ctx.owner = getCurrOwner(c)
+  var ctx = TemplCtx(
+    toBind: initIntSet(),
+    toMixin: initIntSet(),
+    toInject: initIntSet(),
+    c: c,
+    owner: getCurrOwner(c)
+  )
   result = flattenStmts(semPatternBody(ctx, n))
   if result.kind in {nkStmtList, nkStmtListExpr}:
     if result.len == 1:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index ceb3f5a51..94d775e9a 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -727,7 +727,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
     c = m.c
     typeClass = ff.skipTypes({tyUserTypeClassInst})
     body = typeClass.n[3]
-    matchedConceptContext: TMatchedConcept
+    matchedConceptContext = TMatchedConcept()
     prevMatchedConcept = c.matchedConcept
     prevCandidateType = typeClass[0][0]
 
diff --git a/compiler/sourcemap.nim b/compiler/sourcemap.nim
index b0b6fea2e..0810b7f7e 100644
--- a/compiler/sourcemap.nim
+++ b/compiler/sourcemap.nim
@@ -160,10 +160,7 @@ func parse*(source: string): SourceInfo =
 func toSourceMap*(info: SourceInfo, file: string): SourceMap {.raises: [].} =
   ## Convert from high level SourceInfo into the required SourceMap object
   # Add basic info
-  result.version = 3
-  result.file = file
-  result.sources = info.files
-  result.names = info.names
+  result = SourceMap(version: 3, file: file, sources: info.files, names: info.names)
   # Convert nodes into mappings.
   # Mappings are split into blocks where each block referes to a line in the outputted JS.
   # Blocks can be separated into statements which refere to tokens on the line.
diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim
index 8e4a3c35f..4c3b72797 100644
--- a/lib/pure/collections/tables.nim
+++ b/lib/pure/collections/tables.nim
@@ -278,6 +278,7 @@ proc initTable*[A, B](initialSize = defaultInitialSize): Table[A, B] =
     let
       a = initTable[int, string]()
       b = initTable[char, seq[int]]()
+  result = default(Table[A, B])
   initImpl(result, initialSize)
 
 proc `[]=`*[A, B](t: var Table[A, B], key: A, val: sink B) =
@@ -1346,6 +1347,7 @@ proc initOrderedTable*[A, B](initialSize = defaultInitialSize): OrderedTable[A,
     let
       a = initOrderedTable[int, string]()
       b = initOrderedTable[char, seq[int]]()
+  result = default(OrderedTable[A, B])
   initImpl(result, initialSize)
 
 proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: sink B) =
@@ -2336,6 +2338,7 @@ proc initCountTable*[A](initialSize = defaultInitialSize): CountTable[A] =
   ## * `toCountTable proc<#toCountTable,openArray[A]>`_
   ## * `newCountTable proc<#newCountTable>`_ for creating a
   ##   `CountTableRef`
+  result = default(CountTable[A])
   initImpl(result, initialSize)
 
 proc toCountTable*[A](keys: openArray[A]): CountTable[A] =