m2ym / optima

Optimized Pattern Matching Library for Common Lisp
271 stars 19 forks source link

SBCL 1.2.4 compile error with code using optima #100

Closed antonvesnin closed 10 years ago

antonvesnin commented 10 years ago

SBCL version 1.2.4

Compiling file with this code will fail without declaring signal-error notinline.

(defun signal-error ()
  (error 'error))

(defun will-fail ()
  (optima:match 1
    ((not 2)
     (signal-error))))

Error report:

; compiling (DEFUN SIGNAL-ERROR ...)
; compiling (DEFUN WILL-FAIL ...)
; file: /home/freeman/err.lisp
; in: DEFUN WILL-FAIL
; (OPTIMA:MATCH 1
; ((NOT 2) (COMMON-LISP::SIGNAL-ERROR)))
; --> LET OPTIMA::%OR BLOCK SB-C::%COMPILE-TIME-TYPE-ERROR
; ==>
; '((BLOCK #:BLOCK2
; (TAGBODY
; (RETURN-FROM #:BLOCK2
; (SYMBOL-MACROLET #
; #))
; #:FAIL3
; (RETURN-FROM #:BLOCK2 NIL)))
; (COMMON-LISP::SIGNAL-ERROR))
;
; caught ERROR:
; don't know how to dump 2 (default MAKE-LOAD-FORM method called).

; --> LET OPTIMA::%OR BLOCK
; ==>
; (SB-C::%COMPILE-TIME-TYPE-ERROR 'SB-C::DUMMY 'NIL '*
; '((BLOCK #:BLOCK2
; (TAGBODY
; (RETURN-FROM #:BLOCK2 #)
; #:FAIL3
; (RETURN-FROM #:BLOCK2 NIL)))
; (COMMON-LISP::SIGNAL-ERROR)))
;
; note: The fourth argument never returns a value.
Unhandled TYPE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
                                  {1002BF7023}>:
  The value NIL is not of type (AND ATOM (NOT NULL)).

After declaring singnal-error as notinline or changing ERROR to SIGNAL it'll compile ok.

UPDATE: Looks more like SBCL issue, close it pleace.

antonvesnin commented 10 years ago

By the way, here is answer in SBCL bugtracker, may be it'll be useful for for you, showing how to avoid such behavior in SBCL:

This is partially the fault of optima and partially the failure of the compiler to stop processing when things go wrong when attempting to dump a constant object.

The root cause is: caught ERROR: ; don't know how to dump 2 (default MAKE-LOAD-FORM method called). This "2" is not the literal 2, but an OPTIMA.CORE:CONSTANT-PATTERN

If you put this in either your source code or the Optima source code, it fixes the problem:

(eval-when (:compile-toplevel)
 (defmethod make-load-form ((self constant-pattern) &optional env)
            (declare (ignore env))
            (make-load-form-saving-slots self)))

As to why declaring the error signaling inline "fixes" the problem, it's because on account of the compiler knowing that ERROR does not return, there becomes some unreachable code, and that is the very same code which couldn't be dumped properly.

Link to report: https://bugs.launchpad.net/sbcl/+bug/1378476

m2ym commented 10 years ago

I don't understand very well why make-load-form is called since SBCL 1.2.4. The constant pattern 2 shoould be disappeared after macroexpand. Am I missing some points?

antonvesnin commented 10 years ago

Me neither, for now I'm declaring this function not to be inlined and it works for me. Just forwarded to you SBCL response, in case it'll be useful. For example with CCL it works ok without declaration or eval-when.

m2ym commented 10 years ago

Okay, thanks.