From 35b9d6a2d9d7e5db22e7468cfe93fdf0528b1f06 Mon Sep 17 00:00:00 2001 From: Ryan McConnell Date: Mon, 1 Jul 2024 08:39:16 -0400 Subject: [PATCH] fixes #23755; array static inference during overload resolution (#23760) --------- Co-authored-by: Andreas Rumpf (cherry picked from commit 27abcdd57f43fa905153f38afc7b10b990d789c9) --- compiler/sigmatch.nim | 7 +++--- compiler/types.nim | 23 +++++++++++------ tests/overload/t23755.nim | 52 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 tests/overload/t23755.nim diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index f18bf76d82de..fbeddcaf1cd3 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1283,13 +1283,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, subtypeCheck() of tyArray: a = reduceToBase(a) - case a.kind - of tyArray: + if a.kind == tyArray: var fRange = f[0] var aRange = a[0] if fRange.kind in {tyGenericParam, tyAnything}: var prev = PType(idTableGet(c.bindings, fRange)) if prev == nil: + if typeRel(c, fRange, aRange) == isNone: + return isNone put(c, fRange, a[0]) fRange = a else: @@ -1302,7 +1303,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = isGeneric else: result = typeRel(c, ff, aa, flags) - if result < isGeneric: if nimEnableCovariance and trNoCovariance notin flags and @@ -1321,7 +1321,6 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, else: if lengthOrd(c.c.config, fRange) != lengthOrd(c.c.config, aRange): result = isNone - else: discard of tyUncheckedArray: if a.kind == tyUncheckedArray: result = typeRel(c, base(f), base(a), flags) diff --git a/compiler/types.nim b/compiler/types.nim index b5b6d9c501c5..1c820d978cf7 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -117,7 +117,7 @@ proc isPureObject*(typ: PType): bool = proc isUnsigned*(t: PType): bool = t.skipTypes(abstractInst).kind in {tyChar, tyUInt..tyUInt64} -proc getOrdValue*(n: PNode; onError = high(Int128)): Int128 = +proc getOrdValueAux*(n: PNode, err: var bool): Int128 = var k = n.kind if n.typ != nil and n.typ.skipTypes(abstractInst).kind in {tyChar, tyUInt..tyUInt64}: k = nkUIntLit @@ -133,13 +133,22 @@ proc getOrdValue*(n: PNode; onError = high(Int128)): Int128 = toInt128(n.intVal) of nkNilLit: int128.Zero - of nkHiddenStdConv: getOrdValue(n[1], onError) + of nkHiddenStdConv: + getOrdValueAux(n[1], err) else: - # XXX: The idea behind the introduction of int128 was to finally - # have all calculations numerically far away from any - # overflows. This command just introduces such overflows and - # should therefore really be revisited. - onError + err = true + int128.Zero + +proc getOrdValue*(n: PNode): Int128 = + var err: bool = false + result = getOrdValueAux(n, err) + #assert err == false + +proc getOrdValue*(n: PNode, onError: Int128): Int128 = + var err = false + result = getOrdValueAux(n, err) + if err: + result = onError proc getFloatValue*(n: PNode): BiggestFloat = case n.kind diff --git a/tests/overload/t23755.nim b/tests/overload/t23755.nim new file mode 100644 index 000000000000..3d06cee658f6 --- /dev/null +++ b/tests/overload/t23755.nim @@ -0,0 +1,52 @@ +type + BigInt[bits: static int] = object + limbs: array[8, uint64] + +block: + proc view[N](a: array[N, uint64]) = + discard + + proc view[N](a: var array[N, uint64]) = + discard + + var r: BigInt[64] + r.limbs.view() + + +type Limbs[N: static int] = array[N, uint64] + +block: + proc view(a: Limbs) = + discard + + proc view(a: var Limbs) = + discard + + var r: BigInt[64] + r.limbs.view() + + +block: + type IntArray[N: static[int]] = array[N, int] + + proc p[T](a: IntArray[T]): bool= true + proc p(a: IntArray[5]): bool= false + + var s: IntArray[5] + doAssert s.p == false + +block: + type IntArray[N: static[int]] = array[N, int] + + proc `$`(a: IntArray): string = + return "test" + + var s: IntArray[5] = [1,1,1,1,1] + doAssert `$`(s) == "test" + +block: + proc p[n:static[int]](a: array[n, char]):bool=true + proc p[T, IDX](a: array[IDX, T]):bool=false + + var g: array[32, char] + doAssert p(g)