varargs[typed] should behave more like typed (#23303)

This fixes an oversight with a change that I made a while ago.

Basically, these two snippets should both compile. Currently the
`varargs` version will fail.

```nim
template s(d: typed)=discard
proc something()=discard
proc something(x:int)=discard

s(something)
```

```nim
template s(d: varargs[typed])=discard
proc something()=discard
proc something(x:int)=discard

s(something)
```

Potentially unrelated, but this works currently for some reason:
```nim
template s(a: varargs[typed])=discard
proc something()=discard
proc something(x:int)=discard

s:
  something
```

also, this works:
```nim
template s(b:untyped, a: varargs[typed])=discard
proc something()=discard
proc something(x:int)=discard

s (g: int):
  something
```
but this doesn't, and the error message is not what I would expect:
```nim
template s(b:untyped, a: varargs[typed])=discard
proc something()=discard
proc something(x:int)=discard

s (g: int), something
```

So far as I can tell, none of these issues persist for me after the code
changes in this PR.
This commit is contained in:
Ryan McConnell
2024-02-20 02:08:16 -05:00
committed by GitHub
parent 7bf8cd3f86
commit ca77423ffc
2 changed files with 31 additions and 2 deletions

View File

@@ -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:

View File

@@ -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)