summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRyan McConnell <rammcconnell@gmail.com>2024-07-01 08:39:16 -0400
committerGitHub <noreply@github.com>2024-07-01 14:39:16 +0200
commit27abcdd57f43fa905153f38afc7b10b990d789c9 (patch)
tree7e32e34236494a0ad3fd09eb93df16da646f4b4e
parentd78ccbc27cf0acc524279660611ccc57e7d2062a (diff)
downloadNim-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.nim7
-rw-r--r--compiler/types.nim23
-rw-r--r--tests/overload/t23755.nim52
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)