diff options
-rw-r--r-- | compiler/sigmatch.nim | 23 | ||||
-rw-r--r-- | tests/types/tissues_types.nim | 10 |
2 files changed, 31 insertions, 2 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index a0de33ed5..e831a2856 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -2311,6 +2311,9 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, if f.n != nil: # Forward to the varargs converter result = localConvMatch(c, m, f, a, arg) + elif f[0].kind == tyTyped: + inc m.genericMatches + result = arg else: r = typeRel(m, base(f), a) case r @@ -2360,7 +2363,11 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType, var best = -1 result = arg - if f.kind in {tyTyped, tyUntyped}: + var actingF = f + if f.kind == tyVarargs: + if m.calleeSym.kind in {skTemplate, skMacro}: + actingF = f[0] + if actingF.kind in {tyTyped, tyUntyped}: var bestScope = -1 counts = 0 @@ -2376,6 +2383,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType, if best == -1: result = nil elif counts > 0: + m.genericMatches = 1 best = -1 else: # CAUTION: The order depends on the used hashing scheme. Thus it is @@ -2497,6 +2505,9 @@ proc incrIndexType(t: PType) = template isVarargsUntyped(x): untyped = x.kind == tyVarargs and x[0].kind == tyUntyped +template isVarargsTyped(x): untyped = + x.kind == tyVarargs and x[0].kind == tyTyped + proc findFirstArgBlock(m: var TCandidate, n: PNode): int = # see https://github.com/nim-lang/RFCs/issues/405 result = int.high @@ -2671,7 +2682,15 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int n[a], nOrig[a]) if arg == nil: noMatch() - if m.baseTypeMatch: + if formal.typ.isVarargsTyped and m.calleeSym.kind in {skTemplate, skMacro}: + if container.isNil: + container = newNodeIT(nkBracket, n[a].info, arrayConstr(c, n.info)) + setSon(m.call, formal.position + 1, implicitConv(nkHiddenStdConv, formal.typ, container, m, c)) + else: + incrIndexType(container.typ) + container.add n[a] + f = max(f, formalLen - n.len + a + 1) + elif m.baseTypeMatch: assert formal.typ.kind == tyVarargs #assert(container == nil) if container.isNil: diff --git a/tests/types/tissues_types.nim b/tests/types/tissues_types.nim index 49c6d85ee..6bb1258f4 100644 --- a/tests/types/tissues_types.nim +++ b/tests/types/tissues_types.nim @@ -106,3 +106,13 @@ block: let t = Foo[float](x1: 1) doAssert t.x1 == 1 +block: + template s(d: varargs[typed])=discard + + proc something(x:float)=discard + proc something(x:int)=discard + proc otherthing()=discard + + s(something) + s(otherthing, something) + s(something, otherthing) |