~ chicken-core (chicken-5) f335156a069b4be8c3ec90c1c3f5bddb076f2759


commit f335156a069b4be8c3ec90c1c3f5bddb076f2759
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Thu Dec 15 08:19:38 2011 +0100
Commit:     Peter Bex <peter.bex@xs4all.nl>
CommitDate: Sun Dec 18 16:10:32 2011 +0100

    scrutiny: add special cases for result types of list-ref/list-tail
    
    Signed-off-by: Peter Bex <peter.bex@xs4all.nl>

diff --git a/scrutinizer.scm b/scrutinizer.scm
index 2f8ed8f0..a3e2ad4e 100755
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -2147,6 +2147,42 @@
   (define-special-case vector-ref vector-ref-result-type)
   (define-special-case ##sys#vector-ref vector-ref-result-type))
 
+(let ()
+  (define (list-ref-result-type node args rtypes)
+    (or (let ((subs (node-subexpressions node))
+	      (arg1 (second args)))
+	  (and (pair? arg1)
+	       (eq? 'list (car arg1))
+	       (= (length subs) 3)
+	       (let ((index (third subs)))
+		 (and (eq? 'quote (node-class index))
+		      (let ((val (first (node-parameters index))))
+			(and (fixnum? val)
+			     (>= val 0) (< val (length (cdr arg1))) ;XXX could warn on failure (but needs location)
+			     (list (list-ref (cdr arg1) val))))))))
+	rtypes))
+  (define-special-case list-ref list-ref-result-type)
+  (define-special-case ##sys#list-ref list-ref-result-type))
+
+(define-special-case list-tail
+  (lambda (node args rtypes)
+    (or (let ((subs (node-subexpressions node))
+	      (arg1 (second args)))
+	  (and (pair? arg1)
+	       (eq? 'list (car arg1))
+	       (= (length subs) 3)
+	       (let ((index (third subs)))
+		 (and (eq? 'quote (node-class index))
+		      (let ((val (first (node-parameters index))))
+			(and (fixnum? val)
+			     (>= val 0) (< val (length (cdr arg1))) ;XXX could warn on failure (but needs location)
+			     (let ((rest (list-tail (cdr arg1) val)))
+			       (list
+				(if (null? rest)
+				    'null
+				    `(list ,@rest))))))))))
+	rtypes)))
+
 (define-special-case list
   (lambda (node args rtypes)
     (if (null? (cdr args))
diff --git a/types.db b/types.db
index 5d8c746f..9f97c469 100644
--- a/types.db
+++ b/types.db
@@ -163,6 +163,7 @@
 	      ((null) '0)
 	      ((list) (##core#inline "C_u_i_length" #(1))))
 
+;; these are special cased (see scrutinizer.scm)
 (list-tail (forall (a) (#(procedure #:clean #:enforce) list-tail ((list-of a) fixnum) (list-of a))))
 (list-ref (forall (a) (#(procedure #:clean #:enforce) list-ref ((list-of a) fixnum) a)))
 
Trap