Subject: Re: bug#8646: byte-compile-initial-macro-environment confuses byte-compile-arglist-warn

From: Glenn Morris <[email-masked]>
Date: Wed, 11 May 2011 13:39:15 -0400

Stefan Monnier wrote:

> The "2+" vs "2-4" can be fixed by changing either the macro definition
> of its override so that their arglist matches.

No, really? ;)

I don't see how to change the override definition to not use &rest,
since it is a function that needs to distinguish "no argument" from
"argument nil". And changing the macro to match the override seems like
putting the cart before the horse.

How about the following, based on the idea that it is the override that
should be congruent with the real macro definition, even though the
former gets defined first? It's the reason that
byte-compile-macroexpand-declare-function can work.

*** lisp/emacs-lisp/bytecomp.el	2011-05-11 17:32:38 +0000
--- lisp/emacs-lisp/bytecomp.el	2011-05-11 17:35:51 +0000
***************
*** 1321,1327 ****
      ;; Assumes an element of b-c-i-macro-env that is a symbol points
      ;; to a defined function.  (Bug#8646)
      (and initial (symbolp initial)
!          (setq old (byte-compile-fdefinition initial nil)))
      (if (and old (not (eq old t)))
  	(progn
  	  (and (eq 'macro (car-safe old))
--- 1321,1328 ----
      ;; Assumes an element of b-c-i-macro-env that is a symbol points
      ;; to a defined function.  (Bug#8646)
      (and initial (symbolp initial)
!          (setq old (byte-compile-fdefinition initial nil)
!                initial 'yes))
      (if (and old (not (eq old t)))
  	(progn
  	  (and (eq 'macro (car-safe old))
***************
*** 1334,1340 ****
                           ((pred byte-code-function-p) (aref old 0))
                           (t '(&rest def)))))
  		(sig2 (byte-compile-arglist-signature (nth 2 form))))
! 	    (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2)
  	      (byte-compile-set-symbol-position name)
  	      (byte-compile-warn
  	       "%s %s used to take %s %s, now takes %s"
--- 1335,1345 ----
                           ((pred byte-code-function-p) (aref old 0))
                           (t '(&rest def)))))
  		(sig2 (byte-compile-arglist-signature (nth 2 form))))
! 	    ;; If something is on b-c-initial-m-e, *that* should be congruent
! 	    ;; with the normal (new) definition, not vice versa.
! 	    (unless (if (eq initial 'yes)
! 			(byte-compile-arglist-signatures-congruent-p sig2 sig1)
! 		      (byte-compile-arglist-signatures-congruent-p sig1 sig2))
  	      (byte-compile-set-symbol-position name)
  	      (byte-compile-warn
  	       "%s %s used to take %s %s, now takes %s"