Skip to content

Commit b0a8543

Browse files
authored
Fix new safety.
1 parent 2fd14ca commit b0a8543

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

library/core/src/escape.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,43 +176,51 @@ pub(crate) struct MaybeEscaped;
176176
#[derive(Clone)]
177177
pub(crate) struct EscapeIterInner<const N: usize, ESCAPING> {
178178
// The element type ensures this is always ASCII, and thus also valid UTF-8.
179-
// Invariant: `N < 128`. For non-printable characters, contains the escaped
179+
// Invariant: For non-printable characters, contains the escaped
180180
// representation as ASCII characters. For printable characters, contains the
181181
// character itself.
182182
data: MaybeEscapedCharacter<N>,
183183

184-
// Invariant: For non-printable characters, `alive.start <= alive.end <= N`,
184+
// Invariant: For non-printable characters, `alive.start <= alive.end <= N <= 127`,
185185
// for printable characters, `128 <= alive.start <= alive.end`.
186186
alive: Range<u8>,
187187

188188
escaping: PhantomData<ESCAPING>,
189189
}
190190

191191
impl<const N: usize, ESCAPING> EscapeIterInner<N, ESCAPING> {
192+
/// # Safety
193+
///
194+
/// `data.escape_seq` must contain an escape sequence in the range given by `alive`.
192195
#[inline]
193-
const fn new(data: MaybeEscapedCharacter<N>, alive: Range<u8>) -> Self {
194-
const { assert!(N < 128) };
196+
unsafe const fn new(data: MaybeEscapedCharacter<N>, alive: Range<u8>) -> Self {
197+
// Uphold the `alive` invariant for non-printable characters.
198+
const { assert!(N <= 127) };
195199
Self { data, alive, escaping: PhantomData }
196200
}
197201

198202
pub(crate) const fn backslash(c: ascii::Char) -> Self {
199203
let (data, range) = backslash(c);
200-
Self::new(MaybeEscapedCharacter { escape_seq: data }, range)
204+
// SAFETY: `data` contains an escape sequence in the range given by `range`.
205+
unsafe { Self::new(MaybeEscapedCharacter { escape_seq: data }, range) }
201206
}
202207

203208
pub(crate) const fn ascii(c: u8) -> Self {
204209
let (data, range) = escape_ascii(c);
205-
Self::new(MaybeEscapedCharacter { escape_seq: data }, range)
210+
// SAFETY: `data` contains an escape sequence in the range given by `range`.
211+
unsafe { Self::new(MaybeEscapedCharacter { escape_seq: data }, range) }
206212
}
207213

208214
pub(crate) const fn unicode(c: char) -> Self {
209215
let (data, range) = escape_unicode(c);
210-
Self::new(MaybeEscapedCharacter { escape_seq: data }, range)
216+
// SAFETY: `data` contains an escape sequence in the range given by `range`.
217+
unsafe { Self::new(MaybeEscapedCharacter { escape_seq: data }, range) }
211218
}
212219

213220
#[inline]
214221
pub(crate) const fn empty() -> Self {
215-
Self::new(MaybeEscapedCharacter { escape_seq: [ascii::Char::Null; N] }, 0..0)
222+
// SAFETY: `0..0` ensures an empty escape sequence.
223+
unsafe { Self::new(MaybeEscapedCharacter { escape_seq: [ascii::Char::Null; N] }, 0..0) }
216224
}
217225

218226
/// # Safety

0 commit comments

Comments
 (0)