Skip to content

Commit 645c8a8

Browse files
author
The Miri Cronjob Bot
committed
Merge from rustc
2 parents 9ea9a3b + 3aefdd2 commit 645c8a8

File tree

9 files changed

+117
-42
lines changed

9 files changed

+117
-42
lines changed

core/src/any.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ impl TypeId {
742742
#[stable(feature = "rust1", since = "1.0.0")]
743743
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
744744
pub const fn of<T: ?Sized + 'static>() -> TypeId {
745-
let t: u128 = intrinsics::type_id::<T>();
745+
let t: u128 = const { intrinsics::type_id::<T>() };
746746
let t1 = (t >> 64) as u64;
747747
let t2 = t as u64;
748748

@@ -824,7 +824,7 @@ impl fmt::Debug for TypeId {
824824
#[stable(feature = "type_name", since = "1.38.0")]
825825
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
826826
pub const fn type_name<T: ?Sized>() -> &'static str {
827-
intrinsics::type_name::<T>()
827+
const { intrinsics::type_name::<T>() }
828828
}
829829

830830
/// Returns the type name of the pointed-to value as a string slice.

core/src/intrinsics/mod.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,10 @@ pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
839839
/// If the actual type neither requires drop glue nor implements
840840
/// `Copy`, then the return value of this function is unspecified.
841841
///
842-
/// Note that, unlike most intrinsics, this is safe to call;
843-
/// it does not require an `unsafe` block.
844-
/// Therefore, implementations must not require the user to uphold
845-
/// any safety invariants.
842+
/// Note that, unlike most intrinsics, this can only be called at compile-time
843+
/// as backends do not have an implementation for it. The only caller (its
844+
/// stable counterpart) wraps this intrinsic call in a `const` block so that
845+
/// backends only see an evaluated constant.
846846
///
847847
/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
848848
#[rustc_intrinsic_const_stable_indirect]
@@ -2655,10 +2655,10 @@ pub const fn align_of<T>() -> usize;
26552655
/// Returns the number of variants of the type `T` cast to a `usize`;
26562656
/// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
26572657
///
2658-
/// Note that, unlike most intrinsics, this is safe to call;
2659-
/// it does not require an `unsafe` block.
2660-
/// Therefore, implementations must not require the user to uphold
2661-
/// any safety invariants.
2658+
/// Note that, unlike most intrinsics, this can only be called at compile-time
2659+
/// as backends do not have an implementation for it. The only caller (its
2660+
/// stable counterpart) wraps this intrinsic call in a `const` block so that
2661+
/// backends only see an evaluated constant.
26622662
///
26632663
/// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`].
26642664
#[rustc_nounwind]
@@ -2694,10 +2694,10 @@ pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
26942694

26952695
/// Gets a static string slice containing the name of a type.
26962696
///
2697-
/// Note that, unlike most intrinsics, this is safe to call;
2698-
/// it does not require an `unsafe` block.
2699-
/// Therefore, implementations must not require the user to uphold
2700-
/// any safety invariants.
2697+
/// Note that, unlike most intrinsics, this can only be called at compile-time
2698+
/// as backends do not have an implementation for it. The only caller (its
2699+
/// stable counterpart) wraps this intrinsic call in a `const` block so that
2700+
/// backends only see an evaluated constant.
27012701
///
27022702
/// The stabilized version of this intrinsic is [`core::any::type_name`].
27032703
#[rustc_nounwind]
@@ -2709,10 +2709,10 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
27092709
/// function will return the same value for a type regardless of whichever
27102710
/// crate it is invoked in.
27112711
///
2712-
/// Note that, unlike most intrinsics, this is safe to call;
2713-
/// it does not require an `unsafe` block.
2714-
/// Therefore, implementations must not require the user to uphold
2715-
/// any safety invariants.
2712+
/// Note that, unlike most intrinsics, this can only be called at compile-time
2713+
/// as backends do not have an implementation for it. The only caller (its
2714+
/// stable counterpart) wraps this intrinsic call in a `const` block so that
2715+
/// backends only see an evaluated constant.
27162716
///
27172717
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
27182718
#[rustc_nounwind]

core/src/mem/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
616616
#[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")]
617617
#[rustc_diagnostic_item = "needs_drop"]
618618
pub const fn needs_drop<T: ?Sized>() -> bool {
619-
intrinsics::needs_drop::<T>()
619+
const { intrinsics::needs_drop::<T>() }
620620
}
621621

622622
/// Returns the value of type `T` represented by the all-zero byte-pattern.
@@ -1215,7 +1215,7 @@ pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
12151215
#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
12161216
#[rustc_diagnostic_item = "mem_variant_count"]
12171217
pub const fn variant_count<T>() -> usize {
1218-
intrinsics::variant_count::<T>()
1218+
const { intrinsics::variant_count::<T>() }
12191219
}
12201220

12211221
/// Provides associated constants for various useful properties of types,

core/src/primitive_docs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ mod prim_bool {}
316316
#[unstable(feature = "never_type", issue = "35121")]
317317
mod prim_never {}
318318

319+
// Required to make auto trait impls render.
320+
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
321+
#[doc(hidden)]
322+
impl ! {}
323+
319324
#[rustc_doc_primitive = "char"]
320325
#[allow(rustdoc::invalid_rust_codeblocks)]
321326
/// A character type.

std/src/sys/fs/windows/remove_dir_all.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use core::sync::atomic::{Atomic, AtomicU32, Ordering};
3333

3434
use super::{AsRawHandle, DirBuff, File, FromRawHandle};
3535
use crate::sys::c;
36-
use crate::sys::pal::api::WinError;
36+
use crate::sys::pal::api::{UnicodeStrRef, WinError, unicode_str};
3737
use crate::thread;
3838

3939
// The maximum number of times to spin when waiting for deletes to complete.
@@ -74,7 +74,7 @@ unsafe fn nt_open_file(
7474
/// `options` will be OR'd with `FILE_OPEN_REPARSE_POINT`.
7575
fn open_link_no_reparse(
7676
parent: &File,
77-
path: &[u16],
77+
path: UnicodeStrRef<'_>,
7878
access: u32,
7979
options: u32,
8080
) -> Result<Option<File>, WinError> {
@@ -90,9 +90,8 @@ fn open_link_no_reparse(
9090
static ATTRIBUTES: Atomic<u32> = AtomicU32::new(c::OBJ_DONT_REPARSE);
9191

9292
let result = unsafe {
93-
let mut path_str = c::UNICODE_STRING::from_ref(path);
9493
let mut object = c::OBJECT_ATTRIBUTES {
95-
ObjectName: &mut path_str,
94+
ObjectName: path.as_ptr(),
9695
RootDirectory: parent.as_raw_handle(),
9796
Attributes: ATTRIBUTES.load(Ordering::Relaxed),
9897
..c::OBJECT_ATTRIBUTES::with_length()
@@ -129,7 +128,7 @@ fn open_link_no_reparse(
129128
}
130129
}
131130

132-
fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
131+
fn open_dir(parent: &File, name: UnicodeStrRef<'_>) -> Result<Option<File>, WinError> {
133132
// Open the directory for synchronous directory listing.
134133
open_link_no_reparse(
135134
parent,
@@ -140,7 +139,7 @@ fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
140139
)
141140
}
142141

143-
fn delete(parent: &File, name: &[u16]) -> Result<(), WinError> {
142+
fn delete(parent: &File, name: UnicodeStrRef<'_>) -> Result<(), WinError> {
144143
// Note that the `delete` function consumes the opened file to ensure it's
145144
// dropped immediately. See module comments for why this is important.
146145
match open_link_no_reparse(parent, name, c::DELETE, 0) {
@@ -179,16 +178,17 @@ pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
179178
'outer: while let Some(dir) = dirlist.pop() {
180179
let more_data = dir.fill_dir_buff(&mut buffer, restart)?;
181180
for (name, is_directory) in buffer.iter() {
181+
let name = unicode_str!(&name);
182182
if is_directory {
183-
let Some(subdir) = open_dir(&dir, &name)? else { continue };
183+
let Some(subdir) = open_dir(&dir, name)? else { continue };
184184
dirlist.push(dir);
185185
dirlist.push(subdir);
186186
continue 'outer;
187187
} else {
188188
// Attempt to delete, retrying on sharing violation errors as these
189189
// can often be very temporary. E.g. if something takes just a
190190
// bit longer than expected to release a file handle.
191-
retry(|| delete(&dir, &name), WinError::SHARING_VIOLATION)?;
191+
retry(|| delete(&dir, name), WinError::SHARING_VIOLATION)?;
192192
}
193193
}
194194
if more_data {
@@ -197,7 +197,8 @@ pub fn remove_dir_all_iterative(dir: File) -> Result<(), WinError> {
197197
} else {
198198
// Attempt to delete, retrying on not empty errors because we may
199199
// need to wait some time for files to be removed from the filesystem.
200-
retry(|| delete(&dir, &[]), WinError::DIR_NOT_EMPTY)?;
200+
let name = unicode_str!("");
201+
retry(|| delete(&dir, name), WinError::DIR_NOT_EMPTY)?;
201202
restart = true;
202203
}
203204
}

std/src/sys/pal/windows/api.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
//! should go in sys/pal/windows/mod.rs rather than here. See `IoResult` as an example.
3131
3232
use core::ffi::c_void;
33+
use core::marker::PhantomData;
3334

3435
use super::c;
3536

@@ -291,3 +292,75 @@ impl WinError {
291292
pub const TIMEOUT: Self = Self::new(c::ERROR_TIMEOUT);
292293
// tidy-alphabetical-end
293294
}
295+
296+
/// A wrapper around a UNICODE_STRING that is equivalent to `&[u16]`.
297+
///
298+
/// It is preferable to use the `unicode_str!` macro as that contains mitigations for #143078.
299+
///
300+
/// If the MaximumLength field of the underlying UNICODE_STRING is greater than
301+
/// the Length field then you can test if the string is null terminated by inspecting
302+
/// the u16 directly after the string. You cannot otherwise depend on nul termination.
303+
#[derive(Copy, Clone)]
304+
pub struct UnicodeStrRef<'a> {
305+
s: c::UNICODE_STRING,
306+
lifetime: PhantomData<&'a [u16]>,
307+
}
308+
309+
static EMPTY_STRING_NULL_TERMINATED: &[u16] = &[0];
310+
311+
impl UnicodeStrRef<'_> {
312+
const fn new(slice: &[u16], is_null_terminated: bool) -> Self {
313+
let (len, max_len, ptr) = if slice.is_empty() {
314+
(0, 2, EMPTY_STRING_NULL_TERMINATED.as_ptr().cast_mut())
315+
} else {
316+
let len = slice.len() - (is_null_terminated as usize);
317+
(len * 2, size_of_val(slice), slice.as_ptr().cast_mut())
318+
};
319+
Self {
320+
s: c::UNICODE_STRING { Length: len as _, MaximumLength: max_len as _, Buffer: ptr },
321+
lifetime: PhantomData,
322+
}
323+
}
324+
325+
pub const fn from_slice_with_nul(slice: &[u16]) -> Self {
326+
if !slice.is_empty() {
327+
debug_assert!(slice[slice.len() - 1] == 0);
328+
}
329+
Self::new(slice, true)
330+
}
331+
332+
pub const fn from_slice(slice: &[u16]) -> Self {
333+
Self::new(slice, false)
334+
}
335+
336+
/// Returns a pointer to the underlying UNICODE_STRING
337+
pub const fn as_ptr(&self) -> *const c::UNICODE_STRING {
338+
&self.s
339+
}
340+
}
341+
342+
/// Create a UnicodeStringRef from a literal str or a u16 array.
343+
///
344+
/// To mitigate #143078, when using a literal str the created UNICODE_STRING
345+
/// will be nul terminated. The MaximumLength field of the UNICODE_STRING will
346+
/// be set greater than the Length field to indicate that a nul may be present.
347+
///
348+
/// If using a u16 array, the array is used exactly as provided and you cannot
349+
/// count on the string being nul terminated.
350+
/// This should generally be used for strings that come from the OS.
351+
///
352+
/// **NOTE:** we lack a UNICODE_STRING builder type as we don't currently have
353+
/// a use for it. If needing to dynamically build a UNICODE_STRING, the builder
354+
/// should try to ensure there's a nul one past the end of the string.
355+
pub macro unicode_str {
356+
($str:literal) => {const {
357+
crate::sys::pal::windows::api::UnicodeStrRef::from_slice_with_nul(
358+
crate::sys::pal::windows::api::wide_str!($str),
359+
)
360+
}},
361+
($array:expr) => {
362+
crate::sys::pal::windows::api::UnicodeStrRef::from_slice(
363+
$array,
364+
)
365+
}
366+
}

std/src/sys/pal/windows/c.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ pub fn nt_success(status: NTSTATUS) -> bool {
3737
status >= 0
3838
}
3939

40-
impl UNICODE_STRING {
41-
pub fn from_ref(slice: &[u16]) -> Self {
42-
let len = size_of_val(slice);
43-
Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
44-
}
45-
}
46-
4740
impl OBJECT_ATTRIBUTES {
4841
pub fn with_length() -> Self {
4942
Self {

std/src/sys/pal/windows/pipe.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
22
use crate::ops::Neg;
33
use crate::os::windows::prelude::*;
4-
use crate::sys::api::utf16;
5-
use crate::sys::c;
64
use crate::sys::handle::Handle;
5+
use crate::sys::{api, c};
76
use crate::sys_common::{FromInner, IntoInner};
87
use crate::{mem, ptr};
98

@@ -73,8 +72,8 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
7372
// Open a handle to the pipe filesystem (`\??\PIPE\`).
7473
// This will be used when creating a new annon pipe.
7574
let pipe_fs = {
76-
let path = c::UNICODE_STRING::from_ref(utf16!(r"\??\PIPE\"));
77-
object_attributes.ObjectName = &path;
75+
let path = api::unicode_str!(r"\??\PIPE\");
76+
object_attributes.ObjectName = path.as_ptr();
7877
let mut pipe_fs = ptr::null_mut();
7978
let status = c::NtOpenFile(
8079
&mut pipe_fs,
@@ -93,8 +92,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
9392

9493
// From now on we're using handles instead of paths to create and open pipes.
9594
// So set the `ObjectName` to a zero length string.
95+
// As a (perhaps overzealous) mitigation for #143078, we use the null pointer
96+
// for empty.Buffer instead of unicode_str!("").
97+
// There's no difference to the OS itself but it's possible that third party
98+
// DLLs which hook in to processes could be relying on the exact form of this string.
9699
let empty = c::UNICODE_STRING::default();
97-
object_attributes.ObjectName = &empty;
100+
object_attributes.ObjectName = &raw const empty;
98101

99102
// Create our side of the pipe for async access.
100103
let ours = {

stdarch/crates/intrinsic-test/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ USAGE:
77
intrinsic-test [FLAGS] [OPTIONS] <INPUT>
88
99
FLAGS:
10-
--a32 Run tests for A32 instrinsics instead of A64
10+
--a32 Run tests for A32 intrinsics instead of A64
1111
--generate-only Regenerate test programs, but don't build or run them
1212
-h, --help Prints help information
1313
-V, --version Prints version information

0 commit comments

Comments
 (0)