fix in-vector segfault; document corner cases

closes #15227
This commit is contained in:
Stephen Chang 2016-01-19 16:37:07 -05:00
parent 0f39ee9b72
commit fa96375742
3 changed files with 43 additions and 7 deletions

View File

@ -232,9 +232,21 @@ each element in the sequence.
greater or equal to @racket[end] if @racket[step] is non-negative,
or less or equal to @racket[end] if @racket[step] is negative.
If @racket[start] is not a valid index, or @racket[stop] is not in
[-1, @racket[(vector-length vec)]] then the
@exnraise[exn:fail:contract]. If @racket[start] is less than
If @racket[start] is not a valid index, then the
@exnraise[exn:fail:contract], except when @racket[start], @racket[stop], and
@racket[(vector-length vec)] are equal, in which case the result is an
empty sequence.
@examples[#:eval sequence-evaluator
(for ([x (in-vector (vector 1) 1)]) x)
(eval:error (for ([x (in-vector (vector 1) 2)]) x))
(for ([x (in-vector (vector) 0 0)]) x)
(for ([x (in-vector (vector 1) 1 1)]) x)]
If @racket[stop] is not in [-1, @racket[(vector-length vec)]],
then the @exnraise[exn:fail:contract].
If @racket[start] is less than
@racket[stop] and @racket[step] is negative, then the
@exnraise[exn:fail:contract:mismatch]. Similarly, if @racket[start]
is more than @racket[stop] and @racket[step] is positive, then the

View File

@ -369,6 +369,7 @@
(test '() 'in-empty-vector (let ([v (in-vector '#())]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#() 0)]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#() 0 0)]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#(1) 1)]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#(1) 1 1)]) (for/list ([e v]) e)))
(test '() 'in-empty-vector (let ([v (in-vector '#(1) 0 0)]) (for/list ([e v]) e)))
(test '(1) 'in-empty-vector (let ([v (in-vector '#(1) 0 1)]) (for/list ([e v]) e)))
@ -523,6 +524,28 @@
exn:fail:contract:arity?
#rx"expected number of values not received")
(err/rt-test (for/sum ([x (in-vector (vector 1 2) 2 -1 -1)]) x) ; pr 15227
exn:fail:contract?
#rx"starting index is out of range")
(err/rt-test (for/sum ([x (in-vector (vector) -1 -1 -1)]) x)
exn:fail:contract?
#rx"starting index is out of range")
(err/rt-test (for/sum ([x (in-vector (vector) 1 1 1)]) x)
exn:fail:contract?
#rx"starting index is out of range")
(err/rt-test (for/sum ([x (in-vector (vector 1) 1 2)]) x)
exn:fail:contract?
#rx"starting index is out of range")
(err/rt-test (for/sum ([x (in-vector (vector 1) 0 2)]) x)
exn:fail:contract?
#rx"stopping index is out of range")
(err/rt-test (for/sum ([x (in-vector (vector 1) 0 -1)]) x)
exn:fail:contract?
#rx"starting index more than stopping index, but given a positive step")
(err/rt-test (for/sum ([x (in-vector (vector 1) 0 1 -1)]) x)
exn:fail:contract?
#rx"starting index less than stopping index, but given a negative step")
;; for/fold syntax checking
(syntax-test #'(for/fold () bad 1) #rx".*bad sequence binding clauses.*")

View File

@ -809,21 +809,22 @@
;; the largest fixnum, after running these checks start,
;; stop, and step are guaranteed to be fixnums.
(define (check-ranges who vec start stop step len)
(unless (and (exact-nonnegative-integer? start) (<= start len))
(raise-range-error who "vector" "starting " start vec 0 len))
(unless (and (exact-nonnegative-integer? start)
(or (< start len) (= len start stop)))
(raise-range-error who "vector" "starting " start vec 0 (sub1 len)))
(unless (and (exact-integer? stop) (<= -1 stop) (<= stop len))
(raise-range-error who "vector" "stopping " stop vec -1 len))
(unless (and (exact-integer? step) (not (zero? step)))
(raise-argument-error who "(and/c exact-integer? (not/c zero?))" step))
(when (and (< start stop) (< step 0))
(raise-arguments-error who
"starting index less then stopping index, but given a negative step"
"starting index less than stopping index, but given a negative step"
"starting index" start
"stopping index" stop
"step" step))
(when (and (< stop start) (> step 0))
(raise-arguments-error who
"starting index more then stopping index, but given a positive step"
"starting index more than stopping index, but given a positive step"
"starting index" start
"stopping index" stop
"step" step)))