Subject: 27.2; `face-remap-set-base' bug with only two args

From: Drew Adams <[email-masked]>
Date: Tue, 22 Feb 2022 17:47:33 +0000

(I see the same problem (same code) in an Emacs 28 pretest snapshot.)

emacs -Q

Eval the source-code defun of `face-remap-set-base'.

M-x debug-on-entry face-remap-set-base

Evaluate (face-remap-set-base 'variable-pitch 'default).

Debugger entered--Lisp error: (wrong-type-argument listp default)
* car(default)
* (eq (car specs) face)
* (and (eq (car specs) face) (null (cdr specs)))
* (or (null specs) (and (eq (car specs) face) (null (cdr specs))))
* (if (or (null specs) (and (eq (car specs) face) (null (cdr specs)))) (face-remap-reset-base face) (make-local-variable 'face-remapping-alist) (let ((entry (assq face face-remapping-alist))) (if entry (setcar (last entry) specs) (setq face-remapping-alist (cons (list face specs) face-remapping-alist)))) (force-mode-line-update))
* (closure (t) (face &rest specs) "Set the base remapping of FACE in the current buff..." (while (and (consp specs) (not (null (car specs))) (null (cdr specs))) (setq specs (car specs))) (if (or (null specs) (and (eq (car specs) face) (null (cdr specs)))) (face-remap-reset-base face) (make-local-variable 'face-remapping-alist) (let ((entry (assq face face-remapping-alist))) (if entry (setcar (last entry) specs) (setq face-remapping-alist (cons (list face specs) face-remapping-alist)))) (force-mode-line-update)))(variable-pitch default)
* apply((closure (t) (face &rest specs) "Set the base remapping of FACE in the current buff..." (while (and (consp specs) (not (null (car specs))) (null (cdr specs))) (setq specs (car specs))) (if (or (null specs) (and (eq (car specs) face) (null (cdr specs)))) (face-remap-reset-base face) (make-local-variable 'face-remapping-alist) (let ((entry (assq face face-remapping-alist))) (if entry (setcar (last entry) specs) (setq face-remapping-alist (cons (list face specs) face-remapping-alist)))) (force-mode-line-update))) (variable-pitch default))
* face-remap-set-base(variable-pitch default)
  (progn (face-remap-set-base 'variable-pitch 'default))
  eval((progn (face-remap-set-base 'variable-pitch 'default)) t)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

Should the test perhaps be this:

(if (or (null specs) (eq specs face)) ; default

instead of this?

(if (or (null specs)
	(and (eq (car specs) face)
        (null (cdr specs)))) ; default

In GNU Emacs 27.2 (build 1, x86_64-w64-mingw32)
 of 2021-03-26 built on CIRROCUMULUS
Repository revision: deef5efafb70f4b171265b896505b92b6eef24e6
Repository branch: HEAD
Windowing system distributor 'Microsoft Corp.', version 10.0.19043
System Description: Microsoft Windows 10 Pro (v10.0.2009.19043.1526)