- ;; KLUDGE: This stuff might well blow up if we tried to execute it
- ;; when cross-compiling. But since for the foreseeable future the
- ;; only code we'll try to cross-compile is SBCL itself, and SBCL is
- ;; built without using SATISFIES types, it's arguably not important
- ;; to worry about this. -- WHN 19990210.
- (let ((fun (second hairy-spec)))
- (cond ((and (consp fun)
- (eq (car fun) 'lambda))
- (values (not (null (funcall (coerce fun 'function) obj)))
- t))
- ((and (symbolp fun) (fboundp fun))
- (values (not (null (funcall fun obj))) t))
- (t
- (values nil nil))))))))))
+ (let ((predicate-name (second hairy-spec)))
+ (declare (type symbol predicate-name)) ; by ANSI spec of SATISFIES
+ (if (fboundp predicate-name)
+ (let* (;; "Is OBJ of the SATISFIES type?" represented
+ ;; as a generalized boolean.
+ ;;
+ ;; (Why IGNORE-ERRORS? This code is used to try to
+ ;; check type relationships at compile time.
+ ;; Passing only-slightly-twisted types like
+ ;; (AND INTEGER (SATISFIES ODDP)) into the
+ ;; rather-significantly-twisted type dispatch
+ ;; system can easily give rise to oddities like
+ ;; calling predicates like ODDP on values they
+ ;; don't like. (E.g. on OBJ=#\NEWLINE when the
+ ;; above type is tested for TYPE= against
+ ;; STANDARD-CHAR, represented as a
+ ;; MEMBER-TYPE.) In such cases, NIL seems to be
+ ;; an appropriate answer to "is OBJ of the
+ ;; SATISFIES type?")
+ (gbool (ignore-errors (funcall predicate-name obj)))
+ ;; RAW coerced to a pure BOOLEAN value
+ (bool (not (not gbool))))
+ (values bool t))
+ (values nil nil)))))))))