~ chicken-core (chicken-5) dc55c85015b0fa961537a6aa8c21bad7b09e4167
commit dc55c85015b0fa961537a6aa8c21bad7b09e4167
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Wed Jul 13 22:27:20 2016 +0200
Commit: Evan Hanson <evhan@foldling.org>
CommitDate: Sun Jul 24 11:50:39 2016 +1200
Keep vector length when smashing component types.
We just convert the slot types to '*, so we still know the length of the
vector.
Signed-off-by: Evan Hanson <evhan@foldling.org>
diff --git a/NEWS b/NEWS
index 223b4917..f22ca62a 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@
- Warnings are now emitted when using vector-{ref,set!} or one
of take, drop, list-ref or list-tail with an out of range index
for vectors and lists of a definitely known length.
+ - The scrutinizer will no longer drop knowledge of the length of a
+ vector. It still drops types of its contents (which may be mutated).
- Runtime system:
- C_locative_ref has been deprecated in favor of C_a_i_locative_ref,
diff --git a/scrutinizer.scm b/scrutinizer.scm
index 79241c44..0451af8c 100644
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -907,11 +907,16 @@
(dd " smashing `~s' in ~a" (caar lst) where)
(change! 'vector)
(car t))
+ ((vector)
+ (dd " smashing `~s' in ~a" (caar lst) where)
+ ;; (vector x y z) => (vector * * *)
+ (change! (cons 'vector (map (constantly '*) (cdr t))))
+ (car t))
((list-of list)
(dd " smashing `~s' in ~a" (caar lst) where)
(change! '(or pair null))
(car t))
- ((pair vector)
+ ((pair)
(dd " smashing `~s' in ~a" (caar lst) where)
(change! (car t))
(car t))
diff --git a/tests/scrutiny-tests.scm b/tests/scrutiny-tests.scm
index fbd82d2c..70582119 100644
--- a/tests/scrutiny-tests.scm
+++ b/tests/scrutiny-tests.scm
@@ -210,41 +210,24 @@
;; Indexing into vectors or lists of known size.
-;;
-;; TODO: The specific vector or list type will be smashed to just
-;; "vector" or "(or pair null)" after the first operation. This is
-;; why the let is repeated; otherwise we won't get the warnings for
-;; subsequent references. For vectors this is overly pessimistic.
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-ref-warn1) (vector-ref v1 -1)))
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-ref-warn2) (vector-ref v1 3)))
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-ref-warn3) (vector-ref v1 4)))
-
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-ref-nowarn1) (vector-ref v1 0)))
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-ref-nowarn2) (vector-ref v1 2)))
-
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-ref-standard-warn1) (vector-ref v1 'bad)))
-
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-set!-warn1) (vector-set! v1 -1 'whatever)))
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-set!-warn2) (vector-set! v1 3 'whatever)))
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-set!-warn3) (vector-set! v1 4 'whatever)))
-
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-set!-nowarn1) (vector-set! v1 0 'whatever)))
-(let ((v1 (vector 'a 'b 'c)))
- (define (vector-set!-nowarn2) (vector-set! v1 2 'whatever)))
-
(let ((v1 (vector 'a 'b 'c)))
+ (define (vector-ref-warn1) (vector-ref v1 -1))
+ ;; After the first expression, v1's type is smashed to (vector * * *)!
+ (define (vector-ref-warn2) (vector-ref v1 3))
+ (define (vector-ref-warn3) (vector-ref v1 4))
+ (define (vector-ref-nowarn1) (vector-ref v1 0))
+ (define (vector-ref-nowarn2) (vector-ref v1 2))
+ (define (vector-ref-standard-warn1) (vector-ref v1 'bad))
+ (define (vector-set!-warn1) (vector-set! v1 -1 'whatever))
+ (define (vector-set!-warn2) (vector-set! v1 3 'whatever))
+ (define (vector-set!-warn3) (vector-set! v1 4 'whatever))
+ (define (vector-set!-nowarn1) (vector-set! v1 0 'whatever))
+ (define (vector-set!-nowarn2) (vector-set! v1 2 'whatever))
(define (vector-set!-standard-warn1) (vector-set! v1 'bad 'whatever)))
+;; The specific list type will be smashed to just "(or pair null)"
+;; after the first operation. This is why the let is repeated;
+;; otherwise we won't get the warnings for subsequent references.
(let ((l1 (list 'a 'b 'c)))
(define (list-ref-warn1) (list-ref l1 -1)))
(let ((l2 (cons 'a (cons 'b (cons 'c (eval '(list)))))))
Trap