-;;; Check the legality of a function name that is being introduced.
-;;; -- If it names a macro, then give a warning and blast the macro
-;;; information.
-;;; -- If it is a structure slot accessor, give a warning and blast
-;;; the structure.
-;;; -- Check for conflicting setf macros.
-(declaim (ftype (function ((or symbol cons)) t) proclaim-as-function-name))
-(defun proclaim-as-function-name (name)
- (check-function-name name)
- (ecase (info :function :kind name)
- (:function
- (let ((accessor-for (info :function :accessor-for name)))
- (when accessor-for
- (compiler-warning
- "Undefining structure type:~% ~S~@
- so that this slot accessor can be redefined:~% ~S"
- (sb!xc:class-name accessor-for) name)
- ;; FIXME: This is such weird, unfriendly behavior.. (What if
- ;; the user didn't want his structure blasted?) It probably
- ;; violates ANSI, too. (Check this.) Perhaps instead of
- ;; undefining the structure, we should attach the lost
- ;; accessor function to SB-EXT:LOST-STRUCTURE-ACCESSORS on
- ;; the property list of the symbol which names the structure?
- (undefine-structure accessor-for)
- (setf (info :function :kind name) :function))))
- (:macro
- (compiler-style-warning "~S previously defined as a macro." name)
- (setf (info :function :kind name) :function)
- (setf (info :function :where-from name) :assumed)
- (clear-info :function :macro-function name))
- ((nil)
- (setf (info :function :kind name) :function)))
- (note-if-setf-function-and-macro name)
- name)
-
-;;; Make NAME no longer be a function name: clear everything back to the
-;;; default.
-(defun undefine-function-name (name)
+;;;; internal utilities defined in terms of INFO
+
+;;; Check that NAME is a valid function name, returning the name if
+;;; OK, and signalling an error if not. In addition to checking for
+;;; basic well-formedness, we also check that symbol names are not NIL
+;;; or the name of a special form.
+(defun check-fun-name (name)
+ (typecase name
+ (list
+ (unless (legal-fun-name-p name)
+ (compiler-error "illegal function name: ~S" name)))
+ (symbol
+ (when (eq (info :function :kind name) :special-form)
+ (compiler-error "Special form is an illegal function name: ~S" name)))
+ (t
+ (compiler-error "illegal function name: ~S" name)))
+ (values))
+
+;;; Record a new function definition, and check its legality.
+(defun proclaim-as-fun-name (name)
+
+ ;; legal name?
+ (check-fun-name name)
+
+
+ ;; KLUDGE: This can happen when eg. compiling a NAMED-LAMBDA, and isn't
+ ;; guarded against elsewhere -- so we want to assert package locks here. The
+ ;; reason we do it only when stomping on existing stuff is because we want
+ ;; to keep
+ ;; (WITHOUT-PACKAGE-LOCKS (DEFUN LOCKED:FOO ...))
+ ;; viable, which requires no compile-time violations in the harmless cases.
+ (with-single-package-locked-error ()
+ (flet ((assert-it ()
+ (assert-symbol-home-package-unlocked name "proclaiming ~S as a function")))
+
+ (let ((kind (info :function :kind name)))
+ ;; scrubbing old data I: possible collision with a macro
+ (when (and (fboundp name) (eq :macro kind))
+ (assert-it)
+ (compiler-style-warn "~S was previously defined as a macro." name)
+ (setf (info :function :where-from name) :assumed)
+ (clear-info :function :macro-function name))
+
+ (unless (eq :function kind)
+ (assert-it)
+ (setf (info :function :kind name) :function)))))
+
+ ;; scrubbing old data II: dangling forward references
+ ;;
+ ;; (This could happen if someone executes PROCLAIM FTYPE at
+ ;; macroexpansion time, which is bad style, or at compile time, e.g.
+ ;; in EVAL-WHEN (:COMPILE) inside something like DEFSTRUCT, in which
+ ;; case it's reasonable style. Either way, NAME is no longer a free
+ ;; function.)
+ (when (boundp '*free-funs*) ; when compiling
+ (remhash name *free-funs*))
+
+ (note-if-setf-fun-and-macro name)
+
+ (values))
+
+;;; This is called to do something about SETF functions that overlap
+;;; with SETF macros. Perhaps we should interact with the user to see
+;;; whether the macro should be blown away, but for now just give a
+;;; warning. Due to the weak semantics of the (SETF FUNCTION) name, we
+;;; can't assume that they aren't just naming a function (SETF FOO)
+;;; for the heck of it. NAME is already known to be well-formed.
+(defun note-if-setf-fun-and-macro (name)
+ (when (consp name)
+ (when (or (info :setf :inverse name)
+ (info :setf :expander name))
+ (compiler-style-warn
+ "defining as a SETF function a name that already has a SETF macro:~
+ ~% ~S"
+ name)))
+ (values))
+
+;;; Make NAME no longer be a function name: clear everything back to
+;;; the default.
+(defun undefine-fun-name (name)