summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/sigmatch.nim9
-rw-r--r--lib/system.nim9
-rw-r--r--tests/array/tarrindx.nim14
4 files changed, 33 insertions, 3 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 5ff692fd5..04e76102b 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1391,8 +1391,8 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
     n.sons[1] = semConstExpr(c, n.sons[1])
     if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias, tySink}).kind in
         {tyInt..tyInt64}:
-      var idx = getOrdValue(n.sons[1])
-      if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)]
+      let idx = getOrdValue(n.sons[1])
+      if idx >= 0 and idx < len(arr): n.typ = arr.sons[int(idx)]
       else: localError(c.config, n.info, "invalid index value for tuple subscript")
       result = n
     else:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index c53c73074..0cd55068c 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -2132,6 +2132,10 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
       styleCheckUse(arg.info, arg.sons[best].sym)
       result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
                                   argOrig)
+  when false:
+    if m.calleeSym != nil and m.calleeSym.name.s == "[]":
+      echo m.c.config $ arg.info, " for ", m.calleeSym.name.s, " ", m.c.config $ m.calleeSym.info
+      writeMatches(m)
 
 proc setSon(father: PNode, at: int, son: PNode) =
   let oldLen = father.len
@@ -2380,6 +2384,11 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
   if m.magic in {mArrGet, mArrPut}:
     m.state = csMatch
     m.call = n
+    # Note the following doesn't work as it would produce ambiguities.
+    # Instead we patch system.nim, see bug #8049.
+    when false:
+      inc m.genericMatches
+      inc m.exactMatches
     return
   var marker = initIntSet()
   matchesAux(c, n, nOrig, m, marker)
diff --git a/lib/system.nim b/lib/system.nim
index 2c88fe60f..92f51fe7e 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -313,6 +313,12 @@ when defined(nimArrIdx):
   proc `[]=`*[I: Ordinal;T,S](a: T; i: I;
     x: S) {.noSideEffect, magic: "ArrPut".}
   proc `=`*[T](dest: var T; src: T) {.noSideEffect, magic: "Asgn".}
+
+  proc arrGet[I: Ordinal;T](a: T; i: I): T {.
+    noSideEffect, magic: "ArrGet".}
+  proc arrPut[I: Ordinal;T,S](a: T; i: I;
+    x: S) {.noSideEffect, magic: "ArrPut".}
+
   when defined(nimNewRuntime):
     proc `=destroy`*[T](x: var T) {.inline, magic: "Asgn".} =
       ## generic `destructor`:idx: implementation that can be overriden.
@@ -3526,6 +3532,9 @@ template spliceImpl(s, a, L, b: untyped): untyped =
 template `^^`(s, i: untyped): untyped =
   (when i is BackwardsIndex: s.len - int(i) else: int(i))
 
+template `[]`*(s: string; i: int): char = arrGet(s, i)
+template `[]=`*(s: string; i: int; val: char) = arrPut(s, i, val)
+
 when hasAlloc or defined(nimscript):
   proc `[]`*[T, U](s: string, x: HSlice[T, U]): string {.inline.} =
     ## slice operation for strings.
diff --git a/tests/array/tarrindx.nim b/tests/array/tarrindx.nim
index 3bb6b0148..9e8ec31b6 100644
--- a/tests/array/tarrindx.nim
+++ b/tests/array/tarrindx.nim
@@ -1,6 +1,8 @@
 discard """
   output: '''0
-0'''
+0
+bc
+bcdefg'''
 """
 
 # test another strange bug ... (I hate this compiler; it is much too buggy!)
@@ -29,3 +31,13 @@ var
 
 echo obj.s1[0]
 echo obj.s1[0u]
+
+
+# bug #8049
+
+when true:
+  type ustring* = distinct string
+  converter toUString*(s: string): ustring = ustring(s)
+  proc `[]`*(s: ustring, i: int): ustring = s
+  echo "abcdefgh"[1..2]
+  echo "abcdefgh"[1..^2]