Skip to content

Commit 00bf74d

Browse files
committed
Auto merge of rust-lang#134631 - matthiaskrgr:rollup-mkql5pl, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#131072 (Win: Use POSIX rename semantics for `std::fs::rename` if available) - rust-lang#134325 (Correctly document CTFE behavior of is_null and methods that call is_null.) - rust-lang#134526 (update `rustc_index_macros` feature handling) - rust-lang#134581 (Bump Fuchsia toolchain for testing) - rust-lang#134607 (on pair → on par) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 426d173 + 0cfabd5 commit 00bf74d

File tree

12 files changed

+295
-26
lines changed

12 files changed

+295
-26
lines changed

compiler/rustc_index/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
# tidy-alphabetical-start
8-
rustc_index_macros = { path = "../rustc_index_macros", default-features = false }
8+
rustc_index_macros = { path = "../rustc_index_macros" }
99
rustc_macros = { path = "../rustc_macros", optional = true }
1010
rustc_serialize = { path = "../rustc_serialize", optional = true }
1111
smallvec = "1.8.1"

compiler/rustc_index_macros/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,4 @@ proc-macro2 = "1"
1212
quote = "1"
1313

1414
[features]
15-
default = ["nightly"]
1615
nightly = []

library/core/src/ptr/const_ptr.rs

+31-7
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ impl<T: ?Sized> *const T {
1212
/// Therefore, two pointers that are null may still not compare equal to
1313
/// each other.
1414
///
15-
/// ## Behavior during const evaluation
15+
/// # Panics during const evaluation
1616
///
17-
/// When this function is used during const evaluation, it may return `false` for pointers
18-
/// that turn out to be null at runtime. Specifically, when a pointer to some memory
19-
/// is offset beyond its bounds in such a way that the resulting pointer is null,
20-
/// the function will still return `false`. There is no way for CTFE to know
21-
/// the absolute position of that memory, so we cannot tell if the pointer is
22-
/// null or not.
17+
/// If this method is used during const evaluation, and `self` is a pointer
18+
/// that is offset beyond the bounds of the memory it initially pointed to,
19+
/// then there might not be enough information to determine whether the
20+
/// pointer is null. This is because the absolute address in memory is not
21+
/// known at compile time. If the nullness of the pointer cannot be
22+
/// determined, this method will panic.
23+
///
24+
/// In-bounds pointers are never null, so the method will never panic for
25+
/// such pointers.
2326
///
2427
/// # Examples
2528
///
@@ -254,6 +257,13 @@ impl<T: ?Sized> *const T {
254257
/// When calling this method, you have to ensure that *either* the pointer is null *or*
255258
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
256259
///
260+
/// # Panics during const evaluation
261+
///
262+
/// This method will panic during const evaluation if the pointer cannot be
263+
/// determined to be null or not. See [`is_null`] for more information.
264+
///
265+
/// [`is_null`]: #method.is_null
266+
///
257267
/// # Examples
258268
///
259269
/// ```
@@ -331,6 +341,13 @@ impl<T: ?Sized> *const T {
331341
/// When calling this method, you have to ensure that *either* the pointer is null *or*
332342
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
333343
///
344+
/// # Panics during const evaluation
345+
///
346+
/// This method will panic during const evaluation if the pointer cannot be
347+
/// determined to be null or not. See [`is_null`] for more information.
348+
///
349+
/// [`is_null`]: #method.is_null
350+
///
334351
/// # Examples
335352
///
336353
/// ```
@@ -1607,6 +1624,13 @@ impl<T> *const [T] {
16071624
///
16081625
/// [valid]: crate::ptr#safety
16091626
/// [allocated object]: crate::ptr#allocated-object
1627+
///
1628+
/// # Panics during const evaluation
1629+
///
1630+
/// This method will panic during const evaluation if the pointer cannot be
1631+
/// determined to be null or not. See [`is_null`] for more information.
1632+
///
1633+
/// [`is_null`]: #method.is_null
16101634
#[inline]
16111635
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
16121636
pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {

library/core/src/ptr/mut_ptr.rs

+51-7
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ impl<T: ?Sized> *mut T {
1212
/// Therefore, two pointers that are null may still not compare equal to
1313
/// each other.
1414
///
15-
/// ## Behavior during const evaluation
15+
/// # Panics during const evaluation
1616
///
17-
/// When this function is used during const evaluation, it may return `false` for pointers
18-
/// that turn out to be null at runtime. Specifically, when a pointer to some memory
19-
/// is offset beyond its bounds in such a way that the resulting pointer is null,
20-
/// the function will still return `false`. There is no way for CTFE to know
21-
/// the absolute position of that memory, so we cannot tell if the pointer is
22-
/// null or not.
17+
/// If this method is used during const evaluation, and `self` is a pointer
18+
/// that is offset beyond the bounds of the memory it initially pointed to,
19+
/// then there might not be enough information to determine whether the
20+
/// pointer is null. This is because the absolute address in memory is not
21+
/// known at compile time. If the nullness of the pointer cannot be
22+
/// determined, this method will panic.
23+
///
24+
/// In-bounds pointers are never null, so the method will never panic for
25+
/// such pointers.
2326
///
2427
/// # Examples
2528
///
@@ -243,6 +246,13 @@ impl<T: ?Sized> *mut T {
243246
/// When calling this method, you have to ensure that *either* the pointer is null *or*
244247
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
245248
///
249+
/// # Panics during const evaluation
250+
///
251+
/// This method will panic during const evaluation if the pointer cannot be
252+
/// determined to be null or not. See [`is_null`] for more information.
253+
///
254+
/// [`is_null`]: #method.is_null-1
255+
///
246256
/// # Examples
247257
///
248258
/// ```
@@ -327,6 +337,13 @@ impl<T: ?Sized> *mut T {
327337
/// Note that because the created reference is to `MaybeUninit<T>`, the
328338
/// source pointer can point to uninitialized memory.
329339
///
340+
/// # Panics during const evaluation
341+
///
342+
/// This method will panic during const evaluation if the pointer cannot be
343+
/// determined to be null or not. See [`is_null`] for more information.
344+
///
345+
/// [`is_null`]: #method.is_null-1
346+
///
330347
/// # Examples
331348
///
332349
/// ```
@@ -590,6 +607,12 @@ impl<T: ?Sized> *mut T {
590607
/// the pointer is null *or*
591608
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
592609
///
610+
/// # Panics during const evaluation
611+
///
612+
/// This method will panic during const evaluation if the pointer cannot be
613+
/// determined to be null or not. See [`is_null`] for more information.
614+
///
615+
/// [`is_null`]: #method.is_null-1
593616
///
594617
/// # Examples
595618
///
@@ -673,6 +696,13 @@ impl<T: ?Sized> *mut T {
673696
///
674697
/// When calling this method, you have to ensure that *either* the pointer is null *or*
675698
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
699+
///
700+
/// # Panics during const evaluation
701+
///
702+
/// This method will panic during const evaluation if the pointer cannot be
703+
/// determined to be null or not. See [`is_null`] for more information.
704+
///
705+
/// [`is_null`]: #method.is_null-1
676706
#[inline]
677707
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
678708
pub const unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit<T>>
@@ -1949,6 +1979,13 @@ impl<T> *mut [T] {
19491979
///
19501980
/// [valid]: crate::ptr#safety
19511981
/// [allocated object]: crate::ptr#allocated-object
1982+
///
1983+
/// # Panics during const evaluation
1984+
///
1985+
/// This method will panic during const evaluation if the pointer cannot be
1986+
/// determined to be null or not. See [`is_null`] for more information.
1987+
///
1988+
/// [`is_null`]: #method.is_null-1
19521989
#[inline]
19531990
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
19541991
pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
@@ -2000,6 +2037,13 @@ impl<T> *mut [T] {
20002037
///
20012038
/// [valid]: crate::ptr#safety
20022039
/// [allocated object]: crate::ptr#allocated-object
2040+
///
2041+
/// # Panics during const evaluation
2042+
///
2043+
/// This method will panic during const evaluation if the pointer cannot be
2044+
/// determined to be null or not. See [`is_null`] for more information.
2045+
///
2046+
/// [`is_null`]: #method.is_null-1
20032047
#[inline]
20042048
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
20052049
pub const unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit<T>]> {

library/core/src/ptr/non_null.rs

+7
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,13 @@ impl<T: ?Sized> NonNull<T> {
204204

205205
/// Creates a new `NonNull` if `ptr` is non-null.
206206
///
207+
/// # Panics during const evaluation
208+
///
209+
/// This method will panic during const evaluation if the pointer cannot be
210+
/// determined to be null or not. See [`is_null`] for more information.
211+
///
212+
/// [`is_null`]: ../primitive.pointer.html#method.is_null-1
213+
///
207214
/// # Examples
208215
///
209216
/// ```

library/std/src/fs.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -2397,12 +2397,14 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
23972397
/// # Platform-specific behavior
23982398
///
23992399
/// This function currently corresponds to the `rename` function on Unix
2400-
/// and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows.
2400+
/// and the `SetFileInformationByHandle` function on Windows.
24012401
///
24022402
/// Because of this, the behavior when both `from` and `to` exist differs. On
24032403
/// Unix, if `from` is a directory, `to` must also be an (empty) directory. If
2404-
/// `from` is not a directory, `to` must also be not a directory. In contrast,
2405-
/// on Windows, `from` can be anything, but `to` must *not* be a directory.
2404+
/// `from` is not a directory, `to` must also be not a directory. The behavior
2405+
/// on Windows is the same on Windows 10 1607 and higher if `FileRenameInfoEx`
2406+
/// is supported by the filesystem; otherwise, `from` can be anything, but
2407+
/// `to` must *not* be a directory.
24062408
///
24072409
/// Note that, this [may change in the future][changes].
24082410
///

library/std/src/fs/tests.rs

+41
Original file line numberDiff line numberDiff line change
@@ -1912,3 +1912,44 @@ fn test_hidden_file_truncation() {
19121912
let metadata = file.metadata().unwrap();
19131913
assert_eq!(metadata.len(), 0);
19141914
}
1915+
1916+
#[cfg(windows)]
1917+
#[test]
1918+
fn test_rename_file_over_open_file() {
1919+
// Make sure that std::fs::rename works if the target file is already opened with FILE_SHARE_DELETE. See #123985.
1920+
let tmpdir = tmpdir();
1921+
1922+
// Create source with test data to read.
1923+
let source_path = tmpdir.join("source_file.txt");
1924+
fs::write(&source_path, b"source hello world").unwrap();
1925+
1926+
// Create target file with test data to read;
1927+
let target_path = tmpdir.join("target_file.txt");
1928+
fs::write(&target_path, b"target hello world").unwrap();
1929+
1930+
// Open target file
1931+
let target_file = fs::File::open(&target_path).unwrap();
1932+
1933+
// Rename source
1934+
fs::rename(source_path, &target_path).unwrap();
1935+
1936+
core::mem::drop(target_file);
1937+
assert_eq!(fs::read(target_path).unwrap(), b"source hello world");
1938+
}
1939+
1940+
#[test]
1941+
#[cfg(windows)]
1942+
fn test_rename_directory_to_non_empty_directory() {
1943+
// Renaming a directory over a non-empty existing directory should fail on Windows.
1944+
let tmpdir: TempDir = tmpdir();
1945+
1946+
let source_path = tmpdir.join("source_directory");
1947+
let target_path = tmpdir.join("target_directory");
1948+
1949+
fs::create_dir(&source_path).unwrap();
1950+
fs::create_dir(&target_path).unwrap();
1951+
1952+
fs::write(target_path.join("target_file.txt"), b"target hello world").unwrap();
1953+
1954+
error!(fs::rename(source_path, target_path), 145); // ERROR_DIR_NOT_EMPTY
1955+
}

library/std/src/sys/pal/windows/c/bindings.txt

+3
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,7 @@ Windows.Win32.Storage.FileSystem.FILE_NAME_OPENED
22952295
Windows.Win32.Storage.FileSystem.FILE_READ_ATTRIBUTES
22962296
Windows.Win32.Storage.FileSystem.FILE_READ_DATA
22972297
Windows.Win32.Storage.FileSystem.FILE_READ_EA
2298+
Windows.Win32.Storage.FileSystem.FILE_RENAME_INFO
22982299
Windows.Win32.Storage.FileSystem.FILE_SHARE_DELETE
22992300
Windows.Win32.Storage.FileSystem.FILE_SHARE_MODE
23002301
Windows.Win32.Storage.FileSystem.FILE_SHARE_NONE
@@ -2603,5 +2604,7 @@ Windows.Win32.System.Threading.WaitForMultipleObjects
26032604
Windows.Win32.System.Threading.WaitForSingleObject
26042605
Windows.Win32.System.Threading.WakeAllConditionVariable
26052606
Windows.Win32.System.Threading.WakeConditionVariable
2607+
Windows.Win32.System.WindowsProgramming.FILE_RENAME_FLAG_POSIX_SEMANTICS
2608+
Windows.Win32.System.WindowsProgramming.FILE_RENAME_FLAG_REPLACE_IF_EXISTS
26062609
Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
26072610
Windows.Win32.UI.Shell.GetUserProfileDirectoryW

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

+16
Original file line numberDiff line numberDiff line change
@@ -2472,6 +2472,22 @@ pub const FILE_RANDOM_ACCESS: NTCREATEFILE_CREATE_OPTIONS = 2048u32;
24722472
pub const FILE_READ_ATTRIBUTES: FILE_ACCESS_RIGHTS = 128u32;
24732473
pub const FILE_READ_DATA: FILE_ACCESS_RIGHTS = 1u32;
24742474
pub const FILE_READ_EA: FILE_ACCESS_RIGHTS = 8u32;
2475+
pub const FILE_RENAME_FLAG_POSIX_SEMANTICS: u32 = 2u32;
2476+
pub const FILE_RENAME_FLAG_REPLACE_IF_EXISTS: u32 = 1u32;
2477+
#[repr(C)]
2478+
#[derive(Clone, Copy)]
2479+
pub struct FILE_RENAME_INFO {
2480+
pub Anonymous: FILE_RENAME_INFO_0,
2481+
pub RootDirectory: HANDLE,
2482+
pub FileNameLength: u32,
2483+
pub FileName: [u16; 1],
2484+
}
2485+
#[repr(C)]
2486+
#[derive(Clone, Copy)]
2487+
pub union FILE_RENAME_INFO_0 {
2488+
pub ReplaceIfExists: BOOLEAN,
2489+
pub Flags: u32,
2490+
}
24752491
pub const FILE_RESERVE_OPFILTER: NTCREATEFILE_CREATE_OPTIONS = 1048576u32;
24762492
pub const FILE_SEQUENTIAL_ONLY: NTCREATEFILE_CREATE_OPTIONS = 4u32;
24772493
pub const FILE_SESSION_AWARE: NTCREATEFILE_CREATE_OPTIONS = 262144u32;

0 commit comments

Comments
 (0)