Safely enforce thread name requirements · patricklam/verify-rust-std@c10a929 (original) (raw)

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

`

161

161

`use crate::any::Any;

`

162

162

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

`

163

163

`use crate::env;

`

164

``

`-

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

`

``

164

`+

use crate::ffi::CStr;

`

165

165

`use crate::fmt;

`

166

166

`use crate::io;

`

167

167

`use crate:📑:PhantomData;

`

`@@ -487,11 +487,7 @@ impl Builder {

`

487

487

` amt

`

488

488

`});

`

489

489

``

490

``

`-

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

`

495

491

`let their_thread = my_thread.clone();

`

496

492

``

497

493

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

`

`@@ -1273,10 +1269,34 @@ impl ThreadId {

`

1273

1269

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

``

1274

1270

`enum ThreadName {

`

1275

1271

`Main,

`

1276

``

`-

Other(CString),

`

``

1272

`+

Other(ThreadNameString),

`

1277

1273

`Unnamed,

`

1278

1274

`}

`

1279

1275

``

``

1276

`+

// 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 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

+

1280

1300

`` /// The internal representation of a Thread handle

``

1281

1301

`struct Inner {

`

1282

1302

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

`

`@@ -1316,10 +1336,7 @@ pub struct Thread {

`

1316

1336

``

1317

1337

`impl Thread {

`

1318

1338

`/// 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 {

`

1323

1340

`unsafe { Self::new_inner(ThreadName::Other(name)) }

`

1324

1341

`}

`

1325

1342

``