diff options
author | Araq <rumpf_a@web.de> | 2018-10-11 19:52:48 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2018-10-11 19:52:48 +0200 |
commit | d48e964950d92a57c24770d40ef0f05ddfe51b7e (patch) | |
tree | d10d0036ca1ccca319da0cf0bd6028af2b2a6e49 | |
parent | 8ab6fa1be255e91f4a455f5e4a97aff07c12d84c (diff) | |
download | Nim-d48e964950d92a57c24770d40ef0f05ddfe51b7e.tar.gz |
fixes #9281
-rw-r--r-- | compiler/ccgexprs.nim | 18 | ||||
-rw-r--r-- | compiler/reorder.nim | 2 | ||||
-rw-r--r-- | tests/system/tsystem_misc.nim | 15 |
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 |