From: Stas Boukarev Date: Thu, 17 Oct 2013 15:16:41 +0000 (+0400) Subject: Stop (describe (make-instance 'generic-function)) from crashing. X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=f0f3805c145f2699701997761e2c6f55c475c192;p=sbcl.git Stop (describe (make-instance 'generic-function)) from crashing. All the describy things can be pried out of a generic function only if it's a standard-generic-function. Also add an FNDB entry for FUNCTION-LAMBDA-EXPRESSION. --- diff --git a/src/code/describe.lisp b/src/code/describe.lisp index 77f3c36..50f45ac 100644 --- a/src/code/describe.lisp +++ b/src/code/describe.lisp @@ -616,7 +616,7 @@ (:declared :declared) ;; This is hopefully clearer to users ((:defined-method :defined) :derived)))))) - (if (typep fun 'generic-function) + (if (typep fun 'standard-generic-function) (values fun "a generic function" (sb-mop:generic-function-lambda-list fun) diff --git a/src/compiler/fndb.lisp b/src/compiler/fndb.lisp index bb39bc4..0909630 100644 --- a/src/compiler/fndb.lisp +++ b/src/compiler/fndb.lisp @@ -1374,6 +1374,7 @@ null) (defknown describe (t &optional (or stream (member t nil))) (values)) +(defknown function-lambda-expression (function) (values t boolean t)) (defknown inspect (t) (values)) (defknown room (&optional (member t nil :default)) (values)) (defknown ed (&optional (or symbol cons filename)) diff --git a/tests/interface.impure.lisp b/tests/interface.impure.lisp index 0838bdd..da179ed 100644 --- a/tests/interface.impure.lisp +++ b/tests/interface.impure.lisp @@ -30,31 +30,32 @@ (assert (string= (documentation #'(setf foo) 'function) "(setf foo) documentation")) +(with-test (:name :disassemble) ;;; DISASSEMBLE shouldn't fail on closures or unpurified functions -(defun disassemble-fun (x) x) -(disassemble 'disassemble-fun) - -(let ((x 1)) (defun disassemble-closure (y) (if y (setq x y) x))) -(disassemble 'disassemble-closure) - -#+sb-eval -(progn - ;; Nor should it fail on interpreted functions - (let ((sb-ext:*evaluator-mode* :interpret)) - (eval `(defun disassemble-eval (x) x)) - (disassemble 'disassemble-eval)) - - ;; disassemble-eval should still be an interpreted function. - ;; clhs disassemble: "(If that function is an interpreted function, - ;; 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)) + (defun disassemble-fun (x) x) + (disassemble 'disassemble-fun) + + (let ((x 1)) (defun disassemble-closure (y) (if y (setq x y) x))) + (disassemble 'disassemble-closure) + + #+sb-eval + (progn + ;; Nor should it fail on interpreted functions + (let ((sb-ext:*evaluator-mode* :interpret)) + (eval `(defun disassemble-eval (x) x)) + (disassemble 'disassemble-eval)) + + ;; disassemble-eval should still be an interpreted function. + ;; clhs disassemble: "(If that function is an interpreted function, + ;; 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 (make-instance 'sb-mop:funcallable-standard-object))) + (disassemble fin))) ;;; while we're at it, much the same applies to ;;; FUNCTION-LAMBDA-EXPRESSION: @@ -69,7 +70,11 @@ (assert (eql (fle-name #'fle-closure) 'fle-closure)) (assert (eql (fle-name #'disassemble-generic) 'disassemble-generic)) (function-lambda-expression - (sb-mop:make-instance 'sb-mop:funcallable-standard-object)) + (make-instance 'sb-mop:funcallable-standard-object)) + (function-lambda-expression + (make-instance 'generic-function)) + (function-lambda-expression + (make-instance 'standard-generic-function)) #+sb-eval (progn (let ((sb-ext:*evaluator-mode* :interpret)) @@ -86,6 +91,10 @@ (let ((sb-ext:*evaluator-mode* :compile)) (eval `(let (x) (defun closure-to-describe () (incf x))))) +(with-test (:name :describe-empty-gf) + (describe (make-instance 'generic-function)) + (describe (make-instance 'standard-generic-function))) + ;;; DESCRIBE should run without signalling an error. (with-test (:name (describe :no-error)) (describe (make-to-be-described))