Skip to content

Commit

Permalink
sem: correctly type empty containers in macro calls (#1361)
Browse files Browse the repository at this point in the history
## Summary

Internal-only issue. Empty container values passed to `static` macro/
template parameters used empty container types. Now they're converted
to the formal parameter's type.

## Details

* wrap the arguments to `static` macro/template parameters in
  implicit conversions, if needed for the match
* use post-match argument fitting for macro calls
* for a smaller impact, template calls still don't use post-match
  argument fitting
* remove the `vmserialize` workaround for empty set types (which no
  longer reach there now)
  • Loading branch information
zerbina authored Jun 29, 2024
1 parent 0ae0cd5 commit d7353ba
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
8 changes: 6 additions & 2 deletions compiler/sem/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1182,8 +1182,12 @@ proc afterCallActions(c: PContext; n: PNode, flags: TExprFlags): PNode =
result = n
let callee = result[0].sym
case callee.kind
of skMacro: result = semMacroExpr(c, result, callee, flags)
of skTemplate: result = semTemplateExpr(c, result, callee, flags)
of skMacro:
result = fitArgTypesPostMatch(c, result)
if result.kind != nkError:
result = semMacroExpr(c, result, callee, flags)
of skTemplate:
result = semTemplateExpr(c, result, callee, flags)
else:
semFinishOperands(c, result)
activate(c, result)
Expand Down
24 changes: 20 additions & 4 deletions compiler/sem/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2311,10 +2311,26 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
of tyTyped, tyTypeDesc:
arg
of tyStatic:
if arg.typ.n.isNil: # no value on the type
argSemantized
else: # value on the type
arg.typ.n
let n =
if arg.typ.n.isNil: # no value on the type
argSemantized
else: # value on the type
arg.typ.n

# XXX: the implicit conversion handling is duplicated from the non-
# template/non-macro path. Template and macro arguments shouldn't
# be special-cased like this
case r
of isEqual: n
of isGeneric:
if n.typ.isEmptyContainer:
implicitConv(nkHiddenStdConv, f[0], n, m, c)
else:
n
of isSubtype:
implicitConv(nkHiddenSubConv, f[0], n, m, c)
else:
implicitConv(nkHiddenStdConv, f[0], n, m, c)
else:
argSemantized
return
Expand Down
6 changes: 1 addition & 5 deletions compiler/vm/vmserialize.nim
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,7 @@ proc initFromExpr(dest: LocHandle, tree: MirTree, n: var int, env: MirEnv,
# subtract the first element's value to make all values zero-based
toInt(val - first)

let first =
if tree[n].len > 0: firstOrd(c.config, env[tree[n].typ])
else: Zero
# XXX: ^^ ``set[empty]``-typed literals reach here, but they shouldn't. The
# len guard works around the issue
let first = firstOrd(c.config, env[tree[n].typ])
iterTree(j):
let node = next()
if node.kind == mnkRange:
Expand Down

0 comments on commit d7353ba

Please sign in to comment.