racket / ChezScheme

Chez Scheme
Apache License 2.0
110 stars 8 forks source link

Strange behavior of exported condition types and predicates #35

Closed lemvik closed 3 years ago

lemvik commented 3 years ago

Hi!

There seems to be a regression in the Racket fork of Chez Scheme related to define-condition-type and library export forms.

Minimal example

conditions-evaluation.scm:

(library (exporting-conditions)
  (export base-condition?

          &second-derived-condition

          make-first-derived
          make-second-derived)
  (import (rnrs))

  (define-condition-type &base-condition &condition make-base-condition base-condition?)

  (define-condition-type &first-derived-condition &base-condition make-first-derived first-derived?)

  (define-condition-type &second-derived-condition &base-condition make-second-derived second-derived?))

(import (chezscheme)
        (exporting-conditions))

(define (generate-conditions)
  (list (condition (make-first-derived) (make-message-condition "first"))
        (condition (make-second-derived) (make-message-condition "second"))))

(define (check-conditions list-of-conditions)
  (format #t "~&(for-all base-condition? ...): ~a~%"
          (for-all base-condition? list-of-conditions))
  (for-each (lambda (c index)
              (format #t "~&~a condition: ~a~%" index (base-condition? c)))
            list-of-conditions
            (iota (length list-of-conditions))))

(check-conditions (generate-conditions))

(exit)

In base Chez branch:

> scheme conditions-evaluation.scm
Chez Scheme Version 9.5.5
Copyright 1984-2020 Cisco Systems, Inc.

(for-all base-condition? ...): #t
0 condition: #t
1 condition: #t

in Racket branch:

> scheme conditions-evaluation.scm
Chez Scheme Version 9.5.5.3
Copyright 1984-2020 Cisco Systems, Inc.

(for-all base-condition? ...): #t
0 condition: #f
1 condition: #t

So strangely for-all returns true but when conditions are checked individually some of them fail the check.

Surprisingly the problem disappears if I remove the export of &second-derived-condition or if I add the export of &base-condition.

lemvik commented 3 years ago

Sorry, forgot to mention build details:

  1. Threaded Racket Chez built from this commit
  2. Threaded Base Chez build from this commit
  3. OS: Linux 5.8.0-40-generic #45-Ubuntu SMP Fri Jan 15 11:05:36 UTC 2021 x86_64
mflatt commented 3 years ago

Thanks for the report! I'm able to replicate the problem, and I'll continue to investigate.

mflatt commented 3 years ago

The problem is in a change to cross-library inlining that I added to cp0. Here's a somewhat simpler example:

(library (test)
  (export a b am bm)
  (import (rnrs))
  (define-syntax def
    (syntax-rules ()
      [(_ id idm)
       (begin
         (define (helper x) (if (zero? x) 'id (helper (- x 1))))
         (define (id x) (helper x))
         ;; causes `helper` to be preserved:
         (define-syntax idm (syntax-rules () [(_) helper])))]))
  (def a am)
  (def b bm))

(import (test))

(a 10)
(b 10)

In the optimization of (a 10), an inlined reference to helper ends up referring to the wrong helper, because identifier names are not compared the right way when inlining.