Rollup merge of #127918 - ChrisDenton:thread-name-string, r=joboet · model-checking/verify-rust-std@2b62867

@@ -161,7 +161,7 @@ mod tests;

161161

use crate::any::Any;

162162

use crate::cell::{Cell, OnceCell, UnsafeCell};

163163

use crate::env;

164-

use crate::ffi::{CStr, CString};

164+

use crate::ffi::CStr;

165165

use crate::fmt;

166166

use crate::io;

167167

use 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);

495491

let their_thread = my_thread.clone();

496492497493

let my_packet: Arc<Packet<'scope, T>> = Arc::new(Packet {

@@ -1299,10 +1295,51 @@ impl ThreadId {

12991295

/// The internal representation of a `Thread`'s name.

13001296

enum ThreadName {

13011297

Main,

1302-

Other(CString),

1298+

Other(ThreadNameString),

13031299

Unnamed,

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

13071344

struct Inner {

13081345

name: ThreadName, // Guaranteed to be UTF-8

@@ -1342,25 +1379,20 @@ pub struct Thread {

1342137913431380

impl 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

}

1351138513521386

pub(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

13571391

pub(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]

14851517

pub 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

}

1488152014891521

fn 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