Skip to content

Commit 6f3fdeb

Browse files
authored
propagate used typevar count in nested invoke (#1171)
fixes #1167 Invocations track if semchecking their arguments adds to a counter of used typevar symbols, to decide if the invocation is concrete or not so that it can be instantiated. However it does this by swapping the counter with a local variable, which isolates the typevar count in the arguments from the typevar count of the invocation itself. So invocations with generic parameters do not count as generic when nested inside another invocation, which wrongly instantiates it. To fix this, the typevar counter is not isolated, only the counter changing is tracked. Worst case `containsGenericParams` can be used on each of the arguments.
1 parent 318e788 commit 6f3fdeb

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

src/nimony/semtypes.nim

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
323323
var paramCount = 0
324324
var argCount = 0
325325
var m = createMatch(addr c)
326-
var genericArgs = 0
327-
swap c.usedTypevars, genericArgs
326+
let usedTypevarsInitial = c.usedTypevars
328327
let beforeArgs = c.dest.len
329328
while n.kind != ParRi:
330329
inc argCount
@@ -349,15 +348,16 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
349348
addArg = false
350349
if addArg:
351350
c.dest.add argBuf
352-
swap c.usedTypevars, genericArgs
351+
let usedTypevarsFinal = c.usedTypevars
352+
let isConcrete = usedTypevarsInitial == usedTypevarsFinal # no generic params were used
353353
takeParRi c, n
354354
if ok and paramCount != argCount:
355355
c.dest.shrink typeStart
356356
c.buildErr info, "wrong amount of generic parameters for type " & pool.syms[headId] &
357357
", expected " & $paramCount & " but got " & $argCount
358358
return
359359

360-
if ok and (genericArgs == 0 or
360+
if ok and (isConcrete or
361361
# structural types are inlined even with generic arguments
362362
not isNominal(decl.body.typeKind)):
363363
# we have to be eager in generic type instantiations so that type-checking
@@ -374,7 +374,7 @@ proc semInvoke(c: var SemContext; n: var Cursor) =
374374
let instSuffix = instToSuffix(c.dest, typeStart)
375375
let targetSym = newInstSymId(c, headId, instSuffix)
376376
c.instantiatedTypes[key] = targetSym
377-
if genericArgs == 0:
377+
if isConcrete:
378378
c.typeInstDecls.add targetSym
379379
var sub = createTokenBuf(30)
380380
subsGenericTypeFromArgs c, sub, info, instSuffix, headId, targetSym, decl, args
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type
2+
Foo[T] = object
3+
Bar[T] = object
4+
5+
proc foo[T](x: Foo[Bar[T]]) = discard
6+
var x = Foo[Bar[int]]()
7+
foo x

0 commit comments

Comments
 (0)