1.0.20.28: Fewer STYLE-WARNINGs for gf calls.
[sbcl.git] / src / pcl / boot.lisp
index 8f3a2da..bedfc51 100644 (file)
@@ -252,8 +252,9 @@ bootstrapping.
 
 (defun load-defgeneric (fun-name lambda-list source-location &rest initargs)
   (when (fboundp fun-name)
-    (style-warn "redefining ~S in DEFGENERIC" fun-name)
     (let ((fun (fdefinition fun-name)))
+      (warn 'sb-kernel:redefinition-with-defgeneric :name fun-name
+            :old fun :new-location source-location)
       (when (generic-function-p fun)
         (loop for method in (generic-function-initial-methods fun)
               do (remove-method fun method))
@@ -343,13 +344,13 @@ bootstrapping.
       (eval-when (:execute)
         (%defmethod-expander ,name ,qualifiers ,lambda-list ,body)))))
 
-(defmacro %defmethod-expander 
+(defmacro %defmethod-expander
     (name qualifiers lambda-list body &environment env)
   (multiple-value-bind (proto-gf proto-method)
       (prototypes-for-make-method-lambda name)
     (expand-defmethod name proto-gf proto-method qualifiers
                       lambda-list body env)))
-  
+
 
 (defun prototypes-for-make-method-lambda (name)
   (if (not (eq *boot-state* 'complete))
@@ -513,9 +514,6 @@ bootstrapping.
     (sb-c:source-location)))
 
 (defmacro make-method-function (method-lambda &environment env)
-  (make-method-function-internal method-lambda env))
-
-(defun make-method-function-internal (method-lambda &optional env)
   (multiple-value-bind (proto-gf proto-method)
       (prototypes-for-make-method-lambda nil)
     (multiple-value-bind (method-function-lambda initargs)
@@ -578,14 +576,170 @@ bootstrapping.
   (setf (gdefinition 'make-method-initargs-form)
         (symbol-function 'real-make-method-initargs-form)))
 
+;;; When bootstrapping PCL MAKE-METHOD-LAMBDA starts out as a regular
+;;; functions: REAL-MAKE-METHOD-LAMBDA set to the fdefinition of
+;;; MAKE-METHOD-LAMBDA. Once generic functions are born, the
+;;; REAL-MAKE-METHOD lambda is used as the body of the default method.
+;;; MAKE-METHOD-LAMBDA-INTERNAL is split out into a separate function
+;;; so that changing it in a live image is easy, and changes actually
+;;; take effect.
 (defun real-make-method-lambda (proto-gf proto-method method-lambda env)
-  (declare (ignore proto-gf proto-method))
-  (make-method-lambda-internal method-lambda env))
+  (make-method-lambda-internal proto-gf proto-method method-lambda env))
 
 (unless (fboundp 'make-method-lambda)
   (setf (gdefinition 'make-method-lambda)
         (symbol-function 'real-make-method-lambda)))
 
+(defun make-method-lambda-internal (proto-gf proto-method method-lambda env)
+  (declare (ignore proto-gf proto-method))
+  (unless (and (consp method-lambda) (eq (car method-lambda) 'lambda))
+    (error "The METHOD-LAMBDA argument to MAKE-METHOD-LAMBDA, ~S, ~
+            is not a lambda form."
+           method-lambda))
+  (multiple-value-bind (real-body declarations documentation)
+      (parse-body (cddr method-lambda))
+    (let* ((name-decl (get-declaration '%method-name declarations))
+           (sll-decl (get-declaration '%method-lambda-list declarations))
+           (method-name (when (consp name-decl) (car name-decl)))
+           (generic-function-name (when method-name (car method-name)))
+           (specialized-lambda-list (or sll-decl (cadr method-lambda)))
+           ;; the method-cell is a way of communicating what method a
+           ;; method-function implements, for the purpose of
+           ;; NO-NEXT-METHOD.  We need something that can be shared
+           ;; between function and initargs, but not something that
+           ;; will be coalesced as a constant (because we are naughty,
+           ;; oh yes) with the expansion of any other methods in the
+           ;; same file.  -- CSR, 2007-05-30
+           (method-cell (list (make-symbol "METHOD-CELL"))))
+      (multiple-value-bind (parameters lambda-list specializers)
+          (parse-specialized-lambda-list specialized-lambda-list)
+        (let* ((required-parameters
+                (mapcar (lambda (r s) (declare (ignore s)) r)
+                        parameters
+                        specializers))
+               (slots (mapcar #'list required-parameters))
+               (class-declarations
+                `(declare
+                  ;; These declarations seem to be used by PCL to pass
+                  ;; information to itself; when I tried to delete 'em
+                  ;; ca. 0.6.10 it didn't work. I'm not sure how
+                  ;; they work, but note the (VAR-DECLARATION '%CLASS ..)
+                  ;; expression in CAN-OPTIMIZE-ACCESS1. -- WHN 2000-12-30
+                  ,@(remove nil
+                            (mapcar (lambda (a s) (and (symbolp s)
+                                                       (neq s t)
+                                                       `(%class ,a ,s)))
+                                    parameters
+                                    specializers))
+                  ;; These TYPE declarations weren't in the original
+                  ;; PCL code, but the Python compiler likes them a
+                  ;; lot. (We're telling the compiler about our
+                  ;; knowledge of specialized argument types so that
+                  ;; it can avoid run-time type dispatch overhead,
+                  ;; which can be a huge win for Python.)
+                  ;;
+                  ;; KLUDGE: when I tried moving these to
+                  ;; ADD-METHOD-DECLARATIONS, things broke.  No idea
+                  ;; why.  -- CSR, 2004-06-16
+                  ,@(mapcar #'parameter-specializer-declaration-in-defmethod
+                            parameters
+                            specializers)))
+               (method-lambda
+                ;; Remove the documentation string and insert the
+                ;; appropriate class declarations. The documentation
+                ;; string is removed to make it easy for us to insert
+                ;; new declarations later, they will just go after the
+                ;; CADR of the method lambda. The class declarations
+                ;; are inserted to communicate the class of the method's
+                ;; arguments to the code walk.
+                `(lambda ,lambda-list
+                   ;; The default ignorability of method parameters
+                   ;; doesn't seem to be specified by ANSI. PCL had
+                   ;; them basically ignorable but was a little
+                   ;; inconsistent. E.g. even though the two
+                   ;; method definitions
+                   ;;   (DEFMETHOD FOO ((X T) (Y T)) "Z")
+                   ;;   (DEFMETHOD FOO ((X T) Y) "Z")
+                   ;; are otherwise equivalent, PCL treated Y as
+                   ;; ignorable in the first definition but not in the
+                   ;; second definition. We make all required
+                   ;; parameters ignorable as a way of systematizing
+                   ;; the old PCL behavior. -- WHN 2000-11-24
+                   (declare (ignorable ,@required-parameters))
+                   ,class-declarations
+                   ,@declarations
+                   (block ,(fun-name-block-name generic-function-name)
+                     ,@real-body)))
+               (constant-value-p (and (null (cdr real-body))
+                                      (constantp (car real-body))))
+               (constant-value (and constant-value-p
+                                    (constant-form-value (car real-body))))
+               (plist (and constant-value-p
+                           (or (typep constant-value
+                                      '(or number character))
+                               (and (symbolp constant-value)
+                                    (symbol-package constant-value)))
+                           (list :constant-value constant-value)))
+               (applyp (dolist (p lambda-list nil)
+                         (cond ((memq p '(&optional &rest &key))
+                                (return t))
+                               ((eq p '&aux)
+                                (return nil))))))
+          (multiple-value-bind
+                (walked-lambda call-next-method-p closurep
+                               next-method-p-p setq-p
+                               parameters-setqd)
+              (walk-method-lambda method-lambda
+                                  required-parameters
+                                  env
+                                  slots)
+            (multiple-value-bind (walked-lambda-body
+                                  walked-declarations
+                                  walked-documentation)
+                (parse-body (cddr walked-lambda))
+              (declare (ignore walked-documentation))
+              (when (some #'cdr slots)
+                (let ((slot-name-lists (slot-name-lists-from-slots slots)))
+                  (setq plist
+                        `(,@(when slot-name-lists
+                                  `(:slot-name-lists ,slot-name-lists))
+                            ,@plist))
+                  (setq walked-lambda-body
+                        `((pv-binding (,required-parameters
+                                       ,slot-name-lists
+                                       (load-time-value
+                                        (intern-pv-table
+                                         :slot-name-lists ',slot-name-lists)))
+                            ,@walked-lambda-body)))))
+              (when (and (memq '&key lambda-list)
+                         (not (memq '&allow-other-keys lambda-list)))
+                (let ((aux (memq '&aux lambda-list)))
+                  (setq lambda-list (nconc (ldiff lambda-list aux)
+                                           (list '&allow-other-keys)
+                                           aux))))
+              (values `(lambda (.method-args. .next-methods.)
+                         (simple-lexical-method-functions
+                             (,lambda-list .method-args. .next-methods.
+                                           :call-next-method-p
+                                           ,call-next-method-p
+                                           :next-method-p-p ,next-method-p-p
+                                           :setq-p ,setq-p
+                                           :method-cell ,method-cell
+                                           :closurep ,closurep
+                                           :applyp ,applyp)
+                           ,@walked-declarations
+                           (locally
+                               (declare (disable-package-locks
+                                         %parameter-binding-modified))
+                             (symbol-macrolet ((%parameter-binding-modified
+                                                ',@parameters-setqd))
+                               (declare (enable-package-locks
+                                         %parameter-binding-modified))
+                               ,@walked-lambda-body))))
+                      `(,@(when call-next-method-p `(method-cell ,method-cell))
+                          ,@(when plist `(plist ,plist))
+                          ,@(when documentation `(:documentation ,documentation)))))))))))
+
 (defun real-make-method-specializers-form
     (proto-gf proto-method specializer-names env)
   (declare (ignore env proto-gf proto-method))
@@ -776,161 +930,6 @@ bootstrapping.
 ;;; optimized-slot-value* macros.
 (define-symbol-macro %parameter-binding-modified ())
 
-(defun make-method-lambda-internal (method-lambda &optional env)
-  (unless (and (consp method-lambda) (eq (car method-lambda) 'lambda))
-    (error "The METHOD-LAMBDA argument to MAKE-METHOD-LAMBDA, ~S, ~
-            is not a lambda form."
-           method-lambda))
-  (multiple-value-bind (real-body declarations documentation)
-      (parse-body (cddr method-lambda))
-    (let* ((name-decl (get-declaration '%method-name declarations))
-           (sll-decl (get-declaration '%method-lambda-list declarations))
-           (method-name (when (consp name-decl) (car name-decl)))
-           (generic-function-name (when method-name (car method-name)))
-           (specialized-lambda-list (or sll-decl (cadr method-lambda)))
-           ;; the method-cell is a way of communicating what method a
-           ;; method-function implements, for the purpose of
-           ;; NO-NEXT-METHOD.  We need something that can be shared
-           ;; between function and initargs, but not something that
-           ;; will be coalesced as a constant (because we are naughty,
-           ;; oh yes) with the expansion of any other methods in the
-           ;; same file.  -- CSR, 2007-05-30
-           (method-cell (list (make-symbol "METHOD-CELL"))))
-      (multiple-value-bind (parameters lambda-list specializers)
-          (parse-specialized-lambda-list specialized-lambda-list)
-        (let* ((required-parameters
-                (mapcar (lambda (r s) (declare (ignore s)) r)
-                        parameters
-                        specializers))
-               (slots (mapcar #'list required-parameters))
-               (calls (list nil))
-               (class-declarations
-                `(declare
-                  ;; These declarations seem to be used by PCL to pass
-                  ;; information to itself; when I tried to delete 'em
-                  ;; ca. 0.6.10 it didn't work. I'm not sure how
-                  ;; they work, but note the (VAR-DECLARATION '%CLASS ..)
-                  ;; expression in CAN-OPTIMIZE-ACCESS1. -- WHN 2000-12-30
-                  ,@(remove nil
-                            (mapcar (lambda (a s) (and (symbolp s)
-                                                       (neq s t)
-                                                       `(%class ,a ,s)))
-                                    parameters
-                                    specializers))
-                  ;; These TYPE declarations weren't in the original
-                  ;; PCL code, but the Python compiler likes them a
-                  ;; lot. (We're telling the compiler about our
-                  ;; knowledge of specialized argument types so that
-                  ;; it can avoid run-time type dispatch overhead,
-                  ;; which can be a huge win for Python.)
-                  ;;
-                  ;; KLUDGE: when I tried moving these to
-                  ;; ADD-METHOD-DECLARATIONS, things broke.  No idea
-                  ;; why.  -- CSR, 2004-06-16
-                  ,@(mapcar #'parameter-specializer-declaration-in-defmethod
-                            parameters
-                            specializers)))
-               (method-lambda
-                ;; Remove the documentation string and insert the
-                ;; appropriate class declarations. The documentation
-                ;; string is removed to make it easy for us to insert
-                ;; new declarations later, they will just go after the
-                ;; CADR of the method lambda. The class declarations
-                ;; are inserted to communicate the class of the method's
-                ;; arguments to the code walk.
-                `(lambda ,lambda-list
-                   ;; The default ignorability of method parameters
-                   ;; doesn't seem to be specified by ANSI. PCL had
-                   ;; them basically ignorable but was a little
-                   ;; inconsistent. E.g. even though the two
-                   ;; method definitions
-                   ;;   (DEFMETHOD FOO ((X T) (Y T)) "Z")
-                   ;;   (DEFMETHOD FOO ((X T) Y) "Z")
-                   ;; are otherwise equivalent, PCL treated Y as
-                   ;; ignorable in the first definition but not in the
-                   ;; second definition. We make all required
-                   ;; parameters ignorable as a way of systematizing
-                   ;; the old PCL behavior. -- WHN 2000-11-24
-                   (declare (ignorable ,@required-parameters))
-                   ,class-declarations
-                   ,@declarations
-                   (block ,(fun-name-block-name generic-function-name)
-                     ,@real-body)))
-               (constant-value-p (and (null (cdr real-body))
-                                      (constantp (car real-body))))
-               (constant-value (and constant-value-p
-                                    (constant-form-value (car real-body))))
-               (plist (and constant-value-p
-                           (or (typep constant-value
-                                      '(or number character))
-                               (and (symbolp constant-value)
-                                    (symbol-package constant-value)))
-                           (list :constant-value constant-value)))
-               (applyp (dolist (p lambda-list nil)
-                         (cond ((memq p '(&optional &rest &key))
-                                (return t))
-                               ((eq p '&aux)
-                                (return nil))))))
-          (multiple-value-bind
-                (walked-lambda call-next-method-p closurep
-                               next-method-p-p setq-p
-                               parameters-setqd)
-              (walk-method-lambda method-lambda
-                                  required-parameters
-                                  env
-                                  slots
-                                  calls)
-            (multiple-value-bind (walked-lambda-body
-                                  walked-declarations
-                                  walked-documentation)
-                (parse-body (cddr walked-lambda))
-              (declare (ignore walked-documentation))
-              (when (some #'cdr slots)
-                (multiple-value-bind (slot-name-lists call-list)
-                    (slot-name-lists-from-slots slots calls)
-                  (setq plist
-                        `(,@(when slot-name-lists
-                                  `(:slot-name-lists ,slot-name-lists))
-                            ,@(when call-list
-                                    `(:call-list ,call-list))
-                            ,@plist))
-                  (setq walked-lambda-body
-                        `((pv-binding (,required-parameters
-                                       ,slot-name-lists
-                                       (load-time-value
-                                        (intern-pv-table
-                                         :slot-name-lists ',slot-name-lists
-                                         :call-list ',call-list)))
-                            ,@walked-lambda-body)))))
-              (when (and (memq '&key lambda-list)
-                         (not (memq '&allow-other-keys lambda-list)))
-                (let ((aux (memq '&aux lambda-list)))
-                  (setq lambda-list (nconc (ldiff lambda-list aux)
-                                           (list '&allow-other-keys)
-                                           aux))))
-              (values `(lambda (.method-args. .next-methods.)
-                         (simple-lexical-method-functions
-                             (,lambda-list .method-args. .next-methods.
-                                           :call-next-method-p
-                                           ,call-next-method-p
-                                           :next-method-p-p ,next-method-p-p
-                                           :setq-p ,setq-p
-                                           :method-cell ,method-cell
-                                           :closurep ,closurep
-                                           :applyp ,applyp)
-                           ,@walked-declarations
-                           (locally
-                               (declare (disable-package-locks
-                                         %parameter-binding-modified))
-                             (symbol-macrolet ((%parameter-binding-modified
-                                                ',@parameters-setqd))
-                               (declare (enable-package-locks
-                                         %parameter-binding-modified))
-                               ,@walked-lambda-body))))
-                      `(,@(when call-next-method-p `(method-cell ,method-cell))
-                        ,@(when plist `(plist ,plist))
-                        ,@(when documentation `(:documentation ,documentation)))))))))))
-
 (defmacro simple-lexical-method-functions ((lambda-list
                                             method-args
                                             next-methods
@@ -1017,7 +1016,7 @@ bootstrapping.
 
 (defstruct (fast-method-call (:copier nil))
   (function #'identity :type function)
-  pv-cell
+  pv
   next-method-call
   arg-info)
 (defstruct (constant-fast-method-call
@@ -1034,7 +1033,7 @@ bootstrapping.
 
 (defmacro invoke-fast-method-call (method-call restp &rest required-args+rest-arg)
   `(,(if restp 'apply 'funcall) (fast-method-call-function ,method-call)
-                                (fast-method-call-pv-cell ,method-call)
+                                (fast-method-call-pv ,method-call)
                                 (fast-method-call-next-method-call ,method-call)
                                 ,@required-args+rest-arg))
 
@@ -1044,7 +1043,7 @@ bootstrapping.
                                         &rest required-args)
   (macrolet ((generate-call (n)
                ``(funcall (fast-method-call-function ,method-call)
-                          (fast-method-call-pv-cell ,method-call)
+                          (fast-method-call-pv ,method-call)
                           (fast-method-call-next-method-call ,method-call)
                           ,@required-args
                           ,@(loop for x below ,n
@@ -1058,7 +1057,7 @@ bootstrapping.
        (0 ,(generate-call 0))
        (1 ,(generate-call 1))
        (t (multiple-value-call (fast-method-call-function ,method-call)
-            (values (fast-method-call-pv-cell ,method-call))
+            (values (fast-method-call-pv ,method-call))
             (values (fast-method-call-next-method-call ,method-call))
             ,@required-args
             (sb-c::%more-arg-values ,more-context 0 ,more-count))))))
@@ -1206,7 +1205,7 @@ bootstrapping.
             (nreq (car arg-info)))
        (if restp
            (apply (fast-method-call-function emf)
-                  (fast-method-call-pv-cell emf)
+                  (fast-method-call-pv emf)
                   (fast-method-call-next-method-call emf)
                   args)
            (cond ((null args)
@@ -1229,7 +1228,7 @@ bootstrapping.
                              :format-arguments nil)))
                  (t
                   (apply (fast-method-call-function emf)
-                         (fast-method-call-pv-cell emf)
+                         (fast-method-call-pv emf)
                          (fast-method-call-next-method-call emf)
                          args))))))
     (method-call
@@ -1435,7 +1434,7 @@ bootstrapping.
         when (eq key keyword)
           return tail))
 
-(defun walk-method-lambda (method-lambda required-parameters env slots calls)
+(defun walk-method-lambda (method-lambda required-parameters env slots)
   (let (;; flag indicating that CALL-NEXT-METHOD should be in the
         ;; method definition
         (call-next-method-p nil)
@@ -1498,7 +1497,7 @@ bootstrapping.
                           ;; another binding it won't have a %CLASS
                           ;; declaration anymore, and this won't get
                           ;; executed.
-                          (pushnew var parameters-setqd))))
+                          (pushnew var parameters-setqd :test #'eq))))
                     form)
                    ((and (eq (car form) 'function)
                          (cond ((eq (cadr form) 'call-next-method)
@@ -1512,15 +1511,12 @@ bootstrapping.
                                (t nil))))
                    ((and (memq (car form)
                                '(slot-value set-slot-value slot-boundp))
-                         (constantp (caddr form)))
-                    (let ((parameter (can-optimize-access form
-                                                          required-parameters
-                                                          env)))
-                      (let ((fun (ecase (car form)
-                                   (slot-value #'optimize-slot-value)
-                                   (set-slot-value #'optimize-set-slot-value)
-                                   (slot-boundp #'optimize-slot-boundp))))
-                        (funcall fun slots parameter form))))
+                         (constantp (caddr form) env))
+                    (let ((fun (ecase (car form)
+                                 (slot-value #'optimize-slot-value)
+                                 (set-slot-value #'optimize-set-slot-value)
+                                 (slot-boundp #'optimize-slot-boundp))))
+                        (funcall fun form slots required-parameters env)))
                    (t form))))
 
       (let ((walked-lambda (walk-form method-lambda env #'walk-function)))
@@ -1577,8 +1573,10 @@ bootstrapping.
                         (generic-function-methods gf)
                         (find-method gf qualifiers specializers nil))))
       (when method
-        (style-warn "redefining ~S~{ ~S~} ~S in DEFMETHOD"
-                    gf-spec qualifiers specializers))))
+        (style-warn 'sb-kernel:redefinition-with-defmethod
+                    :generic-function gf-spec :old-method method
+                    :qualifiers qualifiers :specializers specializers
+                    :new-location source-location))))
   (let ((method (apply #'add-named-method
                        gf-spec qualifiers specializers lambda-list
                        :definition-source source-location
@@ -1618,11 +1616,10 @@ bootstrapping.
           (set-fun-name mff fast-name))))
     (when plist
       (let ((plist plist))
-        (let ((snl (getf plist :slot-name-lists))
-              (cl (getf plist :call-list)))
-          (when (or snl cl)
+        (let ((snl (getf plist :slot-name-lists)))
+          (when snl
             (setf (method-plist-value method :pv-table)
-                  (intern-pv-table :slot-name-lists snl :call-list cl))))))))
+                  (intern-pv-table :slot-name-lists snl))))))))
 \f
 (defun analyze-lambda-list (lambda-list)
   (flet (;; FIXME: Is this redundant with SB-C::MAKE-KEYWORD-FOR-ARG?
@@ -1704,9 +1701,6 @@ bootstrapping.
                                     (when (or allow-other-keys-p old-allowp)
                                       '(&allow-other-keys)))))
                  *))))
-
-(defun defgeneric-declaration (spec lambda-list)
-  `(ftype ,(ftype-declaration-from-lambda-list lambda-list spec) ,spec))
 \f
 ;;;; early generic function support
 
@@ -1919,14 +1913,19 @@ bootstrapping.
   (aver (= (symbol-value (intern (format nil "*SM-~A-INDEX*" s)))
            (!bootstrap-slot-index 'standard-reader-method s)
            (!bootstrap-slot-index 'standard-writer-method s)
-           (!bootstrap-slot-index 'standard-boundp-method s))))
+           (!bootstrap-slot-index 'standard-boundp-method s)
+           (!bootstrap-slot-index 'global-reader-method s)
+           (!bootstrap-slot-index 'global-writer-method s)
+           (!bootstrap-slot-index 'global-boundp-method s))))
+
+(define-symbol-macro *standard-method-classes*
+  (list *the-class-standard-method* *the-class-standard-reader-method*
+        *the-class-standard-writer-method* *the-class-standard-boundp-method*
+        *the-class-global-reader-method* *the-class-global-writer-method*
+        *the-class-global-boundp-method*))
 
 (defun safe-method-specializers (method)
-  (let ((standard-method-classes
-         (list *the-class-standard-method*
-               *the-class-standard-reader-method*
-               *the-class-standard-writer-method*
-               *the-class-standard-boundp-method*))
+  (let ((standard-method-classes *standard-method-classes*)
         (class (class-of method)))
     (if (member class standard-method-classes)
         (clos-slots-ref (get-slots method) *sm-specializers-index*)
@@ -1936,21 +1935,13 @@ bootstrapping.
     (and (typep mf '%method-function)
          (%method-function-fast-function mf))))
 (defun safe-method-function (method)
-  (let ((standard-method-classes
-         (list *the-class-standard-method*
-               *the-class-standard-reader-method*
-               *the-class-standard-writer-method*
-               *the-class-standard-boundp-method*))
+  (let ((standard-method-classes *standard-method-classes*)
         (class (class-of method)))
     (if (member class standard-method-classes)
         (clos-slots-ref (get-slots method) *sm-%function-index*)
         (method-function method))))
 (defun safe-method-qualifiers (method)
-  (let ((standard-method-classes
-         (list *the-class-standard-method*
-               *the-class-standard-reader-method*
-               *the-class-standard-writer-method*
-               *the-class-standard-boundp-method*))
+  (let ((standard-method-classes *standard-method-classes*)
         (class (class-of method)))
     (if (member class standard-method-classes)
         (clos-slots-ref (get-slots method) *sm-qualifiers-index*)
@@ -2017,6 +2008,7 @@ bootstrapping.
                         (package (symbol-package symbol)))
                    (and (or (eq package *pcl-package*)
                             (memq package (package-use-list *pcl-package*)))
+                        (not (eq package #.(find-package "CL")))
                         ;; FIXME: this test will eventually be
                         ;; superseded by the *internal-pcl...* test,
                         ;; above.  While we are in a process of
@@ -2053,6 +2045,7 @@ bootstrapping.
                                                               lambda-list-p)
                                             argument-precedence-order
                                             source-location
+                                            documentation
                                             &allow-other-keys)
   (declare (ignore keys))
   (cond ((and existing (early-gf-p existing))
@@ -2062,7 +2055,8 @@ bootstrapping.
         ((assoc spec *!generic-function-fixups* :test #'equal)
          (if existing
              (make-early-gf spec lambda-list lambda-list-p existing
-                            argument-precedence-order source-location)
+                            argument-precedence-order source-location
+                            documentation)
              (bug "The function ~S is not already defined." spec)))
         (existing
          (bug "~S should be on the list ~S."
@@ -2070,10 +2064,12 @@ bootstrapping.
         (t
          (pushnew spec *!early-generic-functions* :test #'equal)
          (make-early-gf spec lambda-list lambda-list-p nil
-                        argument-precedence-order source-location))))
+                        argument-precedence-order source-location
+                        documentation))))
 
 (defun make-early-gf (spec &optional lambda-list lambda-list-p
-                      function argument-precedence-order source-location)
+                      function argument-precedence-order source-location
+                      documentation)
   (let ((fin (allocate-standard-funcallable-instance
               *sgf-wrapper* *sgf-slots-init*)))
     (set-funcallable-instance-function
@@ -2089,15 +2085,18 @@ bootstrapping.
                          has not been set." fin)))))
     (setf (gdefinition spec) fin)
     (!bootstrap-set-slot 'standard-generic-function fin 'name spec)
-    (!bootstrap-set-slot 'standard-generic-function
-                         fin
-                         'source
-                         source-location)
+    (!bootstrap-set-slot 'standard-generic-function fin
+                         'source source-location)
+    (!bootstrap-set-slot 'standard-generic-function fin
+                         '%documentation documentation)
     (set-fun-name fin spec)
     (let ((arg-info (make-arg-info)))
       (setf (early-gf-arg-info fin) arg-info)
       (when lambda-list-p
-        (proclaim (defgeneric-declaration spec lambda-list))
+        (setf (info :function :type spec)
+              (specifier-type
+               (ftype-declaration-from-lambda-list lambda-list spec))
+              (info :function :where-from spec) :defined-method)
         (if argument-precedence-order
             (set-arg-info fin
                           :lambda-list lambda-list
@@ -2217,7 +2216,10 @@ bootstrapping.
   (prog1
       (apply #'reinitialize-instance existing all-keys)
     (when lambda-list-p
-      (proclaim (defgeneric-declaration fun-name lambda-list)))))
+      (setf (info :function :type fun-name)
+            (specifier-type
+             (ftype-declaration-from-lambda-list lambda-list fun-name))
+            (info :function :where-from fun-name) :defined-method))))
 
 (defun real-ensure-gf-using-class--null
        (existing
@@ -2233,7 +2235,10 @@ bootstrapping.
             (apply #'make-instance generic-function-class
                    :name fun-name all-keys))
     (when lambda-list-p
-      (proclaim (defgeneric-declaration fun-name lambda-list)))))
+      (setf (info :function :type fun-name)
+            (specifier-type
+             (ftype-declaration-from-lambda-list lambda-list fun-name))
+            (info :function :where-from fun-name) :defined-method))))
 \f
 (defun safe-gf-arg-info (generic-function)
   (if (eq (class-of generic-function) *the-class-standard-generic-function*)
@@ -2268,7 +2273,8 @@ bootstrapping.
             arg-info)))
 
 (defun early-make-a-method (class qualifiers arglist specializers initargs doc
-                            &key slot-name object-class method-class-function)
+                            &key slot-name object-class method-class-function
+                            definition-source)
   (let ((parsed ())
         (unparsed ()))
     ;; Figure out whether we got class objects or class names as the
@@ -2309,13 +2315,15 @@ bootstrapping.
                         initargs doc)
                   (when slot-name
                     (list :slot-name slot-name :object-class object-class
-                          :method-class-function method-class-function))))))
+                          :method-class-function method-class-function))
+                  (list :definition-source definition-source)))))
       (initialize-method-function initargs result)
       result)))
 
 (defun real-make-a-method
        (class qualifiers lambda-list specializers initargs doc
-        &rest args &key slot-name object-class method-class-function)
+        &rest args &key slot-name object-class method-class-function
+        definition-source)
   (if method-class-function
       (let* ((object-class (if (classp object-class) object-class
                                (find-class object-class)))
@@ -2331,6 +2339,7 @@ bootstrapping.
           (apply #'make-instance
                  (apply method-class-function object-class slot-definition
                         initargs)
+                 :definition-source definition-source
                  initargs)))
       (apply #'make-instance class :qualifiers qualifiers
              :lambda-list lambda-list :specializers specializers
@@ -2389,7 +2398,9 @@ bootstrapping.
   (setf (fifth (fifth early-method)) new-value))
 
 (defun early-add-named-method (generic-function-name qualifiers
-                               specializers arglist &rest initargs)
+                               specializers arglist &rest initargs
+                               &key documentation definition-source
+                               &allow-other-keys)
   (let* (;; we don't need to deal with the :generic-function-class
          ;; argument here because the default,
          ;; STANDARD-GENERIC-FUNCTION, is right for all early generic
@@ -2403,7 +2414,8 @@ bootstrapping.
     (setf (getf (getf initargs 'plist) :name)
           (make-method-spec gf qualifiers specializers))
     (let ((new (make-a-method 'standard-method qualifiers arglist
-                              specializers initargs ())))
+                              specializers initargs documentation
+                              :definition-source definition-source)))
       (when existing (remove-method gf existing))
       (add-method gf new))))
 
@@ -2674,13 +2686,18 @@ bootstrapping.
 ;;; walker stuff was only used for implementing stuff like that; maybe
 ;;; it's not needed any more? Hunt down what it was used for and see.
 
+(defun extract-the (form)
+  (cond ((and (consp form) (eq (car form) 'the))
+         (aver (proper-list-of-length-p 3))
+         (third form))
+        (t
+         form)))
+
 (defmacro with-slots (slots instance &body body)
   (let ((in (gensym)))
     `(let ((,in ,instance))
        (declare (ignorable ,in))
-       ,@(let ((instance (if (and (consp instance) (eq (car instance) 'the))
-                             (third instance)
-                             instance)))
+       ,@(let ((instance (extract-the instance)))
            (and (symbolp instance)
                 `((declare (%variable-rebinding ,in ,instance)))))
        ,in
@@ -2702,9 +2719,7 @@ bootstrapping.
   (let ((in (gensym)))
     `(let ((,in ,instance))
        (declare (ignorable ,in))
-       ,@(let ((instance (if (and (consp instance) (eq (car instance) 'the))
-                             (third instance)
-                             instance)))
+       ,@(let ((instance (extract-the instance)))
            (and (symbolp instance)
                 `((declare (%variable-rebinding ,in ,instance)))))
        ,in