1.0.18.1: correct handling of SATISFIES types in the compiler
[sbcl.git] / src / compiler / constantp.lisp
index 41a69d6..85bb5b8 100644 (file)
@@ -40,7 +40,7 @@
       (list
        (or (constant-special-form-p form environment envp)
            #-sb-xc-host
-           (constant-function-call-p form environment envp)))
+           (values (constant-function-call-p form environment envp))))
       (t t))))
 
 (defun %constant-form-value (form environment envp)
 ;;; too.
 (defun constant-function-call-p (form environment envp)
   (let ((name (car form)))
-    (and (legal-fun-name-p name)
-         (eq :function (info :function :kind name))
-         (let ((info (info :function :info name)))
-           (and info (ir1-attributep (fun-info-attributes info)
-                                     foldable)))
-         (every (lambda (arg)
-                  (%constantp arg environment envp))
-                (cdr form)))))
+    (if (and (legal-fun-name-p name)
+             (eq :function (info :function :kind name))
+             (let ((info (info :function :info name)))
+               (and info (ir1-attributep (fun-info-attributes info)
+                                         foldable)))
+             (and (every (lambda (arg)
+                           (%constantp arg environment envp))
+                         (cdr form))))
+        ;; Even though the function may be marked as foldable
+        ;; the call may still signal an error -- eg: (CAR 1).
+        (handler-case
+            (values t (constant-function-call-value form environment envp))
+          (error ()
+            (values nil nil)))
+        (values nil nil))))
 
 (defun constant-function-call-value (form environment envp)
   (apply (fdefinition (car form))
@@ -138,7 +145,7 @@ constantness of the FORM in ENVIRONMENT."
                   ;; instead of general (not handling cases like &key (x y))
                   (declare (ignorable
                             ,@(remove-if (lambda (arg)
-                                           (member arg lambda-list-keywords))
+                                           (member arg sb!xc:lambda-list-keywords))
                                          lambda-list)))
                    ,body))))
       `(progn
@@ -172,14 +179,13 @@ constantness of the FORM in ENVIRONMENT."
    :test (every #'constantp* (cons protected-form cleanup-forms))
    :eval (constant-form-value* protected-form))
 
- (defconstantp the (value-type form)
-   :test (constantp* form)
-   :eval (let ((value (constant-form-value* form)))
-           (if (typep value value-type)
-               value
-               (error 'type-error
-                      :datum value
-                      :expected-type value-type))))
+ (defconstantp the (type form)
+   :test (and (constantp* form)
+              (handler-case
+                  ;; in case the type-spec is malformed!
+                  (typep (constant-form-value* form) type)
+                (error () nil)))
+   :eval (constant-form-value* form))
 
  (defconstantp block (name &body forms)
    ;; We currently fail to detect cases like
@@ -195,15 +201,18 @@ constantness of the FORM in ENVIRONMENT."
 
  (defconstantp multiple-value-prog1 (first-form &body forms)
    :test (every #'constantp* (cons first-form forms))
-   :test (constant-form-value* first-form))
+   :eval (constant-form-value* first-form))
 
  (defconstantp progv (symbols values &body forms)
    :test (and (constantp* symbols)
               (constantp* values)
-              (let ((*special-constant-variables*
-                     (append (constant-form-value* symbols)
-                              *special-constant-variables*)))
-                (every #'constantp* forms)))
+              (let* ((symbol-values (constant-form-value* symbols))
+                     (*special-constant-variables*
+                      (append symbol-values *special-constant-variables*)))
+                (progv
+                    symbol-values
+                    (constant-form-value* values)
+                  (every #'constantp* forms))))
    :eval (progv
              (constant-form-value* symbols)
              (constant-form-value* values)