Rollup merge of #127918 - ChrisDenton:thread-name-string, r=joboet · model-checking/verify-rust-std@2b62867
@@ -161,7 +161,7 @@ mod tests;
161161use crate::any::Any;
162162use crate::cell::{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, Thread::new);
495491let their_thread = my_thread.clone();
496492497493let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {
@@ -1299,10 +1295,51 @@ impl ThreadId {
12991295/// The internal representation of a `Thread`'s name.
13001296enum ThreadName {
13011297Main,
1302-Other(CString),
1298+Other(ThreadNameString),
13031299Unnamed,
13041300}
130513011302+// This module ensures private fields are kept private, which is necessary to enforce the safety requirements.
1303+mod thread_name_string {
1304+use super::ThreadName;
1305+use crate::ffi::{CStr, CString};
1306+use core::str;
1307+1308+/// Like a `String` it's guaranteed UTF-8 and like a `CString` it's null terminated.
1309+ pub(crate) struct ThreadNameString {
1310+inner: CString,
1311+}
1312+impl core::ops::Deref for ThreadNameString {
1313+type Target = CStr;
1314+fn deref(&self) -> &CStr {
1315+&self.inner
1316+}
1317+}
1318+impl From<String> for ThreadNameString {
1319+fn from(s: String) -> Self {
1320+Self {
1321+inner: CString::new(s).expect("thread name may not contain interior null bytes"),
1322+}
1323+}
1324+}
1325+impl ThreadName {
1326+pub fn as_cstr(&self) -> Option<&CStr> {
1327+match self {
1328+ThreadName::Main => Some(c"main"),
1329+ThreadName::Other(other) => Some(other),
1330+ThreadName::Unnamed => None,
1331+}
1332+}
1333+1334+pub fn as_str(&self) -> Option<&str> {
1335+// SAFETY: `as_cstr` can only return `Some` for a fixed CStr or a `ThreadNameString`,
1336+// which is guaranteed to be UTF-8.
1337+self.as_cstr().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1338+}
1339+}
1340+}
1341+pub(crate) use thread_name_string::ThreadNameString;
1342+13061343/// The internal representation of a `Thread` handle
13071344struct Inner {
13081345name: ThreadName, // Guaranteed to be UTF-8
@@ -1342,25 +1379,20 @@ pub struct Thread {
1342137913431380impl Thread {
13441381/// Used only internally to construct a thread object without spawning.
1345- ///
1346- /// # Safety
1347- /// `name` must be valid UTF-8.
1348- pub(crate) unsafe fn new(name: CString) -> Thread {
1349-unsafe { Self::new_inner(ThreadName::Other(name)) }
1382+ pub(crate) fn new(name: String) -> Thread {
1383+Self::new_inner(ThreadName::Other(name.into()))
13501384}
1351138513521386pub(crate) fn new_unnamed() -> Thread {
1353-unsafe { Self::new_inner(ThreadName::Unnamed) }
1387+Self::new_inner(ThreadName::Unnamed)
13541388}
1355138913561390// Used in runtime to construct main thread
13571391pub(crate) fn new_main() -> Thread {
1358-unsafe { Self::new_inner(ThreadName::Main) }
1392+Self::new_inner(ThreadName::Main)
13591393}
136013941361-/// # Safety
1362- /// If `name` is `ThreadName::Other(_)`, the contained string must be valid UTF-8.
1363- unsafe fn new_inner(name: ThreadName) -> Thread {
1395+fn new_inner(name: ThreadName) -> Thread {
13641396// We have to use `unsafe` here to construct the `Parker` in-place,
13651397// which is required for the UNIX implementation.
13661398//
@@ -1483,15 +1515,11 @@ impl Thread {
14831515 #[stable(feature = "rust1", since = "1.0.0")]
14841516#[must_use]
14851517pub fn name(&self) -> Option<&str> {
1486-self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })
1518+self.inner.name.as_str()
14871519}
1488152014891521fn cname(&self) -> Option<&CStr> {
1490-match &self.inner.name {
1491-ThreadName::Main => Some(c"main"),
1492-ThreadName::Other(other) => Some(&other),
1493-ThreadName::Unnamed => None,
1494-}
1522+self.inner.name.as_cstr()
14951523}
14961524}
14971525