1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Parser-combinator-style scanner for a cooked Rust string literal's
//! body. Each `take_*` function follows the convention in
//! `planned-rules/IMPLEMENTATION_CONVENTIONS.md`: consume a recognised
//! prefix from the input and return the rest, or `None` if the input
//! doesn't start with that shape.
//!
//! The walk decides whether a literal contains *only* escapes that a
//! raw string would express verbatim (`\"`, `\\`, `\'`). A single
//! escape outside that set — `\n`, `\t`, `\xNN`, `\u{...}`, line
//! continuations — makes the whole literal ineligible. The generic
//! "take any backslash escape" step is the crate-internal
//! [`crate::literal_scan::take_string_escape`]; this module layers the
//! eligible-escape recognition on top.
/// Default eligible escape sequences: the three escapes that a raw
/// string can express verbatim with no escape at all. Also used as
/// the closed set against which user-supplied `eligible_escapes`
/// entries are validated.
pub const DEFAULT_ELIGIBLE_ESCAPES: & = &;
pub
/// Walk the body of a cooked string literal (everything between the
/// surrounding quotes) and classify each escape. Returns `None` if
/// the body contains any non-raw escape — `\n`, `\t`, `\r`, `\0`,
/// `\xNN`, `\u{...}`, line continuations, or any other backslash
/// sequence that is not listed in the configured `eligible_escapes`.
pub
/// Take a prefix of `input` that matches one of the configured
/// eligible escape sequences. Each entry is matched literally
/// against the input — no decoding, no normalisation. Entries
/// reach this function only after [`is_supported_eligible_entry`]
/// has accepted them, so they are non-empty by construction.
/// Decode an eligible escape into the verbatim text it represents
/// in a raw string. Eligible entries are constrained to the three
/// self-decoding escapes by [`is_supported_eligible_entry`], so the
/// decoded form is exactly the entry with its leading backslash
/// removed.
/// Take a single non-backslash UTF-8 character from the front of
/// `input`. Returns `None` only when `input` is empty or starts with
/// `\`, in which case the caller should run one of the escape
/// combinators first.
/// Build the raw-string replacement for a decoded literal body: the
/// `r`-prefixed form with the smallest hash count that avoids a
/// delimiter collision. Shared by the late `ExprKind::Lit` pass and the
/// pre-expansion `format!`-template pass so the two emit byte-identical
/// suggestions.
pub
/// Smallest number of `#` characters needed so that the closing
/// `"<n #s>` sequence does not appear inside `decoded`.
///
/// In practice this is 0 for paths and 1 for JSON / HTML snippets;
/// longer runs only matter when the literal itself embeds
/// raw-string source text.
pub
/// A supported `eligible_escapes` entry is one of the three Rust
/// escapes that self-decode — that is, whose decoded character is
/// exactly the byte that follows the backslash: `\"`, `\\`, `\'`.
/// [`eliminable_decoded`]'s contract is "strip the leading backslash",
/// which only holds for these three. Every other valid Rust escape
/// (`\n`, `\t`, `\r`, `\0`, `\xNN`, `\u{...}`) decodes to a
/// different character, so accepting it here would let the autofix
/// silently corrupt strings — e.g. `eligible_escapes = ["\\n"]`
/// would rewrite a newline-containing literal to one containing the
/// letter `n`.
///
/// The supported set is the same one named by
/// [`DEFAULT_ELIGIBLE_ESCAPES`]; matching against that constant
/// keeps the two definitions from drifting apart if a future
/// extension to [`eliminable_decoded`] ever adds a fourth entry.
pub