~ chicken-core (chicken-5) fce5c764a8dea2084cc7862f9609ac57349bd1f9
commit fce5c764a8dea2084cc7862f9609ac57349bd1f9 Author: Evan Hanson <evhan@foldling.org> AuthorDate: Sun Aug 17 18:36:21 2014 +1200 Commit: Peter Bex <peter.bex@xs4all.nl> CommitDate: Sun Oct 19 14:22:50 2014 +0200 Add scrutiny special cases for make-list/make-vector with known sizes Signed-off-by: Peter Bex <peter.bex@xs4all.nl> diff --git a/scrutinizer.scm b/scrutinizer.scm index 25abc949..f240c1f2 100644 --- a/scrutinizer.scm +++ b/scrutinizer.scm @@ -109,6 +109,7 @@ (define-constant +fragment-max-length+ 6) (define-constant +fragment-max-depth+ 4) (define-constant +maximal-union-type-length+ 20) +(define-constant +maximal-complex-object-constructor-result-type-length+ 256) (define specialization-statistics '()) @@ -2265,6 +2266,34 @@ `((vector ,@(map walked-result (cdr args)))))) +;;; Special cases for make-list/make-vector with a known size +; +; e.g. (make-list 3 #\a) => (list char char char) + +(let () + + (define (complex-object-constructor-result-type-special-case type) + (lambda (node args rtypes) + (or (and-let* ((subs (node-subexpressions node)) + (fill (case (length subs) + ((2) '*) + ((3) (walked-result (third args))) + (else #f))) + (sub2 (second subs)) + ((eq? 'quote (node-class sub2))) + (size (first (node-parameters sub2))) + ((fixnum? size)) + ((<= 0 size +maximal-complex-object-constructor-result-type-length+))) + `((,type ,@(make-list size fill)))) + rtypes))) + + (define-special-case make-list + (complex-object-constructor-result-type-special-case 'list)) + + (define-special-case make-vector + (complex-object-constructor-result-type-special-case 'vector))) + + ;;; perform check over all typevar instantiations (define (over-all-instantiations tlist typeenv exact process) @@ -2308,7 +2337,8 @@ (ddd " over-all-instantiations: ~s exact=~a" tlist exact) ;; process all tlist elements - (let loop ((ts tlist) (ok #f)) + (let loop ((ts (delete-duplicates tlist equal?)) + (ok #f)) (cond ((null? ts) (cond ((or ok (null? tlist)) (for-each diff --git a/tests/typematch-tests.scm b/tests/typematch-tests.scm index 40515957..4374337b 100644 --- a/tests/typematch-tests.scm +++ b/tests/typematch-tests.scm @@ -286,6 +286,10 @@ (mx (list fixnum) (take (list 1 2.3) 1)) (mx (list fixnum) (take (cons 1 2.3) 1)) (mx (list fixnum float) (take (list 1 2.3) 2)) +(mx (list * *) (make-list 2)) +(mx (list string string) (make-list 2 "a")) +(mx (vector * *) (make-vector 2)) +(mx (vector string string) (make-vector 2 "a")) (: f1 (forall (a) ((list-of a) -> a))) (define (f1 x) (car x)) diff --git a/types.db b/types.db index 7de61288..964e1774 100644 --- a/types.db +++ b/types.db @@ -561,6 +561,7 @@ (vector? (#(procedure #:pure #:predicate vector) vector? (*) boolean)) +;; special-cased (see scrutinizer.scm) (make-vector (forall (a) (#(procedure #:clean #:enforce) make-vector (fixnum #!optional a) (vector-of a)))) @@ -1956,6 +1957,7 @@ ((procedure) (let ((#(tmp) #(1))) '#t)) ((procedure list) (let ((#(tmp1) #(1)) (#(tmp2) #(2))) '#t))) +;; special-cased (see scrutinizer.scm) (make-list (forall (a) (#(procedure #:clean #:enforce) make-list (fixnum #!optional a) (list-of a)))) (map!Trap