Subject: bug#46813: 27.0.91; Form `(subdirs . nil)' in .dir-locals.el does not protect subdirectories

From: Sebastian Tennant <[email-masked]>
Date: Sat, 27 Feb 2021 13:59:19 +0000

Steps to reproduce:

 1. $ emacs -Q

 2. M-x ielm RET

 3. ELISP> (mkdir "tmp/sub" 'parents)
    nil

 4. ELISP> (with-temp-file "tmp/.dir-locals.el"
             (insert "((nil . ((foo . bar) (subdirs . nil))))\n"))
    nil

 5. ELISP> (with-temp-file "tmp/sub/baz" (insert "quux"))
    nil

 6. ELISP> (find-file "tmp/sub/baz")
    #<buffer baz>

According to the sexp written to file tmp/.dir-locals.el in 4, variable
`foo' should only be bound to `bar' in files under tmp/.  However, when
file tmp/sub/baz is visited in 6, the local variables list includes the
binding 'foo : bar', deemed to be risky.

The relevant section of (info "(emacs) Directory Variables") reads:

 "The special ‘subdirs’ element is not a variable, but a special keyword
 which indicates that the [...] settings are only to be applied in the
 current directory, not in any subdirectories."

Bug, documentation bug or thinko?

In GNU Emacs 27.0.91 (build 2, x86_64-pc-linux-gnu)
 of 2021-02-26 built on latignude
Repository revision: 0278741676e2eca89ecf085344be6bc4fd586396
Repository branch: emacs-27
System Description: Debian GNU/Linux 10 (buster)

Configured using:
 'configure -C --prefix=/home/sebyte/emacs/emacs-27
 --enable-check-lisp-object-type --disable-acl --without-dbus
 --without-gconf --without-gif --without-gsettings --without-jpeg
 --without-png --without-rsvg --without-selinux --without-sound
 --without-tiff --without-x --without-xpm'

Configured features:
GPM NOTIFY INOTIFY GNUTLS LIBXML2 ZLIB XIM MODULES THREADS LIBSYSTEMD
JSON PDUMPER LCMS2 GMP

Important settings:
  value of $LC_COLLATE: POSIX
  value of $LC_TIME: POSIX
  value of $LANG: en_GB.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Emacs-Lisp

Minor modes in effect:
  c5-mode: t
  shell-dirtrack-mode: t
  save-place-mode: t
  global-hi-lock-mode: t
  hi-lock-mode: t
  winner-mode: t
  savehist-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  electric-indent-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t

Load-path shadows:
/home/sebyte/emacs/src-emacs-27/lisp/obsolete/iswitchb hides /home/sebyte/elisp/load-path-appended/lib/iswitchb
/home/sebyte/emacs/src-emacs-27/lisp/misc hides /home/sebyte/elisp/load-path-appended/lib/misc

Features:
(pulse misearch multi-isearch find-lisp texinfo add-log vc-git
bug-reference shadow sort mail-extr emacsbug message rmc puny rfc822 mml
mml-sec epa epg epg-config gnus-util rmail rmail-loaddefs
text-property-search mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util mail-prsvr mail-utils dired-aux eieio-opt speedbar sb-image
ezimage image dframe ielm find-dired grep debug backtrace find-func
mule-util info cl-print help-fns radix-tree vc-svn vc-fossil vc
vc-dispatcher pb term disp-table ehelp rvlc ucs-hacks quail svnhacks
svndirs rsync mashfile-mode pcase sh-script smie executable rx c5
ifi-loaddefs psvn tramp tramp-loaddefs trampver tramp-integration
files-x tramp-compat shell pcomplete parse-time iso8601 time-date
ls-lisp format-spec server smerge-mode diff-mode diff ffap dired-x dired
dired-loaddefs anaphora slime-fancy slime-indentation slime-cl-indent
cl-indent slime-trace-dialog slime-fontifying-fu slime-package-fu
slime-references slime-compiler-notes-tree slime-scratch
slime-presentations advice bridge slime-macrostep macrostep
slime-mdot-fu slime-enclosing-context slime-fuzzy slime-fancy-trace
slime-fancy-inspector slime-c-p-c slime-editing-commands slime-autodoc
slime-repl elp slime-parse slime derived cl-extra help-mode edmacro
kmacro lisp-mnt gud apropos compile tool-bar etags fileloop generator
xref project arc-mode archive-mode noutline outline easy-mmode pp comint
regexp-opt ansi-color hyperspec thingatpt cl slime-autoloads saveplace
hi-lock winner ring savehist package easymenu browse-url url-handlers
url-parse auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs
password-cache json subr-x map url-vars seq byte-opt gv bytecomp
byte-compile cconv cl-loaddefs cl-lib tooltip eldoc electric uniquify
ediff-hook vc-hooks lisp-float-type tabulated-list replace newcomment
text-mode elisp-mode lisp-mode prog-mode register page tab-bar menu-bar
rfn-eshadow isearch timer select mouse jit-lock font-lock syntax
facemenu font-core term/tty-colors frame minibuffer cl-generic cham
georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite charscript charprop
case-table epa-hook jka-cmpr-hook help simple abbrev obarray
cl-preloaded nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote threads inotify lcms2
multi-tty make-network-process emacs)

Memory information:
((conses 16 281388 39472)
 (symbols 48 20552 1)
 (strings 32 71994 5103)
 (string-bytes 1 2079872)
 (vectors 16 31989)
 (vector-slots 8 1145219 166804)
 (floats 8 126 292)
 (intervals 56 1454 559)
 (buffers 1000 76))