Skip to content
Permalink
Browse files

Fix off-by-one error in infinite range subscript

Subscripting with an infinite range was inconsistent between `0 ..^ Inf`
and `0 ..^ *`. This commit makes both behave like the former:

  (^3)[0 ..  Inf] eqv (0,1,2)
  (^3)[0 ..^ Inf] eqv (0,1,2)  # Inf-1 is Inf
  (^3)[0 ..  *]   eqv (0,1,2)
  (^3)[0 ..^ *]   eqv (0,1,2)  # used to be (0,1)

The difference came from an nqp::eqaddr(pos.max, Inf) condition which
the `0 .. Inf` range did *not* pass but the `0 .. *` one did. Result
of that condition was treating the range as if it had upper endpoint
`.elems - 1` which seems off-by-one. Notice that there is no behavior
specified for this in roast.

Setting it to `.elems` instead makes it at least consistent with
WhateverCode passed to the subscript:

  (^3)[0 ..^ *].tail == (^3)[*-1]  # True with this commit

Closes #2872
  • Loading branch information...
taboege committed May 3, 2019
1 parent c5bc71e commit 35b69f074b9db3ffeb1638fc8a548fc2c0643d5a
Showing with 2 additions and 2 deletions.
  1. +2 −2 src/core/array_slice.pm6
@@ -57,9 +57,9 @@ multi sub POSITIONS(
# we can optimize `42..*` Ranges; as long as they're from core, unmodified
my \is-pos-lazy = pos.is-lazy;
my \pos-iter = nqp::eqaddr(pos.WHAT,Range)
&& nqp::eqaddr(pos.max,Inf)
&& pos.max === Inf
&& nqp::isfalse(SELF.is-lazy)
?? Range.new(pos.min, SELF.elems-1,
?? Range.new(pos.min, SELF.elems,
:excludes-min(pos.excludes-min),
:excludes-max(pos.excludes-max)
).iterator

0 comments on commit 35b69f0

Please sign in to comment.
You can’t perform that action at this time.