Skip to content

Commit b65dfb5

Browse files
committed
Implement proc macro literal escaping without unstable Utf8Chunks
1 parent ccf4cc5 commit b65dfb5

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

library/proc_macro/src/escape.rs

+53-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::fmt::Write as _;
2-
use std::str::Utf8Chunks;
2+
use std::str;
33

44
#[derive(Copy, Clone)]
55
pub(crate) struct EscapeOptions {
@@ -58,3 +58,55 @@ fn escape_single_char(ch: char, opt: EscapeOptions, repr: &mut String) {
5858
write!(repr, "{}", ch.escape_debug()).unwrap();
5959
}
6060
}
61+
62+
// FIXME: delete this and use std::str::Utf8Chunks once that is stable.
63+
// https://github.com/rust-lang/rust/issues/99543
64+
// Mentioning the feature name so this comes up in search during stabilization:
65+
// #![feature(utf8_chunks)]
66+
struct Utf8Chunks<'a> {
67+
bytes: &'a [u8],
68+
}
69+
70+
impl<'a> Utf8Chunks<'a> {
71+
fn new(bytes: &'a [u8]) -> Self {
72+
Utf8Chunks { bytes }
73+
}
74+
}
75+
76+
impl<'a> Iterator for Utf8Chunks<'a> {
77+
type Item = Utf8Chunk<'a>;
78+
79+
fn next(&mut self) -> Option<Utf8Chunk<'a>> {
80+
if self.bytes.is_empty() {
81+
return None;
82+
}
83+
84+
let (valid, invalid) = match str::from_utf8(self.bytes) {
85+
Ok(all_valid) => (all_valid, b"" as &[u8]),
86+
Err(utf8_error) => {
87+
let (valid, rest) = self.bytes.split_at(utf8_error.valid_up_to());
88+
let valid = str::from_utf8(valid).unwrap();
89+
let invalid = utf8_error.error_len().map_or(rest, |error_len| &rest[..error_len]);
90+
(valid, invalid)
91+
}
92+
};
93+
94+
self.bytes = &self.bytes[valid.len() + invalid.len()..];
95+
Some(Utf8Chunk { valid, invalid })
96+
}
97+
}
98+
99+
struct Utf8Chunk<'a> {
100+
valid: &'a str,
101+
invalid: &'a [u8],
102+
}
103+
104+
impl<'a> Utf8Chunk<'a> {
105+
fn valid(&self) -> &'a str {
106+
self.valid
107+
}
108+
109+
fn invalid(&self) -> &'a [u8] {
110+
self.invalid
111+
}
112+
}

library/proc_macro/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#![feature(rustc_attrs)]
3535
#![feature(min_specialization)]
3636
#![feature(strict_provenance)]
37-
#![feature(utf8_chunks)]
3837
#![recursion_limit = "256"]
3938
#![allow(internal_features)]
4039
#![deny(ffi_unwind_calls)]

0 commit comments

Comments
 (0)