Detect trivial infinite recursion in promises.
authorTaylor R Campbell <campbell@mumble.net>
Thu, 3 Jan 2019 16:35:11 +0000 (16:35 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Fri, 4 Jan 2019 07:08:15 +0000 (07:08 +0000)
Obviously this can be fooled, like

(force (let loop () (delay-force (loop))))

or any non-halting Turing machine, but this is an easy case to detect
with negligible cost.

src/runtime/boot.scm
tests/runtime/test-promise.scm

index 68e62a00ea2bec51b92e0db1e6115f136cccd226..ea7e651b9153a06c4fbda18c968339a0cba3ffa1 100644 (file)
@@ -470,6 +470,8 @@ USA.
        value
        (let ((promise* (value)))
          (guarantee promise? promise* 'force)
+         (if (eq? promise* promise)
+             (error "Infinite recursion in promise:" promise))
          (without-interrupts
           (lambda ()
             (let ((q (cell-contents promise)))
index c8af319e7503451c5029c582bb6cc1d3bb353a54..6291d8b2016fb8da2b450fb1a08f7aa9884e4b1a 100644 (file)
@@ -71,15 +71,13 @@ USA.
 
 (define-test 'delay-force-loop
   (lambda ()
-    (expect-failure
+    (assert-error
      (lambda ()
-       (assert-error
-        (lambda ()
-          (carefully (lambda ()
-                       (define p (delay-force p))
-                       (force p))
-                     (lambda () 'stack-overflow)
-                     (lambda () 'timeout))))))))
+       (carefully (lambda ()
+                    (define p (delay-force p))
+                    (force p))
+                  (lambda () 'stack-overflow)
+                  (lambda () 'timeout))))))
 
 (define-test 'force-force-delay-delay
   (lambda ()