Subject: bug#21466: [PATCH] Avoid defining (temporarily) vars and functions

From: Stefan Kangas <[email-masked]>
Date: Wed, 06 Nov 2019 02:29:09 +0100

Stefan Monnier <[email-masked]> writes:

> Package: Emacs
> Version: 25.0.50
>
>
> CC-mode currently defines various non-CC-mode variables and functions
> with dummy values, as a way to avoid byte-compiler warnings when using
> those external vars/functions.
>
> Since this is dangerous business, CC-mode has to be extra careful to
> undo such settings when they're not needed any more.
>
> It might have made sense back in the days when the byte-compiler did not
> offer built-in ways to silence those warnings, but nowadays we can
> do better.
>
> Any objections to the patch below (which also removes the unused
> cc-bytecomp-put, while we're at it)?

Hi Alan,

This patch was sent to the bug list in 2015, but it seems like it
never got a reply at the time.

Assuming this patch is still relevant, could you please take a look?

Best regards,
Stefan Kangas

> 2015-09-12  Stefan Monnier  <[email-masked]>
>
> 	* lisp/progmodes/cc-bytecomp.el: Use newer compiler-silencers.
> 	(cc-bytecomp-defvar): Use just (defvar <foo>) when that is known to
> 	silence the byte-compiler warnings.
> 	(cc-bytecomp-defun): Use just (declare-function <foo>) when that is
> 	known to silence the byte-compiler warnings.
> 	(cc-bytecomp-boundp, cc-bytecomp-fboundp): Change accordingly.
> 	(cc-bytecomp-put): Remove, unused.
> 	(cc-bytecomp-original-properties): Remove var.
> 	(cc-bytecomp-setup-environment, cc-bytecomp-restore-environment):
> 	Don't use cc-bytecomp-original-properties any more.
>
>
> diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
> index 81b7a82..fff2a9e 100644
> --- a/lisp/progmodes/cc-bytecomp.el
> +++ b/lisp/progmodes/cc-bytecomp.el
> @@ -75,12 +75,10 @@
>  
>  (defvar cc-bytecomp-unbound-variables nil)
>  (defvar cc-bytecomp-original-functions nil)
> -(defvar cc-bytecomp-original-properties nil)
>  (defvar cc-bytecomp-loaded-files nil)
>  
>  (setq cc-bytecomp-unbound-variables nil)
>  (setq cc-bytecomp-original-functions nil)
> -(setq cc-bytecomp-original-properties nil)
>  (setq cc-bytecomp-loaded-files nil)
>  
>  (defvar cc-bytecomp-environment-set nil)
> @@ -173,16 +171,6 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
>  		  (cc-bytecomp-debug-msg
>  		   "cc-bytecomp-setup-environment: Covered function %s" fun))))
>  	  (setq p (cdr p)))
> -	(setq p cc-bytecomp-original-properties)
> -	(while p
> -	  (let ((sym (car (car (car p))))
> -		(prop (cdr (car (car p))))
> -		(tempdef (car (cdr (car p)))))
> -	    (put sym prop tempdef)
> -	    (cc-bytecomp-debug-msg
> -	     "cc-bytecomp-setup-environment: Bound property %s for %s to %s"
> -	     prop sym tempdef))
> -	  (setq p (cdr p)))
>  	(setq cc-bytecomp-environment-set t)
>  	(cc-bytecomp-debug-msg
>  	 "cc-bytecomp-setup-environment: Done"))))
> @@ -232,22 +220,6 @@ perhaps a `cc-bytecomp-restore-environment' is forgotten somewhere"))
>  		   "cc-bytecomp-restore-environment: Not restoring function %s"
>  		   fun))))
>  	  (setq p (cdr p)))
> -	(setq p cc-bytecomp-original-properties)
> -	(while p
> -	  (let ((sym (car (car (car p))))
> -		(prop (cdr (car (car p))))
> -		(tempdef (car (cdr (car p))))
> -		(origdef (cdr (cdr (car p)))))
> -	    (if (eq (get sym prop) tempdef)
> -		(progn
> -		  (put sym prop origdef)
> -		  (cc-bytecomp-debug-msg
> -		   "cc-bytecomp-restore-environment: Restored property %s for %s to %s"
> -		   prop sym origdef))
> -	      (cc-bytecomp-debug-msg
> -	       "cc-bytecomp-restore-environment: Not restoring property %s for %s"
> -	       prop sym)))
> -	  (setq p (cdr p)))
>  	(setq cc-bytecomp-environment-set nil)
>  	(cc-bytecomp-debug-msg
>  	 "cc-bytecomp-restore-environment: Done"))))
> @@ -348,25 +320,28 @@ afterwards.  Don't use within `eval-when-compile'."
>       (eval-when-compile (cc-bytecomp-setup-environment))))
>  
>  (defmacro cc-bytecomp-defvar (var)
> -  "Binds the symbol as a variable during compilation of the file,
> +  "Bind the symbol as a variable during compilation of the file,
>  to silence the byte compiler.  Don't use within `eval-when-compile'."
> -  `(eval-when-compile
> -     (if (boundp ',var)
> -	 (cc-bytecomp-debug-msg
> -	  "cc-bytecomp-defvar: %s bound already as variable" ',var)
> -       (if (not (memq ',var cc-bytecomp-unbound-variables))
> -	   (progn
> -	     (cc-bytecomp-debug-msg
> -	      "cc-bytecomp-defvar: Saving %s (as unbound)" ',var)
> -	     (setq cc-bytecomp-unbound-variables
> -		   (cons ',var cc-bytecomp-unbound-variables))))
> -       (if (cc-bytecomp-is-compiling)
> -	   (progn
> -	     (defvar ,var)
> -	     (set ',var (intern (concat "cc-bytecomp-ignore-var:"
> -					(symbol-name ',var))))
> -	     (cc-bytecomp-debug-msg
> -	      "cc-bytecomp-defvar: Covered variable %s" ',var))))))
> +  (if (not (featurep 'xemacs))
> +      `(defvar ,var)
> +    ;; Not sure if XEmacs's ‘defvar’ works in the same way.
> +    `(eval-when-compile
> +       (if (boundp ',var)
> +	   (cc-bytecomp-debug-msg
> +	    "cc-bytecomp-defvar: %s bound already as variable" ',var)
> +	 (if (not (memq ',var cc-bytecomp-unbound-variables))
> +	     (progn
> +	       (cc-bytecomp-debug-msg
> +		"cc-bytecomp-defvar: Saving %s (as unbound)" ',var)
> +	       (setq cc-bytecomp-unbound-variables
> +		     (cons ',var cc-bytecomp-unbound-variables))))
> +	 (if (cc-bytecomp-is-compiling)
> +	     (progn
> +	       (defvar ,var)
> +	       (set ',var (intern (concat "cc-bytecomp-ignore-var:"
> +					  (symbol-name ',var))))
> +	       (cc-bytecomp-debug-msg
> +		"cc-bytecomp-defvar: Covered variable %s" ',var)))))))
>  
>  (defmacro cc-bytecomp-defun (fun)
>    "Bind the symbol as a function during compilation of the file,
> @@ -377,48 +352,33 @@ definition.  That means that this macro will not shut up warnings
>  about incorrect number of arguments.  It's dangerous to try to replace
>  existing functions since the byte compiler might need the definition
>  at compile time, e.g. for macros and inline functions."
> -  `(eval-when-compile
> -     (if (fboundp ',fun)
> -	 (cc-bytecomp-debug-msg
> -	  "cc-bytecomp-defun: %s bound already as function" ',fun)
> -       (if (not (assq ',fun cc-bytecomp-original-functions))
> -	   (progn
> -	     (cc-bytecomp-debug-msg
> -	      "cc-bytecomp-defun: Saving %s (as unbound)" ',fun)
> -	     (setq cc-bytecomp-original-functions
> -		   (cons (list ',fun nil 'unbound)
> -			 cc-bytecomp-original-functions))))
> -       (if (cc-bytecomp-is-compiling)
> -	   (progn
> -	     (fset ',fun (intern (concat "cc-bytecomp-ignore-fun:"
> -					 (symbol-name ',fun))))
> -	     (cc-bytecomp-debug-msg
> -	      "cc-bytecomp-defun: Covered function %s" ',fun))))))
> -
> -(defmacro cc-bytecomp-put (symbol propname value)
> -  "Set a property on a symbol during compilation (and evaluation) of
> -the file.  Don't use outside `eval-when-compile'."
> -  `(eval-when-compile
> -     (if (not (assoc (cons ,symbol ,propname) cc-bytecomp-original-properties))
> -	 (progn
> +  (if (fboundp 'declare-function)
> +      `(declare-function ,fun nil)
> +    `(eval-when-compile
> +       (if (fboundp ',fun)
>  	   (cc-bytecomp-debug-msg
> -	    "cc-bytecomp-put: Saving property %s for %s with value %s"
> -	    ,propname ,symbol (get ,symbol ,propname))
> -	   (setq cc-bytecomp-original-properties
> -		 (cons (cons (cons ,symbol ,propname)
> -			     (cons ,value (get ,symbol ,propname)))
> -		       cc-bytecomp-original-properties))))
> -     (put ,symbol ,propname ,value)
> -     (cc-bytecomp-debug-msg
> -      "cc-bytecomp-put: Bound property %s for %s to %s"
> -      ,propname ,symbol ,value)))
> +	    "cc-bytecomp-defun: %s bound already as function" ',fun)
> +	 (if (not (assq ',fun cc-bytecomp-original-functions))
> +	     (progn
> +	       (cc-bytecomp-debug-msg
> +		"cc-bytecomp-defun: Saving %s (as unbound)" ',fun)
> +	       (setq cc-bytecomp-original-functions
> +		     (cons (list ',fun nil 'unbound)
> +			   cc-bytecomp-original-functions))))
> +	 (if (cc-bytecomp-is-compiling)
> +	     (progn
> +	       (fset ',fun (intern (concat "cc-bytecomp-ignore-fun:"
> +					   (symbol-name ',fun))))
> +	       (cc-bytecomp-debug-msg
> +		"cc-bytecomp-defun: Covered function %s" ',fun)))))))
>  
>  (defmacro cc-bytecomp-boundp (symbol)
>    "Return non-nil if the given symbol is bound as a variable outside
>  the compilation.  This is the same as using `boundp' but additionally
>  exclude any variables that have been bound during compilation with
>  `cc-bytecomp-defvar'."
> -  (if (and (cc-bytecomp-is-compiling)
> +  (if (and (featurep 'xemacs)
> +	   (cc-bytecomp-is-compiling)
>  	   (memq (car (cdr symbol)) cc-bytecomp-unbound-variables))
>        nil
>      `(boundp ,symbol)))
> @@ -429,7 +389,8 @@ the compilation.  This is the same as using `fboundp' but additionally
>  exclude any functions that have been bound during compilation with
>  `cc-bytecomp-defun'."
>    (let (fun-elem)
> -    (if (and (cc-bytecomp-is-compiling)
> +    (if (and (not (fboundp 'declare-function))
> +	     (cc-bytecomp-is-compiling)
>  	     (setq fun-elem (assq (car (cdr symbol))
>  				  cc-bytecomp-original-functions))
>  	     (eq (elt fun-elem 2) 'unbound))