Skip to content

Commit

Permalink
varargs[typed] should behave more like typed (#23303)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Graveflo authored Feb 20, 2024
1 parent 7bf8cd3 commit ca77423
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
23 changes: 21 additions & 2 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
10 changes: 10 additions & 0 deletions tests/types/tissues_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit ca77423

Please sign in to comment.