~ chicken-core (chicken-5) cf5f48407668414995d908177f797002e3389e19


commit cf5f48407668414995d908177f797002e3389e19
Author:     megane <meganeka@gmail.com>
AuthorDate: Mon May 14 21:59:05 2018 +1200
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Tue May 15 10:32:38 2018 +0200

    Fix error during compiler-typecase trail restore
    
    This fixes an error that can occur when a typecase clause fails to match
    and the subsequent trail restoration fails due to an incorrect
    environment being passed to `trail-restore'. This argument should be the
    one used for matching, not the original environment containing just the
    source expression's types.
    
    Signed-off-by: Evan Hanson <evhan@foldling.org>
    Signed-off-by: felix <felix@call-with-current-continuation.org>

diff --git a/scrutinizer.scm b/scrutinizer.scm
index 4869cc6b..ece07ed3 100644
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -850,27 +850,26 @@
 		 ((##core#typecase)
 		  (let* ((ts (walk (first subs) e loc #f #f flow ctags))
 			 (trail0 trail)
-			 (typeenv (type-typeenv (car ts))))
+			 (typeenv0 (type-typeenv (car ts))))
 		    ;; first exp is always a variable so ts must be of length 1
 		    (let loop ((types (cdr params)) (subs (cdr subs)))
-		      (cond ((null? types)
-			     (quit-compiling
-			      "~a~ano clause applies in `compiler-typecase' for expression of type `~a':~a"
-			      (location-name loc)
-			      (node-source-prefix n)
-			      (type-name (car ts))
-			      (string-intersperse
-			       (map (lambda (t) (sprintf "\n    ~a" (type-name t)))
-				    (cdr params)) "")))
-			    ((match-types (car types) (car ts) 
-					  (append (type-typeenv (car types)) typeenv)
-					  #t)
-			     ;; drops exp
-			     (mutate-node! n (car subs))
-			     (walk n e loc dest tail flow ctags))
-			    (else
-			     (trail-restore trail0 typeenv)
-			     (loop (cdr types) (cdr subs)))))))
+		      (if (null? types)
+			  (quit-compiling
+			   "~a~ano clause applies in `compiler-typecase' for expression of type `~a':~a"
+			   (location-name loc)
+			   (node-source-prefix n)
+			   (type-name (car ts))
+			   (string-intersperse
+			    (map (lambda (t) (sprintf "\n    ~a" (type-name t)))
+				 (cdr params)) ""))
+			  (let ((typeenv (append (type-typeenv (car types)) typeenv0)))
+			    (if (match-types (car types) (car ts) typeenv #t)
+				(begin ; drops exp
+				  (mutate-node! n (car subs))
+				  (walk n e loc dest tail flow ctags))
+				(begin
+				  (trail-restore trail0 typeenv)
+				  (loop (cdr types) (cdr subs)))))))))
 		 ((##core#switch ##core#cond)
 		  (bomb "scrutinize: unexpected node class" class))
 		 (else
diff --git a/tests/scrutiny-tests.scm b/tests/scrutiny-tests.scm
index ef4e0d96..96757b7e 100644
--- a/tests/scrutiny-tests.scm
+++ b/tests/scrutiny-tests.scm
@@ -311,3 +311,8 @@
   (define (append-result-type-nowarn2) (add1 (list-ref l2 1))))
 (let ((l3 (append (the (list-of fixnum) '(1 2)) '(x y))))
   (define (append-result-type-nowarn3) (add1 (list-ref l3 1))))
+
+;; Check the trail is restored from the combined typeenv
+(compiler-typecase (list 2 'a)
+  ((forall (x) (list x x)) 1)
+  (else #t))
Trap