summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim18
-rw-r--r--compiler/reorder.nim2
-rw-r--r--tests/system/tsystem_misc.nim15
3 files changed, 32 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 68cfa8b50..54e805a44 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1533,8 +1533,19 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   var typ = skipTypes(a.typ, abstractVar + tyUserTypeClasses)
   case typ.kind
   of tyOpenArray, tyVarargs:
-    if op == mHigh: unaryExpr(p, e, d, "($1Len_0-1)")
-    else: unaryExpr(p, e, d, "$1Len_0")
+    # Bug #9279, len(toOpenArray()) has to work:
+    if a.kind in nkCallKinds and a[0].kind == nkSym and a[0].sym.magic == mSlice:
+      # magic: pass slice to openArray:
+      var b, c: TLoc
+      initLocExpr(p, a[2], b)
+      initLocExpr(p, a[3], c)
+      if op == mHigh:
+        putIntoDest(p, d, e, ropecg(p.module, "($2)-($1)", [rdLoc(b), rdLoc(c)]))
+      else:
+        putIntoDest(p, d, e, ropecg(p.module, "($2)-($1)+1", [rdLoc(b), rdLoc(c)]))
+    else:
+      if op == mHigh: unaryExpr(p, e, d, "($1Len_0-1)")
+      else: unaryExpr(p, e, d, "$1Len_0")
   of tyCString:
     if op == mHigh: unaryExpr(p, e, d, "($1 ? (#nimCStrLen($1)-1) : -1)")
     else: unaryExpr(p, e, d, "($1 ? #nimCStrLen($1) : 0)")
@@ -2020,6 +2031,9 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mDotDot, mEqCString: genCall(p, e, d)
   of mWasMoved: genWasMoved(p, e)
   of mMove: genMove(p, e, d)
+  of mSlice:
+    localError(p.config, e.info, "invalid context for 'toOpenArray'; " &
+      " 'toOpenArray' is only valid within a call expression")
   else:
     when defined(debugMagics):
       echo p.prc.name.s, " ", p.prc.id, " ", p.prc.flags, " ", p.prc.ast[genericParamsPos].kind
diff --git a/compiler/reorder.nim b/compiler/reorder.nim
index 27b19a373..07462bb3e 100644
--- a/compiler/reorder.nim
+++ b/compiler/reorder.nim
@@ -238,7 +238,7 @@ proc mergeSections(conf: ConfigRef; comps: seq[seq[DepN]], res: PNode) =
               var sn = newNode(ckind)
               sn.add cs[i].pnode[0]
               inc i
-              while i < cs.len and cs[i].pnode.kind == ckind :
+              while i < cs.len and cs[i].pnode.kind == ckind:
                 sn.add cs[i].pnode[0]
                 inc i
               res.add sn
diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim
index ce36bc9ef..c8189b3b1 100644
--- a/tests/system/tsystem_misc.nim
+++ b/tests/system/tsystem_misc.nim
@@ -25,6 +25,7 @@ discard """
 55
 56
 57
+2
 '''
 """
 
@@ -102,3 +103,17 @@ proc foo(a: openArray[byte]) =
 
 let str = "0123456789"
 foo(toOpenArrayByte(str, 0, str.high))
+
+
+template boundedOpenArray[T](x: seq[T], first, last: int): openarray[T] =
+  toOpenarray(x, max(0, first), min(x.high, last))
+
+# bug #9281
+
+proc foo[T](x: openarray[T]) =
+  echo x.len
+
+let a = @[1, 2, 3]
+
+# a.boundedOpenArray(1, 2).foo()  # Works
+echo a.boundedOpenArray(1, 2).len # Internal compiler error