typescommon-lispsbcl

SBCL Note: type assertion too complex to check


Having trouble deciphering an SBCL compiler message:

; in: DEFUN PURIFY-FILE
;     (DEFUN DEPENDENCIES::PURIFY-FILE (DEPENDENCIES::FILE)
;       "Transforms problematic symbols to benign NIL in file, before reading.
;      Returns a string of altered file content."
;       (LET ((DEPENDENCIES::FILE-STRING
;              (ALEXANDRIA:READ-FILE-INTO-STRING DEPENDENCIES::FILE))
;             (DEPENDENCIES::MODIFIED-FILE-STRING ""))
;         (SETF DEPENDENCIES::MODIFIED-FILE-STRING
;                 (CL-PPCRE:REGEX-REPLACE-ALL "[ trn]'[A-Za-z0-9!@$%&*_+:=<.>/?-]+"
;                                             DEPENDENCIES::FILE-STRING " NIL"))
;         (CL-PPCRE:REGEX-REPLACE-ALL
;          "[(][qQ][uU][oO][tT][eE][ trn]+[A-Za-z0-9!@$%&*_+:=<.>/?-]+[)]"
;          DEPENDENCIES::MODIFIED-FILE-STRING "NIL")))
; --> PROGN SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA
; ==>
;   #'(SB-INT:NAMED-LAMBDA DEPENDENCIES::PURIFY-FILE
;         (DEPENDENCIES::FILE)
;       (DECLARE (SB-C::TOP-LEVEL-FORM))
;       "Transforms problematic symbols to benign NIL in file, before reading.
;    Returns a string of altered file content."
;       (BLOCK DEPENDENCIES::PURIFY-FILE
;         (LET ((DEPENDENCIES::FILE-STRING #)
;               (DEPENDENCIES::MODIFIED-FILE-STRING ""))
;           (SETF DEPENDENCIES::MODIFIED-FILE-STRING #)
;           (CL-PPCRE:REGEX-REPLACE-ALL
;            "[(][qQ][uU][oO][tT][eE][ trn]+[A-Za-z0-9!@$%&*_+:=<.>/?-]+[)]"
;            DEPENDENCIES::MODIFIED-FILE-STRING "NIL"))))
;
; note: type assertion too complex to check:
; (VALUES STRING &OPTIONAL BOOLEAN &REST T).

My specification for this function is (declaim (ftype (function (pathname) (values string (member NIL T))) purify-file))

Is it something about CL-PPCRE:REGEX-REPLACE-ALL returning multiple values? If so, how do you use ftype to specify the type of all multiple values--in this case string & NIL or T? Thanks.


Solution

  • Example:

    * (declaim (ftype (function () (values string boolean)) f))
    (F)
    * (defun f () (values "a" t))
    F
    * (describe #'f)
    #<FUNCTION F>
      [compiled function]
    
    Lambda-list: ()
    Declared type: (FUNCTION NIL (VALUES STRING &OPTIONAL BOOLEAN &REST T))
    Derived type: (FUNCTION NIL
                   (VALUES (SIMPLE-ARRAY CHARACTER (1)) (MEMBER T) &OPTIONAL))
    

    As you can see, (VALUES STRING BOOLEAN) is implicitly extended with &REST T. To remove the implicit &REST replace it with an empty &OPTIONAL like in the derived type shown: (VALUES STRING BOOLEAN &OPTIONAL).