Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3054,6 +3054,13 @@ proc semExport(c: PContext, n: PNode): PNode =

s = nextOverloadIter(o, c, a)

proc isTypeTupleField(n: PNode): bool {.inline.} =
result = n.typ.kind == tyTypeDesc or
(n.typ.kind == tyGenericParam and n.typ.sym.kind == skGenericParam)
# `skGenericParam` stays as `tyGenericParam` type rather than being wrapped in `tyTypeDesc`
# would check if `n` itself is an `skGenericParam` symbol, but these symbols semcheck to an ident
# maybe check if `n` is an ident to ensure this is not a value with the generic param type?

proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
result = semTuplePositionsConstr(c, n, flags, expectedType)
if result.typ.kind == tyFromExpr:
Expand All @@ -3064,10 +3071,10 @@ proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
var isTupleType: bool = false
if tupexp.len > 0: # don't interpret () as type
internalAssert c.config, tupexp.kind == nkTupleConstr
isTupleType = tupexp[0].typ.kind == tyTypeDesc
isTupleType = isTypeTupleField(tupexp[0])
# check if either everything or nothing is tyTypeDesc
for i in 1..<tupexp.len:
if isTupleType != (tupexp[i].typ.kind == tyTypeDesc):
if isTupleType != isTypeTupleField(tupexp[i]):
return localErrorNode(c, n, tupexp[i].info, "Mixing types and values in tuples is not allowed.")
if isTupleType: # expressions as ``(int, string)`` are reinterpret as type expressions
result = n
Expand Down
34 changes: 34 additions & 0 deletions tests/tuples/tgenericparamtypetuple.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# issue #25312

import heapqueue

proc test1[T](test: (float, T)) = # Works
discard

proc test2[T](test: seq[(float, T)]) = # Works
discard

proc test3[T](test: HeapQueue[tuple[sqd: float, data: T]]) = # Works
discard

proc test4(test: HeapQueue[(float, float)]) = # Works
discard

type ExampleObj = object
a: string
b: seq[float]

proc test5(test: HeapQueue[(float, ExampleObj)]) = # Works
discard

proc failingTest[T](test: HeapQueue[(float, T)]) = # (Compile) Error: Mixing types and values in tuples is not allowed.
discard

proc failingTest2[T](test: HeapQueue[(T, float)]) = # (Compile) Error: Mixing types and values in tuples is not allowed.
discard

proc test6[T](test: HeapQueue[(T, T)]) = # works
discard

proc test7[T, U](test: HeapQueue[(T, U)]) = # works
discard