Subject: bug#23164: 25.1.50; xref-find-definitions with local tags-file-name fails

From: Dmitry Gutov <[email-masked]>
Date: Mon, 4 Apr 2016 04:29:30 +0300

Hi there!

On 03/30/2016 11:52 PM, Johan Claesson wrote:

> emacs -Q
>
> (fundamental-mode)
> (setq-local tags-file-name "/dev/zero")
> (xref-find-definitions "foo")
>
> Fails with (wrong-type-argument stringp nil) in
> visit-tags-table-buffer.

I do see the error with tags-file-name set to /dev/zero.

> The problem also occurs when tags-file-name points to a valid TAGS
> file (the invalid /dev/zero was chosen just to make the recipe
> short).

Thanks for the report, but that doesn't seem to be the case here. At 
least if I replace "/dev/zero" with "~/vc/emacs/src/TAGS", the scenario 
doesn't lead to an error (I just get "not found"), and if I also use 
e.g. "CALLN" instead of "foo", the jump to the destination occurs as 
expected.

To be 100% sure we're trying the same code, could you build Emacs from 
the branch emacs-25? Is there anything else you can tell us to help 
reproduce the problem?

> If tags-file-name have a global value there is no problem.
>
> It is the following line in visit-tags-table-buffer that fails.
>
>   (setq tags-file-name (tags-expand-table-name tags-file-name))
>
> If this is protected with (when tags-file-name ...) then the problem
> do not occur.  The same if the line is moved down and inside the
> unless sexp that follows immediately.  If either is the right thing to
> do i don't know.  But it seem a bit strange to assume that
> tags-file-name shall be non-nil at that point.

The preceding form tries to make sure to set it to the current value. 
Depending on the value of CONT, it will ask the user, use the current 
value, or delegate to some guessing logic. It's not 100% solid, though.

> The problem occurs
> when etags--xref-find-definitions calls visit-tags-table-buffer for
> the second time.

The assumption here is that the second time visit-tags-table-buffer is 
called from the tags file buffer. And that the previous invocation 
either set tags-file-name locally in that buffer, or at least set 
tags-table-list.