1.0.19.3: more careful PROGV and SET
[sbcl.git] / tests / compiler.impure.lisp
index 89a9d83..a508073 100644 (file)
     (eval '(labels ((%f (&key x) x)) (%f nil nil)))
   (error (c) :good)
   (:no-error (val) (error "no error: ~S" val)))
+
+;;; PROGV must not bind constants, or violate declared types -- ditto for SET.
+(assert (raises-error? (set pi 3)))
+(assert (raises-error? (progv '(pi s) '(3 pi) (symbol-value x))))
+(declaim (cons *special-cons*))
+(assert (raises-error? (set '*special-cons* "nope") type-error))
+(assert (raises-error? (progv '(*special-cons*) '("no hope") (car *special-cons*)) type-error))
 \f
 ;;;; tests not in the problem domain, but of the consistency of the
 ;;;; compiler machinery itself
 (defconstant +born-to-coalesce4+ '(foo bar "zot" 123 (nested "quux") #*0101110010))
 (assert-coalescing '+born-to-coalesce4+)
 
+(defclass some-constant-thing () ())
+
+;;; correct handling of nested things loaded via SYMBOL-VALUE
+(defvar *sneaky-nested-thing* (list (make-instance 'some-constant-thing)))
+(defconstant +sneaky-nested-thing+ *sneaky-nested-thing*)
+(multiple-value-bind (file-fun core-fun) (compile2 '(lambda () +sneaky-nested-thing+))
+  (assert (equal *sneaky-nested-thing* (funcall file-fun)))
+  (assert (equal *sneaky-nested-thing* (funcall core-fun))))
+
 ;;; catch constant modifications thru undefined variables
 (defun sneak-set-dont-set-me (x)
   (ignore-errors (setq dont-set-me x)))
 (defconstant dont-set-me 42)
 (assert (not (sneak-set-dont-set-me 13)))
 (assert (= 42 dont-set-me))
-(defclass some-constant-thing () ())
 (defun sneak-set-dont-set-me2 (x)
   (ignore-errors (setq dont-set-me2 x)))
 (defconstant dont-set-me2 (make-instance 'some-constant-thing))
 (assert (not (sneak-set-dont-set-me2 13)))
 (assert (typep dont-set-me2 'some-constant-thing))
 
+;;; check that non-trivial constants are EQ across different files: this is
+;;; not something ANSI either guarantees or requires, but we want to do it
+;;; anyways.
+(defconstant +share-me-1+ 123.456d0)
+(defconstant +share-me-2+ "a string to share")
+(defconstant +share-me-3+ (vector 1 2 3))
+(defconstant +share-me-4+ (* 2 most-positive-fixnum))
+(multiple-value-bind (f1 c1) (compile2 '(lambda () (values +share-me-1+
+                                                           +share-me-2+
+                                                           +share-me-3+
+                                                           +share-me-4+
+                                                           pi)))
+  (multiple-value-bind (f2 c2) (compile2 '(lambda () (values +share-me-1+
+                                                             +share-me-2+
+                                                             +share-me-3+
+                                                             +share-me-4+
+                                                             pi)))
+    (flet ((test (fa fb)
+             (mapc (lambda (a b)
+                     (assert (eq a b)))
+                   (multiple-value-list (funcall fa))
+                   (multiple-value-list (funcall fb)))))
+      (test f1 c1)
+      (test f1 f2)
+      (test f1 c2))))
+
+;;; user-defined satisfies-types cannot be folded
+(deftype mystery () '(satisfies mysteryp))
+(defvar *mystery* nil)
+(defun mysteryp (x) (eq x *mystery*))
+(defstruct thing (slot (error "missing") :type mystery))
+(defun test-mystery (m) (when (eq :mystery (thing-slot m)) :ok))
+(setf *mystery* :mystery)
+(assert (eq :ok (test-mystery (make-thing :slot :mystery))))
+
 ;;; success