Cosmetic compiler cleanup (#12718)

* Cleanup compiler code base

* Unify add calls

* Unify len invocations

* Unify range operators

* Fix oversight

* Remove {.procvar.} pragma

* initCandidate -> newCandidate where reasonable

* Unify safeLen calls
This commit is contained in:
Clyybber 2019-11-28 17:13:04 +01:00 • committed by Andreas Rumpf
commit 7e747d11c6
109 changed files with 6115 additions and 6254 deletions

View file

@ -91,7 +91,7 @@ proc isLocalVar(a: PEffects, s: PSym): bool =
proc getLockLevel(t: PType): TLockLevel =
var t = t
# tyGenericInst(TLock {tyGenericBody}, tyStatic, tyObject):
if t.kind == tyGenericInst and t.len == 3: t = t.sons[1]
if t.kind == tyGenericInst and t.len == 3: t = t[1]
if t.kind == tyStatic and t.n != nil and t.n.kind in {nkCharLit..nkInt64Lit}:
result = t.n.intVal.TLockLevel
@ -131,21 +131,21 @@ proc guardGlobal(a: PEffects; n: PNode; guard: PSym) =
# 'guard*' are checks which are concerned with 'guard' annotations
# (var x{.guard: y.}: int)
proc guardDotAccess(a: PEffects; n: PNode) =
let ri = n.sons[1]
let ri = n[1]
if ri.kind != nkSym or ri.sym.kind != skField: return
var g = ri.sym.guard
if g.isNil or a.isTopLevel: return
# fixup guard:
if g.kind == skUnknown:
var field: PSym = nil
var ty = n.sons[0].typ.skipTypes(abstractPtrs)
var ty = n[0].typ.skipTypes(abstractPtrs)
if ty.kind == tyTuple and not ty.n.isNil:
field = lookupInRecord(ty.n, g.name)
else:
while ty != nil and ty.kind == tyObject:
field = lookupInRecord(ty.n, g.name)
if field != nil: break
ty = ty.sons[0]
ty = ty[0]
if ty == nil: break
ty = ty.skipTypes(skipPtrs)
if field == nil:
@ -156,8 +156,8 @@ proc guardDotAccess(a: PEffects; n: PNode) =
# XXX unfortunately this is not correct for generic instantiations!
if g.kind == skField:
let dot = newNodeI(nkDotExpr, n.info, 2)
dot.sons[0] = n.sons[0]
dot.sons[1] = newSymNode(g)
dot[0] = n[0]
dot[1] = newSymNode(g)
dot.typ = g.typ
for L in a.locked:
#if a.guards.sameSubexprs(dot, L): return
@ -305,7 +305,7 @@ proc createTag(g: ModuleGraph; n: PNode): PNode =
proc addEffect(a: PEffects, e: PNode, useLineInfo=true) =
assert e.kind != nkRaiseStmt
var aa = a.exc
for i in a.bottom ..< aa.len:
for i in a.bottom..<aa.len:
if sameType(a.graph.excType(aa[i]), a.graph.excType(e)):
if not useLineInfo or a.config.cmd == cmdDoc: return
elif aa[i].info == e.info: return
@ -313,7 +313,7 @@ proc addEffect(a: PEffects, e: PNode, useLineInfo=true) =
proc addTag(a: PEffects, e: PNode, useLineInfo=true) =
var aa = a.tags
for i in 0 ..< aa.len:
for i in 0..<aa.len:
if sameType(aa[i].typ.skipTypes(skipPtrs), e.typ.skipTypes(skipPtrs)):
if not useLineInfo or a.config.cmd == cmdDoc: return
elif aa[i].info == e.info: return
@ -344,7 +344,7 @@ proc catches(tracked: PEffects, e: PType) =
while i < L:
# r supertype of e?
if safeInheritanceDiff(tracked.graph.excType(tracked.exc[i]), e) <= 0:
tracked.exc.sons[i] = tracked.exc.sons[L-1]
tracked.exc[i] = tracked.exc[L-1]
dec L
else:
inc i
@ -366,7 +366,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
var inter: TIntersection = @[]
inc tracked.inTryStmt
track(tracked, n.sons[0])
track(tracked, n[0])
dec tracked.inTryStmt
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@ -375,35 +375,33 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
var hasFinally = false
# Collect the exceptions caught by the except branches
for i in 1 ..< n.len:
let b = n.sons[i]
let blen = len(b)
for i in 1..<n.len:
let b = n[i]
if b.kind == nkExceptBranch:
inc branches
if blen == 1:
if b.len == 1:
catchesAll(tracked)
else:
for j in 0 .. blen - 2:
if b.sons[j].isInfixAs():
assert(b.sons[j][1].kind == nkType)
catches(tracked, b.sons[j][1].typ)
for j in 0..<b.len - 1:
if b[j].isInfixAs():
assert(b[j][1].kind == nkType)
catches(tracked, b[j][1].typ)
else:
assert(b.sons[j].kind == nkType)
catches(tracked, b.sons[j].typ)
assert(b[j].kind == nkType)
catches(tracked, b[j].typ)
else:
assert b.kind == nkFinally
# Add any other exception raised in the except bodies
for i in 1 ..< n.len:
let b = n.sons[i]
let blen = len(b)
for i in 1..<n.len:
let b = n[i]
if b.kind == nkExceptBranch:
setLen(tracked.init, oldState)
track(tracked, b.sons[blen-1])
track(tracked, b[^1])
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
else:
setLen(tracked.init, oldState)
track(tracked, b.sons[blen-1])
track(tracked, b[^1])
hasFinally = true
tracked.bottom = oldBottom
@ -427,8 +425,8 @@ proc isForwardedProc(n: PNode): bool =
result = n.kind == nkSym and sfForward in n.sym.flags
proc trackPragmaStmt(tracked: PEffects, n: PNode) =
for i in 0 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if whichPragma(it) == wEffects:
# list the computed effects up to here:
listEffects(tracked)
@ -459,7 +457,7 @@ proc mergeLockLevels(tracked: PEffects, n: PNode, lockLevel: TLockLevel) =
tracked.maxLockLevel = max(tracked.maxLockLevel, lockLevel)
proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
let pragma = s.ast.sons[pragmasPos]
let pragma = s.ast[pragmasPos]
let spec = effectSpec(pragma, wRaises)
mergeEffects(tracked, spec, n)
@ -531,8 +529,8 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType; caller: PNode)
let op = a.typ
# assume indirect calls are taken here:
if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit and not isTrival(caller):
internalAssert tracked.config, op.n.sons[0].kind == nkEffectList
var effectList = op.n.sons[0]
internalAssert tracked.config, op.n[0].kind == nkEffectList
var effectList = op.n[0]
var s = n.skipConv
if s.kind == nkCast and s[1].typ.kind == tyProc:
s = s[1]
@ -553,8 +551,8 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType; caller: PNode)
elif tfNoSideEffect notin op.flags and not isOwnedProcVar(a, tracked.owner):
markSideEffect(tracked, a)
else:
mergeEffects(tracked, effectList.sons[exceptionEffects], n)
mergeTags(tracked, effectList.sons[tagEffects], n)
mergeEffects(tracked, effectList[exceptionEffects], n)
mergeTags(tracked, effectList[tagEffects], n)
if notGcSafe(op):
if warnGcUnsafe in tracked.config.notes: warnAboutGcUnsafe(n, tracked.config)
markGcUnsafe(tracked, a)
@ -582,23 +580,23 @@ proc breaksBlock(n: PNode): bool =
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
proc trackCase(tracked: PEffects, n: PNode) =
track(tracked, n.sons[0])
track(tracked, n[0])
let oldState = tracked.init.len
let oldFacts = tracked.guards.s.len
let stringCase = skipTypes(n.sons[0].typ,
let stringCase = skipTypes(n[0].typ,
abstractVarRange-{tyTypeDesc}).kind in {tyFloat..tyFloat128, tyString}
let interesting = not stringCase and interestingCaseExpr(n.sons[0]) and
let interesting = not stringCase and interestingCaseExpr(n[0]) and
warnProveField in tracked.config.notes
var inter: TIntersection = @[]
var toCover = 0
for i in 1..<n.len:
let branch = n.sons[i]
let branch = n[i]
setLen(tracked.init, oldState)
if interesting:
setLen(tracked.guards.s, oldFacts)
addCaseBranchFacts(tracked.guards, n, i)
for i in 0 ..< branch.len:
track(tracked, branch.sons[i])
for i in 0..<branch.len:
track(tracked, branch[i])
if not breaksBlock(branch.lastSon): inc toCover
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@ -611,28 +609,28 @@ proc trackCase(tracked: PEffects, n: PNode) =
setLen(tracked.guards.s, oldFacts)
proc trackIf(tracked: PEffects, n: PNode) =
track(tracked, n.sons[0].sons[0])
track(tracked, n[0][0])
let oldFacts = tracked.guards.s.len
addFact(tracked.guards, n.sons[0].sons[0])
addFact(tracked.guards, n[0][0])
let oldState = tracked.init.len
var inter: TIntersection = @[]
var toCover = 0
track(tracked, n.sons[0].sons[1])
if not breaksBlock(n.sons[0].sons[1]): inc toCover
track(tracked, n[0][1])
if not breaksBlock(n[0][1]): inc toCover
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
for i in 1..<n.len:
let branch = n.sons[i]
let branch = n[i]
setLen(tracked.guards.s, oldFacts)
for j in 0..i-1:
addFactNeg(tracked.guards, n.sons[j].sons[0])
addFactNeg(tracked.guards, n[j][0])
if branch.len > 1:
addFact(tracked.guards, branch.sons[0])
addFact(tracked.guards, branch[0])
setLen(tracked.init, oldState)
for i in 0 ..< branch.len:
track(tracked, branch.sons[i])
for i in 0..<branch.len:
track(tracked, branch[i])
if not breaksBlock(branch.lastSon): inc toCover
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@ -647,14 +645,14 @@ proc trackBlock(tracked: PEffects, n: PNode) =
if n.kind in {nkStmtList, nkStmtListExpr}:
var oldState = -1
for i in 0..<n.len:
if hasSubnodeWith(n.sons[i], nkBreakStmt):
if hasSubnodeWith(n[i], nkBreakStmt):
# block:
# x = def
# if ...: ... break # some nested break
# y = def
# --> 'y' not defined after block!
if oldState < 0: oldState = tracked.init.len
track(tracked, n.sons[i])
track(tracked, n[i])
if oldState > 0: setLen(tracked.init, oldState)
else:
track(tracked, n)
@ -664,10 +662,10 @@ proc isTrue*(n: PNode): bool =
n.kind == nkIntLit and n.intVal != 0
proc paramType(op: PType, i: int): PType =
if op != nil and i < op.len: result = op.sons[i]
if op != nil and i < op.len: result = op[i]
proc cstringCheck(tracked: PEffects; n: PNode) =
if n.sons[0].typ.kind == tyCString and (let a = skipConv(n[1]);
if n[0].typ.kind == tyCString and (let a = skipConv(n[1]);
a.typ.kind == tyString and a.kind notin {nkStrLit..nkTripleStrLit}):
message(tracked.config, n.info, warnUnsafeCode, renderTree(n))
@ -696,11 +694,11 @@ proc track(tracked: PEffects, n: PNode) =
tracked.owner.flags.incl sfInjectDestructors
of nkRaiseStmt:
if n[0].kind != nkEmpty:
n.sons[0].info = n.info
#throws(tracked.exc, n.sons[0])
addEffect(tracked, n.sons[0], useLineInfo=false)
for i in 0 ..< safeLen(n):
track(tracked, n.sons[i])
n[0].info = n.info
#throws(tracked.exc, n[0])
addEffect(tracked, n[0], useLineInfo=false)
for i in 0..<n.safeLen:
track(tracked, n[i])
createTypeBoundOps(tracked, n[0].typ, n.info)
else:
# A `raise` with no arguments means we're going to re-raise the exception
@ -709,7 +707,7 @@ proc track(tracked: PEffects, n: PNode) =
addEffect(tracked, createRaise(tracked.graph, n))
of nkCallKinds:
# p's effects are ours too:
var a = n.sons[0]
var a = n[0]
let op = a.typ
if n.typ != nil:
if tracked.owner.kind != skMacro and n.typ.skipTypes(abstractVar).kind != tyOpenArray:
@ -722,7 +720,7 @@ proc track(tracked: PEffects, n: PNode) =
# calling getAst(templateOrMacro()). Currently, templates and macros
# are indistinguishable from normal procs (both have tyProc type) and
# we can detect them only by checking for attached nkEffectList.
if op != nil and op.kind == tyProc and op.n.sons[0].kind == nkEffectList:
if op != nil and op.kind == tyProc and op.n[0].kind == nkEffectList:
if a.kind == nkSym:
if a.sym == tracked.owner: tracked.isRecursive = true
# even for recursive calls we need to check the lock levels (!):
@ -730,7 +728,7 @@ proc track(tracked: PEffects, n: PNode) =
if sfSideEffect in a.sym.flags: markSideEffect(tracked, a)
else:
mergeLockLevels(tracked, n, op.lockLevel)
var effectList = op.n.sons[0]
var effectList = op.n[0]
if a.kind == nkSym and a.sym.kind == skMethod:
propagateEffects(tracked, n, a.sym)
elif isNoEffectList(effectList):
@ -740,14 +738,14 @@ proc track(tracked: PEffects, n: PNode) =
assumeTheWorst(tracked, n, op)
gcsafeAndSideeffectCheck()
else:
mergeEffects(tracked, effectList.sons[exceptionEffects], n)
mergeTags(tracked, effectList.sons[tagEffects], n)
mergeEffects(tracked, effectList[exceptionEffects], n)
mergeTags(tracked, effectList[tagEffects], n)
gcsafeAndSideeffectCheck()
if a.kind != nkSym or a.sym.magic != mNBindSym:
for i in 1 ..< n.len: trackOperand(tracked, n.sons[i], paramType(op, i), a)
for i in 1..<n.len: trackOperand(tracked, n[i], paramType(op, i), a)
if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
# may not look like an assignment, but it is:
let arg = n.sons[1]
let arg = n[1]
initVarViaNew(tracked, arg)
if arg.typ.len != 0 and {tfNeedsInit} * arg.typ.lastSon.flags != {}:
if a.sym.magic == mNewSeq and n[2].kind in {nkCharLit..nkUInt64Lit} and
@ -760,24 +758,24 @@ proc track(tracked: PEffects, n: PNode) =
if n[1].typ.len > 0:
createTypeBoundOps(tracked, n[1].typ.lastSon, n.info)
createTypeBoundOps(tracked, n[1].typ, n.info)
for i in 0 ..< safeLen(n):
track(tracked, n.sons[i])
for i in 0..<n.safeLen:
track(tracked, n[i])
of nkDotExpr:
guardDotAccess(tracked, n)
for i in 0 ..< n.len: track(tracked, n.sons[i])
for i in 0..<n.len: track(tracked, n[i])
of nkCheckedFieldExpr:
track(tracked, n.sons[0])
track(tracked, n[0])
if warnProveField in tracked.config.notes:
checkFieldAccess(tracked.guards, n, tracked.config)
of nkTryStmt: trackTryStmt(tracked, n)
of nkPragma: trackPragmaStmt(tracked, n)
of nkAsgn, nkFastAsgn:
track(tracked, n.sons[1])
initVar(tracked, n.sons[0], volatileCheck=true)
invalidateFacts(tracked.guards, n.sons[0])
track(tracked, n.sons[0])
addAsgnFact(tracked.guards, n.sons[0], n.sons[1])
notNilCheck(tracked, n.sons[1], n.sons[0].typ)
track(tracked, n[1])
initVar(tracked, n[0], volatileCheck=true)
invalidateFacts(tracked.guards, n[0])
track(tracked, n[0])
addAsgnFact(tracked.guards, n[0], n[1])
notNilCheck(tracked, n[1], n[0].typ)
when false: cstringCheck(tracked, n)
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n[0].typ, n.info)
@ -788,17 +786,17 @@ proc track(tracked: PEffects, n: PNode) =
if tracked.owner.kind != skMacro:
if child.kind == nkVarTuple:
createTypeBoundOps(tracked, child[^1].typ, child.info)
for i in 0..child.len-3:
for i in 0..<child.len-2:
createTypeBoundOps(tracked, child[i].typ, child.info)
else:
createTypeBoundOps(tracked, child[0].typ, child.info)
if child.kind == nkIdentDefs and last.kind != nkEmpty:
for i in 0 .. child.len-3:
initVar(tracked, child.sons[i], volatileCheck=false)
addAsgnFact(tracked.guards, child.sons[i], last)
notNilCheck(tracked, last, child.sons[i].typ)
for i in 0..<child.len-2:
initVar(tracked, child[i], volatileCheck=false)
addAsgnFact(tracked.guards, child[i], last)
notNilCheck(tracked, last, child[i].typ)
elif child.kind == nkVarTuple and last.kind != nkEmpty:
for i in 0 .. child.len-2:
for i in 0..<child.len-1:
if child[i].kind == nkEmpty or
child[i].kind == nkSym and child[i].sym.name.s == "_":
continue
@ -814,24 +812,24 @@ proc track(tracked: PEffects, n: PNode) =
track(tracked, last)
of nkCaseStmt: trackCase(tracked, n)
of nkWhen, nkIfStmt, nkIfExpr: trackIf(tracked, n)
of nkBlockStmt, nkBlockExpr: trackBlock(tracked, n.sons[1])
of nkBlockStmt, nkBlockExpr: trackBlock(tracked, n[1])
of nkWhileStmt:
track(tracked, n.sons[0])
track(tracked, n[0])
# 'while true' loop?
if isTrue(n.sons[0]):
trackBlock(tracked, n.sons[1])
if isTrue(n[0]):
trackBlock(tracked, n[1])
else:
# loop may never execute:
let oldState = tracked.init.len
let oldFacts = tracked.guards.s.len
addFact(tracked.guards, n.sons[0])
track(tracked, n.sons[1])
addFact(tracked.guards, n[0])
track(tracked, n[1])
setLen(tracked.init, oldState)
setLen(tracked.guards.s, oldFacts)
of nkForStmt, nkParForStmt:
# we are very conservative here and assume the loop is never executed:
let oldState = tracked.init.len
for i in 0 .. n.len-3:
for i in 0..<n.len-2:
let it = n[i]
track(tracked, it)
if tracked.owner.kind != skMacro:
@ -840,8 +838,8 @@ proc track(tracked: PEffects, n: PNode) =
createTypeBoundOps(tracked, x.typ, x.info)
else:
createTypeBoundOps(tracked, it.typ, it.info)
let iterCall = n[n.len-2]
let loopBody = n[n.len-1]
let iterCall = n[^2]
let loopBody = n[^1]
if tracked.owner.kind != skMacro and iterCall.safeLen > 1:
# XXX this is a bit hacky:
if iterCall[1].typ != nil and iterCall[1].typ.skipTypes(abstractVar).kind notin {tyVarargs, tyOpenArray}:
@ -850,26 +848,26 @@ proc track(tracked: PEffects, n: PNode) =
track(tracked, loopBody)
setLen(tracked.init, oldState)
of nkObjConstr:
when false: track(tracked, n.sons[0])
when false: track(tracked, n[0])
let oldFacts = tracked.guards.s.len
for i in 1 ..< n.len:
let x = n.sons[i]
for i in 1..<n.len:
let x = n[i]
track(tracked, x)
if x.sons[0].kind == nkSym and sfDiscriminant in x.sons[0].sym.flags:
if x[0].kind == nkSym and sfDiscriminant in x[0].sym.flags:
addDiscriminantFact(tracked.guards, x)
setLen(tracked.guards.s, oldFacts)
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n.typ, n.info)
of nkPragmaBlock:
let pragmaList = n.sons[0]
let pragmaList = n[0]
let oldLocked = tracked.locked.len
let oldLockLevel = tracked.currLockLevel
var enforcedGcSafety = false
var enforceNoSideEffects = false
for i in 0 ..< pragmaList.len:
let pragma = whichPragma(pragmaList.sons[i])
for i in 0..<pragmaList.len:
let pragma = whichPragma(pragmaList[i])
if pragma == wLocks:
lockLocations(tracked, pragmaList.sons[i])
lockLocations(tracked, pragmaList[i])
elif pragma == wGcSafe:
enforcedGcSafety = true
elif pragma == wNoSideEffect:
@ -885,15 +883,15 @@ proc track(tracked: PEffects, n: PNode) =
nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef:
discard
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv:
if n.len == 2: track(tracked, n.sons[1])
if n.len == 2: track(tracked, n[1])
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
if n.len == 1: track(tracked, n.sons[0])
if n.len == 1: track(tracked, n[0])
of nkBracket:
for i in 0 ..< safeLen(n): track(tracked, n.sons[i])
for i in 0..<n.safeLen: track(tracked, n[i])
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n.typ, n.info)
else:
for i in 0 ..< safeLen(n): track(tracked, n.sons[i])
for i in 0..<n.safeLen: track(tracked, n[i])
proc subtypeRelation(g: ModuleGraph; spec, real: PNode): bool =
result = safeInheritanceDiff(g.excType(real), spec.typ) <= 0
@ -905,7 +903,7 @@ proc checkRaisesSpec(g: ModuleGraph; spec, real: PNode, msg: string, hints: bool
var used = initIntSet()
for r in items(real):
block search:
for s in 0 ..< spec.len:
for s in 0..<spec.len:
if effectPredicate(g, spec[s], r):
used.incl(s)
break search
@ -915,23 +913,23 @@ proc checkRaisesSpec(g: ModuleGraph; spec, real: PNode, msg: string, hints: bool
popInfoContext(g.config)
# hint about unnecessarily listed exception types:
if hints:
for s in 0 ..< spec.len:
for s in 0..<spec.len:
if not used.contains(s):
message(g.config, spec[s].info, hintXDeclaredButNotUsed, renderTree(spec[s]))
proc checkMethodEffects*(g: ModuleGraph; disp, branch: PSym) =
## checks for consistent effects for multi methods.
let actual = branch.typ.n.sons[0]
let actual = branch.typ.n[0]
if actual.len != effectListLen: return
let p = disp.ast.sons[pragmasPos]
let p = disp.ast[pragmasPos]
let raisesSpec = effectSpec(p, wRaises)
if not isNil(raisesSpec):
checkRaisesSpec(g, raisesSpec, actual.sons[exceptionEffects],
checkRaisesSpec(g, raisesSpec, actual[exceptionEffects],
"can raise an unlisted exception: ", hints=off, subtypeRelation)
let tagsSpec = effectSpec(p, wTags)
if not isNil(tagsSpec):
checkRaisesSpec(g, tagsSpec, actual.sons[tagEffects],
checkRaisesSpec(g, tagsSpec, actual[tagEffects],
"can have an unlisted effect: ", hints=off, subtypeRelation)
if sfThread in disp.flags and notGcSafe(branch.typ):
localError(g.config, branch.info, "base method is GC-safe, but '$1' is not" %
@ -963,14 +961,14 @@ proc setEffectsForProcType*(g: ModuleGraph; t: PType, n: PNode) =
proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PContext) =
newSeq(effects.sons, effectListLen)
effects.sons[exceptionEffects] = newNodeI(nkArgList, s.info)
effects.sons[tagEffects] = newNodeI(nkArgList, s.info)
effects.sons[usesEffects] = g.emptyNode
effects.sons[writeEffects] = g.emptyNode
effects.sons[pragmasEffects] = g.emptyNode
effects[exceptionEffects] = newNodeI(nkArgList, s.info)
effects[tagEffects] = newNodeI(nkArgList, s.info)
effects[usesEffects] = g.emptyNode
effects[writeEffects] = g.emptyNode
effects[pragmasEffects] = g.emptyNode
t.exc = effects.sons[exceptionEffects]
t.tags = effects.sons[tagEffects]
t.exc = effects[exceptionEffects]
t.tags = effects[tagEffects]
t.owner = s
t.ownerModule = s.getModule
t.init = @[]
@ -983,7 +981,7 @@ proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PC
proc trackProc*(c: PContext; s: PSym, body: PNode) =
let g = c.graph
var effects = s.typ.n.sons[0]
var effects = s.typ.n[0]
if effects.kind != nkEffectList: return
# effects already computed?
if sfForward in s.flags: return
@ -995,32 +993,32 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
if s.kind != skMacro:
let params = s.typ.n
for i in 1 ..< params.len:
for i in 1..<params.len:
let param = params[i].sym
if isSinkTypeForParam(param.typ):
createTypeBoundOps(t.graph, t.c, param.typ, param.info)
if not isEmptyType(s.typ.sons[0]) and
({tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} or
s.typ.sons[0].skipTypes(abstractInst).kind == tyVar) and
if not isEmptyType(s.typ[0]) and
({tfNeedsInit, tfNotNil} * s.typ[0].flags != {} or
s.typ[0].skipTypes(abstractInst).kind == tyVar) and
s.kind in {skProc, skFunc, skConverter, skMethod}:
var res = s.ast.sons[resultPos].sym # get result symbol
var res = s.ast[resultPos].sym # get result symbol
if res.id notin t.init:
message(g.config, body.info, warnProveInit, "result")
let p = s.ast.sons[pragmasPos]
let p = s.ast[pragmasPos]
let raisesSpec = effectSpec(p, wRaises)
if not isNil(raisesSpec):
checkRaisesSpec(g, raisesSpec, t.exc, "can raise an unlisted exception: ",
hints=on, subtypeRelation)
# after the check, use the formal spec:
effects.sons[exceptionEffects] = raisesSpec
effects[exceptionEffects] = raisesSpec
let tagsSpec = effectSpec(p, wTags)
if not isNil(tagsSpec):
checkRaisesSpec(g, tagsSpec, t.tags, "can have an unlisted effect: ",
hints=off, subtypeRelation)
# after the check, use the formal spec:
effects.sons[tagEffects] = tagsSpec
effects[tagEffects] = tagsSpec
if sfThread in s.flags and t.gcUnsafe:
if optThreads in g.config.globalOptions and optThreadAnalysis in g.config.globalOptions: