Safely enforce thread name requirements · patricklam/verify-rust-std@c10a929
@@ -161,7 +161,7 @@ mod tests;
161161use crate::any::Any;
162162use crate::cell::{OnceCell, UnsafeCell};
163163use crate::env;
164-use crate::ffi::{CStr, CString};
164+use crate::ffi::CStr;
165165use crate::fmt;
166166use crate::io;
167167use crate::marker::PhantomData;
@@ -487,11 +487,7 @@ impl Builder {
487487 amt
488488});
489489490-let my_thread = name.map_or_else(Thread::new_unnamed, |name| unsafe {
491-Thread::new(
492-CString::new(name).expect("thread name may not contain interior null bytes"),
493-)
494-});
490+let my_thread = name.map_or_else(Thread::new_unnamed, |name| Thread::new(name.into()));
495491let their_thread = my_thread.clone();
496492497493let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
@@ -1273,10 +1269,34 @@ impl ThreadId {
12731269/// The internal representation of a `Thread`'s name.
12741270enum ThreadName {
12751271Main,
1276-Other(CString),
1272+Other(ThreadNameString),
12771273Unnamed,
12781274}
127912751276+// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
1277+mod thread_name_string {
1278+use crate::ffi::{CStr, CString};
1279+1280+/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
1281+ pub(crate) struct ThreadNameString {
1282+inner: CString,
1283+}
1284+impl core::ops::Deref for ThreadNameString {
1285+type Target = CStr;
1286+fn deref(&self) -> &CStr {
1287+&self.inner
1288+}
1289+}
1290+impl From<String> for ThreadNameString {
1291+fn from(s: String) -> Self {
1292+Self {
1293+inner: CString::new(s).expect("thread name may not contain interior null bytes"),
1294+}
1295+}
1296+}
1297+}
1298+pub(crate) use thread_name_string::ThreadNameString;
1299+12801300/// The internal representation of a `Thread` handle
12811301struct Inner {
12821302name: ThreadName, // Guaranteed to be UTF-8
@@ -1316,10 +1336,7 @@ pub struct Thread {
1316133613171337impl Thread {
13181338/// Used only internally to construct a thread object without spawning.
1319- ///
1320- /// # Safety
1321- /// `name` must be valid UTF-8.
1322- pub(crate) unsafe fn new(name: CString) -> Thread {
1339+ pub(crate) fn new(name: ThreadNameString) -> Thread {
13231340unsafe { Self::new_inner(ThreadName::Other(name)) }
13241341}
13251342