1.0.46.43: fix sb-introspect on non-threaded builds
[sbcl.git] / tests / interface.impure.lisp
index 1914816..cbb9ae3 100644 (file)
@@ -12,7 +12,9 @@
 ;;;; more information.
 
 (load "assertoid.lisp")
+(load "test-util.lisp")
 (use-package "ASSERTOID")
+(use-package "TEST-UTIL")
 
 (defun (setf foo) (x)
   "(setf foo) documentation"
   ;; it is first compiled but the result of this implicit compilation
   ;; is not installed.)"
   (assert (sb-eval:interpreted-function-p #'disassemble-eval)))
+
+;; nor should it fail on generic functions or other funcallable instances
+(defgeneric disassemble-generic (x))
+(disassemble 'disassemble-generic)
+(let ((fin (sb-mop:make-instance 'sb-mop:funcallable-standard-object)))
+  (disassemble fin))
+
+;;; while we're at it, much the same applies to
+;;; FUNCTION-LAMBDA-EXPRESSION:
+(defun fle-fun (x) x)
+(function-lambda-expression #'fle-fun)
+
+(let ((x 1)) (defun fle-closure (y) (if y (setq x y) x)))
+(function-lambda-expression #'fle-closure)
+
+#+sb-eval
+(progn
+  ;; Nor should it fail on interpreted functions
+  (let ((sb-ext:*evaluator-mode* :interpret))
+    (eval `(defun fle-eval (x) x))
+    (function-lambda-expression #'fle-eval))
+
+  ;; fle-eval should still be an interpreted function.
+  (assert (sb-eval:interpreted-function-p #'fle-eval)))
+
+;; nor should it fail on generic functions or other funcallable instances
+(defgeneric fle-generic (x))
+(function-lambda-expression #'fle-generic)
+(let ((fin (sb-mop:make-instance 'sb-mop:funcallable-standard-object)))
+  (function-lambda-expression fin))
 \f
 ;;; support for DESCRIBE tests
 (defstruct to-be-described a b)
   (let ((s (with-output-to-string (s)
              (write-char #\x s)
              (describe i s))))
-    (unless (and (char= #\x (char s 0))
-                 ;; one leading #\NEWLINE from FRESH-LINE or the like, no more
-                 (char= #\newline (char s 1))
-                 (char/= #\newline (char s 2))
-                 ;; one trailing #\NEWLINE from TERPRI or the like, no more
-                 (let ((n (length s)))
-                   (and (char= #\newline (char s (- n 1)))
-                        (char/= #\newline (char s (- n 2))))))
-      (error "misbehavior in DESCRIBE of ~S" i))))
+    (macrolet ((check (form)
+                 `(or ,form
+                      (error "misbehavior in DESCRIBE of ~S:~%   ~S" i ',form))))
+      (check (char= #\x (char s 0)))
+      ;; one leading #\NEWLINE from FRESH-LINE or the like, no more
+      (check (char= #\newline (char s 1)))
+      (check (char/= #\newline (char s 2)))
+      ;; one trailing #\NEWLINE from TERPRI or the like, no more
+      (let ((n (length s)))
+        (check (char= #\newline (char s (- n 1))))
+        (check (char/= #\newline (char s (- n 2))))))))
 
 \f
 ;;; Tests of documentation on types and classes
 (assert (string= (documentation 'frob 'structure) "FROB"))
 (setf (documentation 'frob 'structure) "NEW5")
 (assert (string= (documentation 'frob 'structure) "NEW5"))
+
+(define-compiler-macro cmacro (x)
+  "compiler macro"
+  x)
+
+(define-compiler-macro (setf cmacro) (y x)
+  "setf compiler macro"
+  y)
+
+(with-test (:name (documentation compiler-macro))
+  (unless (equal "compiler macro"
+                 (documentation 'cmacro 'compiler-macro))
+    (error "got ~S for cmacro"
+           (documentation 'cmacro 'compiler-macro)))
+  (unless (equal "setf compiler macro"
+                 (documentation '(setf cmacro) 'compiler-macro))
+    (error "got ~S for setf macro" (documentation '(setf cmacro) 'compiler-macro))))
+
+(with-test (:name (documentation lambda))
+  (let ((f (lambda () "aos the zos" t))
+        (g (sb-int:named-lambda fii () "zoot the fruit" t)))
+    (dolist (doc-type '(t function))
+      (assert (string= (documentation f doc-type) "aos the zos"))
+      (assert (string= (documentation g doc-type) "zoot the fruit")))
+    (setf (documentation f t) "fire")
+    (assert (string= (documentation f t) "fire"))
+    (assert (string= (documentation g t) "zoot the fruit"))))
+
+(with-test (:name (documentation flet))
+  (assert
+   (string= (documentation
+             (flet ((quux (x)
+                      "this is FLET quux"
+                      (/ x 2)))
+               #'quux)
+             t)
+            "this is FLET quux")))
+
+(with-test (:name (documentation labels))
+  (assert
+   (string= (documentation
+             (labels ((rec (x)
+                        "this is LABELS rec"
+                        (if (plusp x)
+                            (* x (rec (1- x)))
+                            1)))
+               #'rec)
+             t)
+            "this is LABELS rec")))
+
+(let ((x 1))
+  (defun docfoo (y)
+    "bar"
+    (incf x y)))
+
+(with-test (:name (documentation closure))
+  (assert (string= (documentation 'docfoo 'function) "bar"))
+  (assert (string= (documentation #'docfoo t) "bar"))
+  (assert (string= (setf (documentation 'docfoo 'function) "baz") "baz"))
+  (assert (string= (documentation 'docfoo 'function) "baz"))
+  (assert (string= (documentation #'docfoo t) "bar"))
+  (assert (string= (setf (documentation #'docfoo t) "zot") "zot"))
+  (assert (string= (documentation #'docfoo t) "zot"))
+  (assert (string= (documentation 'docfoo 'function) "baz"))
+  (assert (not (setf (documentation 'docfoo 'function) nil)))
+  (assert (string= (documentation 'docfoo 'function) "zot")))
+
+#+sb-doc
+(with-test (:name (documentation built-in-macro))
+  (assert (documentation 'trace 'function)))
+
+#+sb-doc
+(with-test (:name (documentation built-in-function))
+  (assert (documentation 'cons 'function)))
+
+(with-test (:name :describe-generic-function-with-assumed-type)
+  ;; Signalled an error at one point
+  (flet ((zoo () (gogo)))
+    (defmethod gogo () nil)
+    (describe 'gogo)))
+
+(defmacro bug-643958-test ()
+  "foo"
+  :ding!)
+
+(with-test (:name :bug-643958)
+  (assert (equal "foo" (documentation 'bug-643958-test 'function)))
+  (setf (documentation 'bug-643958-test 'function) "bar")
+  (assert (equal "bar" (documentation 'bug-643958-test 'function))))
 \f
 ;;;; success