cisco/ChezScheme

Non-tail calls to errorf sometimes treated as tail calls with debug-level 2

burgerrg opened this issue ยท 5 comments

(debug-level 2) is supposed to preserve non-tail calls to error functions like errorf. In Chez Scheme 10.0.0, the following code produces a tail call to errorf:

(define (boom)
  (errorf 'boom "non tail")
  (pretty-print "boom!"))

It appears that cp0 is eliminating the call to pretty-print:

(debug-level 2)
(expand/optimize '(define (boom) (errorf 'boom "non tail") (pretty-print "boom!")))
(begin
  (set! boom (lambda () (#2%errorf 'boom "non tail")))
  (#2%void))

Setting (enable-type-recovery #f) preserves the non-tail call in this case.

Possibly, the solution is to guard various (predicate-implies? ret 'bottom) tests in cptypes.ss with a check that debug-level is less than 2, but I'm far from certain that will be sufficient in general. I had not previously noted this intent of debug-level!

Or maybe the problem is that unwrapped-error in cptype.ss isn't doing its job to keep things in non-tail position.

On further reflection, although I had not noticed the specification of debug-level, my intent in general has been to disallow optimizations that move calls into tail position, since continuation marks expose that difference. So, I'm inclined to say that this is a bug independent of debug-level.

After investigating and refreshing my memory on 6a73b9e, I see how the (debug-level 2) constraint is stronger than the one that the optimizer currently follows. So, I am back to thinking that the needed repair is specific to debug-level >= 2.

Specifically, the cp0/cptypes pass will lift an error-raising expression out of a nested position if determines that no continuation-mark operations will detect that change. (Although raising an exception will eventually call a handler that might use continuation-mark operations, the call to the handler is not in tail position with respect to the exception-raising function.) But (debug-level 2) is about detecting frames even without continuation-mark operations.

Candidate repair: #834

Since #834 was merged, should this be closed?