summary refs log tree commit diff stats
path: root/compiler/sempass2.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/sempass2.nim')
-rw-r--r--compiler/sempass2.nim244
1 files changed, 121 insertions, 123 deletions
diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim
index 36179511c..e64bccdce 100644
--- a/compiler/sempass2.nim
+++ b/compiler/sempass2.nim
@@ -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
-
-  t.exc = effects.sons[exceptionEffects]
-  t.tags = effects.sons[tagEffects]
+  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[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: