diff options
author | Ryan McConnell <rammcconnell@gmail.com> | 2024-07-01 08:39:16 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-01 14:39:16 +0200 |
commit | 27abcdd57f43fa905153f38afc7b10b990d789c9 (patch) | |
tree | 7e32e34236494a0ad3fd09eb93df16da646f4b4e | |
parent | d78ccbc27cf0acc524279660611ccc57e7d2062a (diff) | |
download | Nim-27abcdd57f43fa905153f38afc7b10b990d789c9.tar.gz |
fixes #23755; array static inference during overload resolution (#23760)
#23755 --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
-rw-r--r-- | compiler/sigmatch.nim | 7 | ||||
-rw-r--r-- | compiler/types.nim | 23 | ||||
-rw-r--r-- | tests/overload/t23755.nim | 52 |
3 files changed, 71 insertions, 11 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 64d5df788..9595ac62b 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1260,13 +1260,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.indexType var aRange = a.indexType if fRange.kind in {tyGenericParam, tyAnything}: var prev = idTableGet(c.bindings, fRange) if prev == nil: + if typeRel(c, fRange, aRange) == isNone: + return isNone put(c, fRange, a.indexType) fRange = a else: @@ -1279,7 +1280,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 @@ -1298,7 +1298,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, elementType(f), elementType(a), flags) diff --git a/compiler/types.nim b/compiler/types.nim index 880f811dd..dbdaab670 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -115,7 +115,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 @@ -131,13 +131,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 000000000..3d06cee65 --- /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) |