Subject: 28.1.50; completion--replace illegally mutates completion candidates

From: Daniel Mendler <[email-masked]>
Date: Sun, 1 May 2022 10:27:56 +0200

The function completion--replace mutates the replacement string, it
strips the text properties. The command minibuffer-force-complete calls
(completion--replace base end (car all)) on the first candidate returned
by completion-all-sorted-completions, which then affects the candidate
strings passed to completing-read. The candidate strings passed to
completing-read should be treated as constant and should not be mutated.

There are two possibilities to fix this:

1. Copy the string (with concat or substring) before mutating it in
completion--replace. This is the preferred solution and will make
completion--replace safer to use.
2. Copy the candidate string just before passing it to
completion--replace. This is the approach I take for example in my Corfu
package and I will continue to do so for backward compatibility. Still,
the pattern is error prone and copying the candidate string is easily
forgotten, (completion--replace beg end (concat cand)).

Original downstream issue: https://github.com/minad/consult/issues/566

In GNU Emacs 28.1.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
version 1.16.0, Xaw scroll bars)
 of 2022-04-29 built on projects
Repository revision: 3b6338c8c351cce721f2f1aa115cadc401179d5c
Repository branch: emacs-28
Windowing system distributor 'The X.Org Foundation', version 11.0.12004000
System Description: Debian GNU/Linux 10 (buster)