Showing with 1,572 additions and 389 deletions.
  1. +22 −5 compiler/ccgexprs.nim
  2. +1 −1 compiler/cgen.nim
  3. +3 −1 compiler/closureiters.nim
  4. +10 −6 compiler/depends.nim
  5. +1 −1 compiler/extccomp.nim
  6. +1 −1 compiler/importer.nim
  7. +3 −2 compiler/injectdestructors.nim
  8. +19 −5 compiler/lambdalifting.nim
  9. +6 −3 compiler/lookups.nim
  10. +4 −1 compiler/lowerings.nim
  11. +6 −1 compiler/nimeval.nim
  12. +5 −1 compiler/pragmas.nim
  13. +49 −3 compiler/sem.nim
  14. +6 −2 compiler/semcall.nim
  15. +9 −7 compiler/semexprs.nim
  16. +3 −1 compiler/seminst.nim
  17. +1 −1 compiler/sempass2.nim
  18. +19 −13 compiler/semstmts.nim
  19. +47 −19 compiler/semtempl.nim
  20. +27 −15 compiler/semtypes.nim
  21. +3 −2 compiler/semtypinst.nim
  22. +22 −13 compiler/sigmatch.nim
  23. +9 −1 compiler/suggest.nim
  24. +23 −2 compiler/transf.nim
  25. +17 −10 compiler/types.nim
  26. +19 −2 compiler/vm.nim
  27. +1 −1 compiler/vmdef.nim
  28. +54 −21 compiler/vmgen.nim
  29. +1 −0 compiler/wordrecg.nim
  30. +4 −1 config/nim.cfg
  31. +1 −1 lib/compilation.nim
  32. +4 −3 lib/core/macros.nim
  33. +8 −2 lib/posix/posix_linux_amd64.nim
  34. +1 −0 lib/posix/posix_linux_amd64_consts.nim
  35. +1 −0 lib/posix/posix_other_consts.nim
  36. +1 −1 lib/pure/asynchttpserver.nim
  37. +2 −3 lib/pure/collections/deques.nim
  38. +22 −22 lib/pure/collections/lists.nim
  39. +5 −3 lib/pure/collections/tableimpl.nim
  40. +15 −2 lib/pure/collections/tables.nim
  41. +14 −6 lib/pure/hashes.nim
  42. +63 −60 lib/pure/math.nim
  43. +2 −2 lib/pure/os.nim
  44. +1 −1 lib/pure/pegs.nim
  45. +24 −10 lib/pure/strformat.nim
  46. +37 −8 lib/pure/strutils.nim
  47. +0 −1 lib/std/packedsets.nim
  48. +1 −1 lib/system.nim
  49. +1 −1 lib/system/alloc.nim
  50. +11 −8 lib/system/cellseqs_v1.nim
  51. +10 −13 lib/system/cellseqs_v2.nim
  52. +1 −1 lib/system/comparisons.nim
  53. +0 −6 lib/system/memalloc.nim
  54. +2 −2 lib/system/mm/malloc.nim
  55. +1 −1 lib/system/repr_v2.nim
  56. +3 −1 lib/system/sets.nim
  57. +62 −37 lib/system/strs_v2.nim
  58. +6 −0 nimsuggest/tests/module_20265.nim
  59. +8 −0 nimsuggest/tests/t20265_1.nim
  60. +8 −0 nimsuggest/tests/t20265_2.nim
  61. +2 −2 testament/important_packages.nim
  62. +16 −0 tests/align/talign.nim
  63. +55 −0 tests/arc/t22237.nim
  64. +30 −0 tests/arc/tarc_orc.nim
  65. +1 −1 tests/arc/tcontrolflow.nim
  66. +1 −0 tests/async/tasyncssl.nim
  67. +22 −0 tests/ccgbugs/t15428.nim
  68. +15 −0 tests/ccgbugs/twrong_tupleconv.nim
  69. +11 −0 tests/closure/tclosure.nim
  70. +17 −0 tests/collections/tseq.nim
  71. +27 −0 tests/compilerapi/tcompilerapi.nim
  72. +13 −3 tests/controlflow/tunreachable.nim
  73. +9 −0 tests/errmsgs/t22097.nim
  74. +3 −0 tests/errmsgs/tassignunpack.nim
  75. +2 −0 tests/errmsgs/ttupleindexoutofbounds.nim
  76. +36 −0 tests/exprs/t22604.nim
  77. +25 −0 tests/generics/t17509.nim
  78. +20 −1 tests/generics/timplicit_and_explicit.nim
  79. +16 −0 tests/generics/tuninstantiated_failure.nim
  80. +1 −1 tests/import/buzz/m21496.nim
  81. +1 −1 tests/import/fizz/m21496.nim
  82. +1 −1 tests/import/t21496.nim
  83. +6 −0 tests/import/t22208.nim
  84. +22 −0 tests/iter/t21737.nim
  85. +21 −0 tests/iter/t22548.nim
  86. +15 −0 tests/iter/titer.nim
  87. +1 −6 tests/js/tstdlib_various.nim
  88. +20 −0 tests/lent/tlent_from_var.nim
  89. +17 −0 tests/lookups/tundeclaredmixin.nim
  90. +1 −0 tests/misc/trunner_special.nim
  91. +32 −0 tests/objects/twhen1.nim
  92. +11 −0 tests/overload/tvartypeclass.nim
  93. +5 −0 tests/pragmas/tuserpragmaargs.nim
  94. +3 −0 tests/statictypes/t5780.nim
  95. +10 −0 tests/stdlib/t20023.nim
  96. +6 −0 tests/stdlib/t21251.nim
  97. +1 −1 tests/stdlib/tmacros.nim
  98. +15 −0 tests/stdlib/tmath.nim
  99. +1 −6 tests/stdlib/tstdlib_various.nim
  100. +11 −0 tests/stdlib/tstrformat.nim
  101. +8 −0 tests/stdlib/tstrformatlineinfo.nim
  102. +20 −2 tests/stdlib/tstrutils.nim
  103. +7 −0 tests/stdlib/tsystem.nim
  104. +51 −0 tests/system/tcomparisons.nim
  105. +1 −0 tests/system/tgcnone.nim
  106. +10 −0 tests/template/t21231.nim
  107. +8 −0 tests/template/t21532.nim
  108. +4 −0 tests/template/template_issues.nim
  109. +12 −0 tests/template/tobjectdeclfield.nim
  110. +26 −0 tests/tuples/ttuples_various.nim
  111. +1 −1 tests/types/tassignemptytuple.nim
  112. +16 −4 tests/types/tcyclic.nim
  113. +39 −0 tests/types/tinheritgenericparameter.nim
  114. +35 −0 tests/types/ttopdowninference.nim
  115. +0 −19 tests/vm/t19075.nim
  116. +32 −0 tests/vm/tnoreturn.nim
  117. +18 −0 tests/vm/ttypedesc.nim
  118. +3 −0 tests/vm/tunsupportedintfloatcast.nim
  119. +48 −2 tests/vm/tvmmisc.nim
  120. +1 −0 tools/detect/detect.nim
27 changes: 22 additions & 5 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,10 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) =
[addrLoc(p.config, dest), rdLoc(src),
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
of tyOpenArray, tyVarargs:
let source = addrLocOrTemp(src)
linefmt(p, cpsStmts,
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
[addrLoc(p.config, dest), addrLocOrTemp(src),
"#genericDeepCopyOpenArray((void*)$1, (void*)$2, $2->Field1, $3);$n",
[addrLoc(p.config, dest), source,
genTypeInfoV1(p.module, dest.t, dest.lode.info)])
of tySet:
if mapSetType(p.config, ty) == ctArray:
Expand Down Expand Up @@ -1446,6 +1447,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
getSeqPayloadType(p.module, seqtype),
])
else:
if d.k == locNone: getTemp(p, e.typ, d, needsInit=false) # bug #22560
putIntoDest(p, d, e, ropecg(p.module,
"($1)#nimNewSeqOfCap($2, $3)", [
getTypeDesc(p.module, seqtype),
Expand Down Expand Up @@ -2566,15 +2568,30 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
if not handleConstExpr(p, n, d):
let t = n.typ
discard getTypeDesc(p.module, t) # so that any fields are initialized
if d.k == locNone: getTemp(p, t, d)

var tmp: TLoc
# bug #16331
let doesAlias = lhsDoesAlias(d.lode, n)
let dest = if doesAlias: addr(tmp) else: addr(d)
if doesAlias:
getTemp(p, n.typ, tmp)
elif d.k == locNone:
getTemp(p, n.typ, d)

for i in 0..<n.len:
var it = n[i]
if it.kind == nkExprColonExpr: it = it[1]
initLoc(rec, locExpr, it, d.storage)
rec.r = "$1.Field$2" % [rdLoc(d), rope(i)]
initLoc(rec, locExpr, it, dest[].storage)
rec.r = "$1.Field$2" % [rdLoc(dest[]), rope(i)]
rec.flags.incl(lfEnforceDeref)
expr(p, it, rec)

if doesAlias:
if d.k == locNone:
d = tmp
else:
genAssignment(p, d, tmp, {})

proc isConstClosure(n: PNode): bool {.inline.} =
result = n[0].kind == nkSym and isRoutine(n[0].sym) and
n[1].kind == nkNilLit
Expand Down
2 changes: 1 addition & 1 deletion compiler/cgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1266,10 +1266,10 @@ proc genVarPrototype(m: BModule, n: PNode) =
if sym.owner.id != m.module.id:
# else we already have the symbol generated!
assert(sym.loc.r != nil)
incl(m.declaredThings, sym.id)
if sfThread in sym.flags:
declareThreadVar(m, sym, true)
else:
incl(m.declaredThings, sym.id)
if sym.kind in {skLet, skVar, skField, skForVar} and sym.alignment > 0:
m.s[cfsVars].addf "NIM_ALIGN($1) ", [rope(sym.alignment)]
m.s[cfsVars].add(if m.hcrOn: "static " else: "extern ")
Expand Down
4 changes: 3 additions & 1 deletion compiler/closureiters.nim
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,9 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
case n.kind
of nkReturnStmt:
# We're somewhere in try, transform to finally unrolling
assert(ctx.nearestFinally != 0)
if ctx.nearestFinally == 0:
# return is within the finally
return

result = newNodeI(nkStmtList, n.info)

Expand Down
16 changes: 10 additions & 6 deletions compiler/depends.nim
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,16 @@ proc toNimblePath(s: string, isStdlib: bool): string =
sub.add "/pkgs/"
var start = s.find(sub)
if start < 0:
result = s
else:
start += sub.len
start += skipUntil(s, '/', start)
start += 1
result = pkgPrefix & s[start..^1]
sub[^1] = '2'
sub.add '/'
start = s.find(sub) # /pkgs2
if start < 0:
return s

start += sub.len
start += skipUntil(s, '/', start)
start += 1
result = pkgPrefix & s[start..^1]

proc addDependency(c: PPassContext, g: PGen, b: Backend, n: PNode) =
doAssert n.kind == nkSym, $n.kind
Expand Down
2 changes: 1 addition & 1 deletion compiler/extccomp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,

compilePattern = joinPath(conf.cCompilerPath, exe)
else:
compilePattern = getCompilerExe(conf, c, isCpp)
compilePattern = exe

includeCmd.add(join([CC[c].includeCmd, quoteShell(conf.projectPath.string)]))

Expand Down
2 changes: 1 addition & 1 deletion compiler/importer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ proc importModuleAs(c: PContext; n: PNode, realModule: PSym, importHidden: bool)
result.options.incl optImportHidden
c.unusedImports.add((result, n.info))
c.importModuleMap[result.id] = realModule.id
c.importModuleLookup.mgetOrPut(realModule.name.id, @[]).addUnique realModule.id
c.importModuleLookup.mgetOrPut(result.name.id, @[]).addUnique realModule.id

proc transformImportAs(c: PContext; n: PNode): tuple[node: PNode, importHidden: bool] =
var ret: typeof(result)
Expand Down
5 changes: 3 additions & 2 deletions compiler/injectdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =

proc sameLocation*(a, b: PNode): bool =
proc sameConstant(a, b: PNode): bool =
a.kind in nkLiterals and a.intVal == b.intVal
a.kind in nkLiterals and b.kind in nkLiterals and a.intVal == b.intVal

const nkEndPoint = {nkSym, nkDotExpr, nkCheckedFieldExpr, nkBracketExpr}
if a.kind in nkEndPoint and b.kind in nkEndPoint:
Expand Down Expand Up @@ -1054,7 +1054,8 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
else:
result = newTree(nkFastAsgn, dest, p(ri, c, s, normal))
else:
case ri.kind
let ri2 = if ri.kind == nkWhen: ri[1][0] else: ri
case ri2.kind
of nkCallKinds:
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
of nkBracketExpr:
Expand Down
24 changes: 19 additions & 5 deletions compiler/lambdalifting.nim
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ type
processed, capturedVars: IntSet
ownerToType: Table[int, PType]
somethingToDo: bool
inTypeOf: bool
graph: ModuleGraph
idgen: IdGenerator

Expand Down Expand Up @@ -401,6 +402,9 @@ Consider:
"""

proc isTypeOf(n: PNode): bool =
n.kind == nkSym and n.sym.magic in {mTypeOf, mType}

proc addClosureParam(c: var DetectionPass; fn: PSym; info: TLineInfo) =
var cp = getEnvParam(fn)
let owner = if fn.kind == skIterator: fn else: fn.skipGenericOwner
Expand Down Expand Up @@ -437,7 +441,8 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
c.somethingToDo = true
addClosureParam(c, owner, n.info)
if interestingIterVar(s):
if not c.capturedVars.containsOrIncl(s.id):
if not c.capturedVars.contains(s.id):
if not c.inTypeOf: c.capturedVars.incl(s.id)
let obj = getHiddenParam(c.graph, owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
#let obj = c.getEnvTypeForOwner(s.owner).skipTypes({tyOwned, tyRef, tyPtr})

Expand All @@ -463,10 +468,12 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
addClosureParam(c, owner, n.info)
#echo "capturing ", n.info
# variable 's' is actually captured:
if interestingVar(s) and not c.capturedVars.containsOrIncl(s.id):
let obj = c.getEnvTypeForOwner(ow, n.info).skipTypes({tyOwned, tyRef, tyPtr})
#getHiddenParam(owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
discard addField(obj, s, c.graph.cache, c.idgen)
if interestingVar(s):
if not c.capturedVars.contains(s.id):
if not c.inTypeOf: c.capturedVars.incl(s.id)
let obj = c.getEnvTypeForOwner(ow, n.info).skipTypes({tyOwned, tyRef, tyPtr})
#getHiddenParam(owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
discard addField(obj, s, c.graph.cache, c.idgen)
# create required upFields:
var w = owner.skipGenericOwner
if isInnerProc(w) or owner.isIterator:
Expand Down Expand Up @@ -498,9 +505,14 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
detectCapturedVars(n[namePos], owner, c)
of nkReturnStmt:
detectCapturedVars(n[0], owner, c)
of nkIdentDefs:
detectCapturedVars(n[^1], owner, c)
else:
if n.isCallExpr and n[0].isTypeOf:
c.inTypeOf = true
for i in 0..<n.len:
detectCapturedVars(n[i], owner, c)
c.inTypeOf = false

type
LiftingPass = object
Expand Down Expand Up @@ -780,6 +792,8 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: var DetectionPass;
of nkTypeOfExpr:
result = n
else:
if n.isCallExpr and n[0].isTypeOf:
return
if owner.isIterator:
if nfLL in n.flags:
# special case 'when nimVm' due to bug #3636:
Expand Down
9 changes: 6 additions & 3 deletions compiler/lookups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import std/[algorithm, strutils, tables]
import
intsets, ast, astalgo, idents, semdata, types, msgs, options,
renderer, nimfix/prettybase, lineinfos, modulegraphs, astmsgs
renderer, nimfix/prettybase, lineinfos, modulegraphs, astmsgs, wordrecg

proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)

Expand Down Expand Up @@ -311,10 +311,10 @@ proc wrongRedefinition*(c: PContext; info: TLineInfo, s: string;
proc addDeclAt*(c: PContext; scope: PScope, sym: PSym, info: TLineInfo) =
let conflict = scope.addUniqueSym(sym)
if conflict != nil:
if sym.kind == skModule and conflict.kind == skModule:
if sym.kind == skModule and conflict.kind == skModule:
# e.g.: import foo; import foo
# xxx we could refine this by issuing a different hint for the case
# where a duplicate import happens inside an include.
# where a duplicate import happens inside an include.
if c.importModuleMap[sym.id] == c.importModuleMap[conflict.id]:
#only hints if the conflict is the actual module not just a shared name
localError(c.config, info, hintDuplicateModuleImport,
Expand Down Expand Up @@ -604,6 +604,9 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
result = errorUndeclaredIdentifierHint(c, n[1], ident)
elif n[1].kind == nkSym:
result = n[1].sym
if result.owner != nil and result.owner != m and checkUndeclared in flags:
# dotExpr in templates can end up here
result = errorUndeclaredIdentifierHint(c, n[1], considerQuotedIdent(c, n[1]))
elif checkUndeclared in flags and
n[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(c.config, n[1].info, "identifier expected, but got: " &
Expand Down
5 changes: 4 additions & 1 deletion compiler/lowerings.nim
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; idgen: IdGenerator; o

var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
vpart[0] = tempAsNode
vpart[1] = newNodeI(nkEmpty, value.info)
vpart[1] = newNodeI(nkTupleClassTy, value.info)
vpart[2] = value
v.add vpart
result.add(v)
Expand Down Expand Up @@ -235,6 +235,9 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym
field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
let t = skipIntLit(s.typ, idgen)
field.typ = t
if s.kind in {skLet, skVar, skField, skForVar}:
#field.bitsize = s.bitsize
field.alignment = s.alignment
assert t.kind != tyTyped
propagateToOwner(obj, t)
field.position = obj.n.len
Expand Down
7 changes: 6 additions & 1 deletion compiler/nimeval.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import
ast, astalgo, modules, passes, condsyms,
options, sem, llstream, lineinfos, vm,
vmdef, modulegraphs, idents, os, pathutils,
passaux, scriptconfig, std/compilesettings
passaux,
scriptconfig, std/[compilesettings, tables]


type
Interpreter* = ref object ## Use Nim as an interpreter with this object
Expand Down Expand Up @@ -72,6 +74,9 @@ proc evalScript*(i: Interpreter; scriptStream: PLLStream = nil) =
assert i != nil
assert i.mainModule != nil, "no main module selected"
initStrTables(i.graph, i.mainModule)
i.graph.cacheSeqs.clear()
i.graph.cacheCounters.clear()
i.graph.cacheTables.clear()
i.mainModule.ast = nil

let s = if scriptStream != nil: scriptStream
Expand Down
6 changes: 5 additions & 1 deletion compiler/pragmas.nim
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
validPragmas: TSpecialWords,
comesFromPush, isStatement: bool): bool =
var it = n[i]
var key = if it.kind in nkPragmaCallKinds and it.len > 1: it[0] else: it
let keyDeep = it.kind in nkPragmaCallKinds and it.len > 1
var key = if keyDeep: it[0] else: it
if key.kind == nkBracketExpr:
processNote(c, it)
return
Expand All @@ -842,6 +843,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
if c.instCounter > 100:
globalError(c.config, it.info, "recursive dependency: " & userPragma.name.s)

if keyDeep:
localError(c.config, it.info, "user pragma cannot have arguments")

pragma(c, sym, userPragma.ast, validPragmas, isStatement)
n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content
i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty
Expand Down
52 changes: 49 additions & 3 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,58 @@ proc commonType*(c: PContext; x, y: PType): PType =
result.addSonSkipIntLit(r, c.idgen)

proc endsInNoReturn(n: PNode): bool =
# check if expr ends in raise exception or call of noreturn proc
## check if expr ends the block like raising or call of noreturn procs do
result = false # assume it does return

template checkBranch(branch) =
if not endsInNoReturn(branch):
# proved a branch returns
return false

var it = n
# skip these beforehand, no special handling needed
while it.kind in {nkStmtList, nkStmtListExpr} and it.len > 0:
it = it.lastSon
result = it.kind in nkLastBlockStmts or
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags

case it.kind
of nkIfStmt:
var hasElse = false
for branch in it:
checkBranch:
if branch.len == 2:
branch[1]
elif branch.len == 1:
hasElse = true
branch[0]
else:
raiseAssert "Malformed `if` statement during endsInNoReturn"
# none of the branches returned
result = hasElse # Only truly a no-return when it's exhaustive
of nkCaseStmt:
for i in 1 ..< it.len:
let branch = it[i]
checkBranch:
case branch.kind
of nkOfBranch:
branch[^1]
of nkElifBranch:
branch[1]
of nkElse:
branch[0]
else:
raiseAssert "Malformed `case` statement in endsInNoReturn"
# none of the branches returned
result = true
of nkTryStmt:
checkBranch(it[0])
for i in 1 ..< it.len:
let branch = it[i]
checkBranch(branch[^1])
# none of the branches returned
result = true
else:
result = it.kind in nkLastBlockStmts or
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags

proc commonType*(c: PContext; x: PType, y: PNode): PType =
# ignore exception raising branches in case/if expressions
Expand Down
8 changes: 6 additions & 2 deletions compiler/semcall.nim
Original file line number Diff line number Diff line change
Expand Up @@ -660,14 +660,18 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
onUse(info, s)
result = newSymNode(newInst, info)

proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
assert n.kind == nkBracketExpr
proc setGenericParams(c: PContext, n: PNode) =
## sems generic params in subscript expression
for i in 1..<n.len:
let e = semExprWithType(c, n[i])
if e.typ == nil:
n[i].typ = errorType(c)
else:
n[i].typ = e.typ.skipTypes({tyTypeDesc})

proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
assert n.kind == nkBracketExpr
setGenericParams(c, n)
var s = s
var a = n[0]
if a.kind == nkSym:
Expand Down
Loading