Subject: bug#22983: syntax-ppss returns wrong result.

From: Dmitry Gutov <[email-masked]>
Date: Fri, 11 Mar 2016 23:35:08 +0200

On 03/11/2016 11:24 PM, Alan Mackenzie wrote:

>> I think you mean that ppss-0 and ppss-1 must match independent of
>> narrowing, and also match (parse-partial-sexp 1 40000).
>
> Er no, I meant what I wrote: the result of (syntax-ppss pos) must match
> that of (parse-partial-sexp (point-min) pos).  I think ppss-0 and ppss-1
> did actually match (but I can't quite remember).

I imagine they didn't. I got the same value in all three cases, though, 
so your scenario could use some revising.

>> Considering narrowing can change point-min arbitrarily, specifying
>> (syntax-ppss pos) as (parse-partial-sexp (point-min) pos) is a losing
>> proposition if you want consistency.
>
> Indeed.  But that is how syntax-ppss is specified, and (partially) how
> it is implemented.

That part of specification can be rephrased.

>> Alas, we have some code out there that implements multiple-major-mode
>> functionality using narrowing and some hacking of syntax-ppss-last
>> syntax-ppss-cache values.
>
>> Changing syntax-ppss to be independent of narrowing will break it, and
>> we'll need to provide some alternative first.
>
> syntax-ppss is broken, and can't be fixed.

It's used ubiquitously, so it must be working.

> The only sensible fix would
> be to specify that (syntax-ppss pos) is the same as (parse-partial-sexp
> 1 pos).  But that is then a totally different function, and there are
> around 200 uses in the Emacs sources to check and fix, to say nothing of
> external code.

Not entirely different, no. AFAIK, these are the semantics the vast 
majority of its usages expect. Except the multiple-major-mode case, 
which we'd ideally try to accommodate, too.

>> We could introduce a syntax-ppss-dont-widen variable, though. Similar to
>> font-lock-dont-widen.
>
> I'm trying to figure that out.  Wouldn't that still leave you with
> problems when point-min is inside a string?

syntax-ppss-dont-widen would be nil by default, it would be an escape 
hatch toward the current semantics, for when the caller knows how to 
manage narrowings, etc.