(I couldn't send this immediately and now I see Bart already replied but maybe my example is still useful)
A few hours ago, by an incredible coincidence, I stumbled on
this code. I couldn’t make much sense of it but when I read your question I remembered that it contained something about named directories. After a closer look, I figured that it must be the code responsible of restoring a named directory when a local parameter goes out of scope and an enclosing parameter pointing to a directory becomes visible again.
Looking at your example, I think that it's working as intended. The problem is that "hash -d nm=/a/path" only defines a named directory "nm". It does NOT define any (global) parameter "nm". Therefore there is nothing to restore to when the function is exited. Here is an example that illustrates the problem:
#!/bin/zsh -i
setopt autonamedirs
show-state() {
printf "%-6s: nameddirs=(%-21s) nm1=%s nm2=%s\n" \
$1 "${(kv)nameddirs}" ${nm1-<undef>} ${nm2-<undef>}
}
local nm1=/1/aaa
hash -d nm2=/2/aaa
show-state before
local-nms() {
local nm1=/1/zzz
local nm2=/2/zzz
show-state inside
}
local-nms
show-state after
Output
before: nameddirs=(nm1 /1/aaa nm2 /2/aaa) nm1=/1/aaa nm2=<undef>
inside: nameddirs=(nm1 /1/zzz nm2 /2/zzz) nm1=/1/zzz nm2=/2/zzz
after : nameddirs=(nm1 /1/aaa ) nm1=/1/aaa nm2=<undef>
Notice that "nm1" is correctly restored to "/1/aaa" when "local-nms" exits. That's what the code I mentioned above does thanks to the presence of the global parameter "nm1". For "nm2", since there is no global parameter "nm2". Therefore, there is nothing to restore when "local-nms" exits and the named directory "nm2" gets removed when the local parameter "nm2" goes out of scope.
If you run the code without -i, then the parameters don't create named directories and the named directory "nm2" created by "hash -d nm2=/2/aaa" remains unchanged during the whole script.
Output without -i
before: nameddirs=(nm2 /2/aaa ) nm1=/1/aaa nm2=<undef>
inside: nameddirs=(nm2 /2/aaa ) nm1=/1/zzz nm2=/2/zzz
after : nameddirs=(nm2 /2/aaa ) nm1=/1/aaa nm2=<undef>
Philippe