mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-24 21:59:52 +00:00
fix #25789 This pull request addresses an issue with the `distinctBase` trait in the Nim compiler, ensuring it correctly handles types with generic parameters and static parameters. Additionally, it adds a new test to cover this scenario. The most important changes are: ### Compiler logic improvements * Updated the `evalTypeTrait` implementation for the `distinctBase` trait in `compiler/semmagic.nim` to properly skip all relevant type wrappers, including those with generic and static parameters, when unwrapping distinct types. This fixes incorrect handling of types like `distinct L[int, 100]`. ### Test coverage * Added a new test block for bug #25789 in `tests/metatype/ttypetraits.nim` that defines a distinct type over a generic type with a static parameter, verifies conversions, and checks that the `distinctBase` trait returns the correct type.
This commit is contained in:
@@ -248,10 +248,13 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
||||
assert operand.kind == tyTuple, $operand.kind
|
||||
result = newIntNodeT(toInt128(operand.len), traitCall, c.idgen, c.graph)
|
||||
of "distinctBase":
|
||||
var arg = operand.skipTypes({tyGenericInst})
|
||||
var arg = operand.skipTypes(skippedTypes)
|
||||
let rec = semConstExpr(c, traitCall[2]).intVal != 0
|
||||
while arg.kind == tyDistinct:
|
||||
arg = arg.base.skipTypes(skippedTypes + {tyGenericInst})
|
||||
while true:
|
||||
let distinctArg = arg.skipTypes(skippedTypes + {tyGenericInst})
|
||||
if distinctArg.kind != tyDistinct:
|
||||
break
|
||||
arg = distinctArg.base.skipTypes(skippedTypes)
|
||||
if not rec: break
|
||||
result = getTypeDescNode(c, arg, operand.owner, traitCall.info)
|
||||
of "rangeBase":
|
||||
|
||||
@@ -434,3 +434,32 @@ block: # bug #24378
|
||||
type Win222[T] = typeof("foobar")
|
||||
doAssert not supportsCopyMem((int, Win222[int]))
|
||||
doAssert not supportsCopyMem(tuple[a: int, b: Win222[int]])
|
||||
|
||||
block: # bug #25789
|
||||
type
|
||||
L[T; N: static int] = distinct seq[T]
|
||||
EPF = distinct L[int, 100]
|
||||
|
||||
var e: EPF = EPF(L[int, 100](@[1, 2, 3]))
|
||||
|
||||
template classifyGeneric[T](x: T): bool =
|
||||
when typeof(x) is L:
|
||||
true
|
||||
else:
|
||||
false
|
||||
|
||||
template classifyConcrete[T](x: T): bool =
|
||||
when typeof(x) is L[int, 100]:
|
||||
true
|
||||
else:
|
||||
false
|
||||
|
||||
let viaConv = L[int, 100](e)
|
||||
doAssert $type(viaConv) == "L[system.int, 100]"
|
||||
doAssert classifyGeneric(viaConv)
|
||||
doAssert classifyConcrete(viaConv)
|
||||
|
||||
let viaDB = distinctBase(e, recursive = false)
|
||||
doAssert $type(viaDB) == "L[system.int, 100]"
|
||||
doAssert classifyGeneric(viaDB)
|
||||
doAssert classifyConcrete(viaDB)
|
||||
|
||||
Reference in New Issue
Block a user