From b661e98f09a195cd13457525b09b6db628835734 Mon Sep 17 00:00:00 2001 From: Caio Date: Sun, 1 Dec 2024 19:10:44 -0300 Subject: [PATCH 001/113] Fix #128346 --- compiler/rustc_expand/src/mbe/transcribe.rs | 6 +++-- tests/crashes/128346.rs | 13 ----------- .../macro-metavar-expr-concat/repetitions.rs | 22 +++++++++++++++++-- .../repetitions.stderr | 22 +++++++++++++++++++ 4 files changed, 46 insertions(+), 17 deletions(-) delete mode 100644 tests/crashes/128346.rs create mode 100644 tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index b77d02e630a2..c780cfd0e8fd 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -696,8 +696,10 @@ fn transcribe_metavar_expr<'a>( MetaVarExprConcatElem::Var(ident) => { match matched_from_ident(dcx, *ident, interp)? { NamedMatch::MatchedSeq(named_matches) => { - let curr_idx = repeats.last().unwrap().0; - match &named_matches[curr_idx] { + let Some((curr_idx, _)) = repeats.last() else { + return Err(dcx.struct_span_err(sp.entire(), "invalid syntax")); + }; + match &named_matches[*curr_idx] { // FIXME(c410-f3r) Nested repetitions are unimplemented MatchedSeq(_) => unimplemented!(), MatchedSingle(pnr) => { diff --git a/tests/crashes/128346.rs b/tests/crashes/128346.rs deleted file mode 100644 index 93d9c40a544e..000000000000 --- a/tests/crashes/128346.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#128346 - -macro_rules! one_rep { - ( $($a:ident)* ) => { - A( - const ${concat($a, Z)}: i32 = 3; - )* - }; -} - -fn main() { - one_rep!(A B C); -} diff --git a/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs b/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs index 781443207ac1..52a7d5cd8a7e 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/repetitions.rs @@ -1,5 +1,3 @@ -//@ run-pass - #![feature(macro_metavar_expr_concat)] macro_rules! one_rep { @@ -10,9 +8,29 @@ macro_rules! one_rep { }; } +macro_rules! issue_128346 { + ( $($a:ident)* ) => { + A( + const ${concat($a, Z)}: i32 = 3; + //~^ ERROR invalid syntax + )* + }; +} + +macro_rules! issue_131393 { + ($t:ident $($en:ident)?) => { + read::<${concat($t, $en)}>() + //~^ ERROR invalid syntax + //~| ERROR invalid syntax + } +} + fn main() { one_rep!(A B C); assert_eq!(AZ, 3); assert_eq!(BZ, 3); assert_eq!(CZ, 3); + issue_128346!(A B C); + issue_131393!(u8); + issue_131393!(u16 le); } diff --git a/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr b/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr new file mode 100644 index 000000000000..c3006c4be5df --- /dev/null +++ b/tests/ui/macros/macro-metavar-expr-concat/repetitions.stderr @@ -0,0 +1,22 @@ +error: invalid syntax + --> $DIR/repetitions.rs:14:20 + | +LL | const ${concat($a, Z)}: i32 = 3; + | ^^^^^^^^^^^^^^^ + +error: invalid syntax + --> $DIR/repetitions.rs:22:17 + | +LL | read::<${concat($t, $en)}>() + | ^^^^^^^^^^^^^^^^^ + +error: invalid syntax + --> $DIR/repetitions.rs:22:17 + | +LL | read::<${concat($t, $en)}>() + | ^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + From 00c5289c649394d544b6189e2bcdbcc7ceff49f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Mon, 16 Dec 2024 10:42:26 +0100 Subject: [PATCH 002/113] Add 'into_array' conversion destructors for 'Box', 'Rc', and 'Arc'; --- library/alloc/src/boxed.rs | 20 ++++++++++++++++++++ library/alloc/src/rc.rs | 20 ++++++++++++++++++++ library/alloc/src/sync.rs | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 23b85fbd4ebc..ca3bd24a4203 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -761,6 +761,26 @@ impl Box<[T]> { }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } + + /// Converts the boxed slice into a boxed array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *mut [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Box::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Box<[T], A> { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index bb27fe3c62dc..58edb44e3738 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1084,6 +1084,26 @@ impl Rc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Rc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Rc<[T], A> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 6cf41a3fa4e1..e499d1b04f40 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1203,6 +1203,26 @@ impl Arc<[T]> { )) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "slice_as_array", issue = "133508")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let ptr = Self::into_raw(self) as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Arc::from_raw(ptr) }; + Some(me) + } else { + None + } + } } impl Arc<[T], A> { From 526d29865c3956ab0dcfba62df7a1933e1f1520d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 21 Dec 2024 08:32:47 +0100 Subject: [PATCH 003/113] ptr::copy: fix docs for the overlapping case --- compiler/rustc_const_eval/src/interpret/memory.rs | 2 ++ library/core/src/intrinsics/mod.rs | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 027ba9644cba..0790db984e34 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1359,6 +1359,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let src_alloc = self.get_alloc_raw(src_alloc_id)?; let src_range = alloc_range(src_offset, size); assert!(!self.memory.validation_in_progress, "we can't be copying during validation"); + // For the overlapping case, it is crucial that we trigger the read hook + // before the write hook -- the aliasing model cares about the order. M::before_memory_read( tcx, &self.machine, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 3e53c0497cc7..61a142b459ac 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -4364,13 +4364,11 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us /// /// Behavior is undefined if any of the following conditions are violated: /// -/// * `src` must be [valid] for reads of `count * size_of::()` bytes, and must remain valid even -/// when `dst` is written for `count * size_of::()` bytes. (This means if the memory ranges -/// overlap, the two pointers must not be subject to aliasing restrictions relative to each -/// other.) +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. /// /// * `dst` must be [valid] for writes of `count * size_of::()` bytes, and must remain valid even -/// when `src` is read for `count * size_of::()` bytes. +/// when `src` is read for `count * size_of::()` bytes. (This means if the memory ranges +/// overlap, the `dst` pointer must not be invalidated by `src` reads.) /// /// * Both `src` and `dst` must be properly aligned. /// From 1e3ecd5e4d822425e072e784dbb9732058d4b292 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 13 Dec 2024 17:31:46 +0000 Subject: [PATCH 004/113] Windows: Use WriteFile to write to a UTF-8 console --- .../std/src/sys/pal/windows/c/bindings.txt | 1 + .../std/src/sys/pal/windows/c/windows_sys.rs | 2 ++ library/std/src/sys/pal/windows/stdio.rs | 24 ++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt index 248ce3c9ff62..06d192587832 100644 --- a/library/std/src/sys/pal/windows/c/bindings.txt +++ b/library/std/src/sys/pal/windows/c/bindings.txt @@ -2425,6 +2425,7 @@ Windows.Win32.System.Console.ENABLE_VIRTUAL_TERMINAL_PROCESSING Windows.Win32.System.Console.ENABLE_WINDOW_INPUT Windows.Win32.System.Console.ENABLE_WRAP_AT_EOL_OUTPUT Windows.Win32.System.Console.GetConsoleMode +Windows.Win32.System.Console.GetConsoleOutputCP Windows.Win32.System.Console.GetStdHandle Windows.Win32.System.Console.ReadConsoleW Windows.Win32.System.Console.STD_ERROR_HANDLE diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs index 19925e59dfe9..a3c4cf6b4220 100644 --- a/library/std/src/sys/pal/windows/c/windows_sys.rs +++ b/library/std/src/sys/pal/windows/c/windows_sys.rs @@ -34,6 +34,7 @@ windows_targets::link!("kernel32.dll" "system" fn FreeEnvironmentStringsW(penv : windows_targets::link!("kernel32.dll" "system" fn GetActiveProcessorCount(groupnumber : u16) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCommandLineW() -> PCWSTR); windows_targets::link!("kernel32.dll" "system" fn GetConsoleMode(hconsolehandle : HANDLE, lpmode : *mut CONSOLE_MODE) -> BOOL); +windows_targets::link!("kernel32.dll" "system" fn GetConsoleOutputCP() -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCurrentDirectoryW(nbufferlength : u32, lpbuffer : PWSTR) -> u32); windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcess() -> HANDLE); windows_targets::link!("kernel32.dll" "system" fn GetCurrentProcessId() -> u32); @@ -3317,6 +3318,7 @@ pub struct XSAVE_FORMAT { pub XmmRegisters: [M128A; 8], pub Reserved4: [u8; 224], } + #[cfg(target_arch = "arm")] #[repr(C)] pub struct WSADATA { diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 642c8bc4df7d..1b735e7f0cb2 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -84,21 +84,43 @@ fn is_console(handle: c::HANDLE) -> bool { unsafe { c::GetConsoleMode(handle, &mut mode) != 0 } } +/// Returns true if the attached console's code page is currently UTF-8. +#[cfg(not(target_vendor = "win7"))] +fn is_utf8_console() -> bool { + unsafe { c::GetConsoleOutputCP() == c::CP_UTF8 } +} + +#[cfg(target_vendor = "win7")] +fn is_utf8_console() -> bool { + // Windows 7 has a fun "feature" where WriteFile on a console handle will return + // the number of UTF-16 code units written and not the number of bytes from the input string. + // So we always claim the console isn't UTF-8 to trigger the WriteConsole fallback code. + false +} + fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> io::Result { if data.is_empty() { return Ok(0); } let handle = get_handle(handle_id)?; - if !is_console(handle) { + if !is_console(handle) || is_utf8_console() { unsafe { let handle = Handle::from_raw_handle(handle); let ret = handle.write(data); let _ = handle.into_raw_handle(); // Don't close the handle return ret; } + } else { + write_console_utf16(data, incomplete_utf8, handle) } +} +fn write_console_utf16( + data: &[u8], + incomplete_utf8: &mut IncompleteUtf8, + handle: c::HANDLE, +) -> io::Result { if incomplete_utf8.len > 0 { assert!( incomplete_utf8.len < 4, From 70fe5a150d2aa28e704a30a6ce8c2219e4b98583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 21 Dec 2024 19:08:30 +0000 Subject: [PATCH 005/113] Avoid ICE in borrowck Provide a fallback in `best_blame_constraint` when `find_constraint_paths_between_regions` doesn't have a result. This code is due a rework to avoid the letf-over `unwrap()`, but avoids the ICE caused by the repro. Fix #133252. --- .../rustc_borrowck/src/region_infer/mod.rs | 10 ++++-- ...entation-not-general-enough-ice-133252.rs} | 6 +++- ...ation-not-general-enough-ice-133252.stderr | 34 +++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) rename tests/{crashes/133252.rs => ui/borrowck/implementation-not-general-enough-ice-133252.rs} (81%) create mode 100644 tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d39fbf32921a..37e931963351 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1945,8 +1945,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { target_test: impl Fn(RegionVid) -> bool, ) -> (BlameConstraint<'tcx>, Vec) { // Find all paths - let (path, target_region) = - self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); + let (path, target_region) = self + .find_constraint_paths_between_regions(from_region, target_test) + .or_else(|| { + self.find_constraint_paths_between_regions(from_region, |r| { + self.cannot_name_placeholder(from_region, r) + }) + }) + .unwrap(); debug!( "path={:#?}", path.iter() diff --git a/tests/crashes/133252.rs b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.rs similarity index 81% rename from tests/crashes/133252.rs rename to tests/ui/borrowck/implementation-not-general-enough-ice-133252.rs index 3cecf448287b..7ee16e62b9a7 100644 --- a/tests/crashes/133252.rs +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.rs @@ -1,4 +1,4 @@ -//@ known-bug: #133252 +// Regression test for borrowck ICE #133252 //@ edition:2021 use std::future::Future; @@ -7,6 +7,8 @@ fn ice() -> impl Future { async { let not_static = 0; force_send(async_load(¬_static)); + //~^ ERROR implementation of `LoadQuery` is not general enough + //~| ERROR `not_static` does not live long enough loop {} } } @@ -41,3 +43,5 @@ impl Future for SimpleFuture { loop {} } } + +fn main() {} diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr new file mode 100644 index 000000000000..13c768dcbf63 --- /dev/null +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -0,0 +1,34 @@ +error: implementation of `LoadQuery` is not general enough + --> $DIR/implementation-not-general-enough-ice-133252.rs:9:9 + | +LL | force_send(async_load(¬_static)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `LoadQuery` is not general enough + | + = note: `LoadQuery<'0>` would have to be implemented for the type `&u8`, for any lifetime `'0`... + = note: ...but `LoadQuery<'1>` is actually implemented for the type `&'1 u8`, for some specific lifetime `'1` + +error[E0597]: `not_static` does not live long enough + --> $DIR/implementation-not-general-enough-ice-133252.rs:9:31 + | +LL | async { + | - return type of async block is &(dyn Owned + '1) +LL | let not_static = 0; + | ---------- binding `not_static` declared here +LL | force_send(async_load(¬_static)); + | -----------^^^^^^^^^^^- + | | | + | | borrowed value does not live long enough + | argument requires that `not_static` is borrowed for `'1` +... +LL | } + | - `not_static` dropped here while still borrowed + | +note: due to current limitations in the borrow checker, this implies a `'static` lifetime + --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18 + | +LL | fn force_send(_: T) {} + | ^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`. From 73b41fbcfacb8fcc5a8be3ffa849abcd543069b6 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Tue, 17 Dec 2024 12:40:39 -0500 Subject: [PATCH 006/113] Unify fs::copy and io::copy --- library/std/src/sys/pal/unix/fs.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 37029bcd36e3..3fb0ed064cbb 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1980,7 +1980,7 @@ fn open_to_and_set_permissions( Ok((writer, writer_metadata)) } -#[cfg(not(any(target_os = "linux", target_os = "android", target_vendor = "apple")))] +#[cfg(not(target_vendor = "apple"))] pub fn copy(from: &Path, to: &Path) -> io::Result { let (mut reader, reader_metadata) = open_from(from)?; let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; @@ -1988,24 +1988,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { io::copy(&mut reader, &mut writer) } -#[cfg(any(target_os = "linux", target_os = "android"))] -pub fn copy(from: &Path, to: &Path) -> io::Result { - let (mut reader, reader_metadata) = open_from(from)?; - let max_len = u64::MAX; - let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; - - use super::kernel_copy::{CopyResult, copy_regular_files}; - - match copy_regular_files(reader.as_raw_fd(), writer.as_raw_fd(), max_len) { - CopyResult::Ended(bytes) => Ok(bytes), - CopyResult::Error(e, _) => Err(e), - CopyResult::Fallback(written) => match io::copy::generic_copy(&mut reader, &mut writer) { - Ok(bytes) => Ok(bytes + written), - Err(e) => Err(e), - }, - } -} - #[cfg(target_vendor = "apple")] pub fn copy(from: &Path, to: &Path) -> io::Result { const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA; From e0a1549e44036a75feb2fad4ffbd98ad398eac3b Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Sat, 21 Dec 2024 15:10:29 -0800 Subject: [PATCH 007/113] Eliminate redundant statx syscalls Signed-off-by: Alex Saveau --- library/std/src/sys/pal/unix/fs.rs | 15 +++--- library/std/src/sys/pal/unix/kernel_copy.rs | 58 +++++++++++++++++++-- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 3fb0ed064cbb..c18f4d566797 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1944,7 +1944,7 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> #[cfg(target_os = "espidf")] fn open_to_and_set_permissions( to: &Path, - _reader_metadata: crate::fs::Metadata, + _reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; let writer = OpenOptions::new().open(to)?; @@ -1955,7 +1955,7 @@ fn open_to_and_set_permissions( #[cfg(not(target_os = "espidf"))] fn open_to_and_set_permissions( to: &Path, - reader_metadata: crate::fs::Metadata, + reader_metadata: &crate::fs::Metadata, ) -> io::Result<(crate::fs::File, crate::fs::Metadata)> { use crate::fs::OpenOptions; use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt}; @@ -1982,10 +1982,13 @@ fn open_to_and_set_permissions( #[cfg(not(target_vendor = "apple"))] pub fn copy(from: &Path, to: &Path) -> io::Result { - let (mut reader, reader_metadata) = open_from(from)?; - let (mut writer, _) = open_to_and_set_permissions(to, reader_metadata)?; + let (reader, reader_metadata) = open_from(from)?; + let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; - io::copy(&mut reader, &mut writer) + io::copy( + &mut crate::sys::kernel_copy::CachedFileMetadata(reader, reader_metadata), + &mut crate::sys::kernel_copy::CachedFileMetadata(writer, writer_metadata), + ) } #[cfg(target_vendor = "apple")] @@ -2022,7 +2025,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } // Fall back to using `fcopyfile` if `fclonefileat` does not succeed. - let (writer, writer_metadata) = open_to_and_set_permissions(to, reader_metadata)?; + let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; // We ensure that `FreeOnDrop` never contains a null pointer so it is // always safe to call `copyfile_state_free` diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index a671383cb795..bddfe829f43a 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -52,8 +52,8 @@ use crate::cmp::min; use crate::fs::{File, Metadata}; use crate::io::copy::generic_copy; use crate::io::{ - BufRead, BufReader, BufWriter, Error, Read, Result, StderrLock, StdinLock, StdoutLock, Take, - Write, + BorrowedCursor, BufRead, BufReader, BufWriter, Error, IoSlice, IoSliceMut, Read, Result, + StderrLock, StdinLock, StdoutLock, Take, Write, }; use crate::mem::ManuallyDrop; use crate::net::TcpStream; @@ -192,7 +192,7 @@ impl SpecCopy for Copier<'_, '_, R, W> { let w_cfg = writer.properties(); // before direct operations on file descriptors ensure that all source and sink buffers are empty - let mut flush = || -> crate::io::Result { + let mut flush = || -> Result { let bytes = reader.drain_to(writer, u64::MAX)?; // BufWriter buffered bytes have already been accounted for in earlier write() calls writer.flush()?; @@ -537,6 +537,58 @@ impl CopyWrite for BufWriter { } } +pub(crate) struct CachedFileMetadata(pub File, pub Metadata); + +impl Read for CachedFileMetadata { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { + self.0.read_vectored(bufs) + } + fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { + self.0.read_buf(cursor) + } + #[inline] + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + fn read_to_end(&mut self, buf: &mut Vec) -> Result { + self.0.read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> Result { + self.0.read_to_string(buf) + } +} +impl Write for CachedFileMetadata { + fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { + self.0.write_vectored(bufs) + } + #[inline] + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } + #[inline] + fn flush(&mut self) -> Result<()> { + self.0.flush() + } +} + +impl CopyRead for CachedFileMetadata { + fn properties(&self) -> CopyParams { + CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) + } +} + +impl CopyWrite for CachedFileMetadata { + fn properties(&self) -> CopyParams { + CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) + } +} + fn fd_to_meta(fd: &T) -> FdMeta { let fd = fd.as_raw_fd(); let file: ManuallyDrop = ManuallyDrop::new(unsafe { File::from_raw_fd(fd) }); From b5e8a5d3939935eecfe8ed2dbc97ad748e090d90 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Wed, 13 Oct 2021 08:46:34 -0700 Subject: [PATCH 008/113] Document collection `From` and `FromIterator` impls that drop duplicate keys. This behavior is worth documenting because there are other plausible alternatives, such as panicking when a duplicate is encountered, and it reminds the programmer to consider whether they should, for example, coalesce duplicate keys first. --- library/alloc/src/collections/btree/map.rs | 9 ++++++++- library/alloc/src/collections/btree/set.rs | 4 ++++ library/std/src/collections/hash/map.rs | 9 +++++++++ library/std/src/collections/hash/set.rs | 4 ++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index d1ce4e215ed9..56679eaa1189 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2289,6 +2289,10 @@ impl FusedIterator for RangeMut<'_, K, V> {} #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator<(K, V)> for BTreeMap { + /// Constructs a `BTreeMap` from an iterator of key-value pairs. + /// + /// If the iterator produces any pairs with equal keys, + /// all but the last value for each such key are discarded. fn from_iter>(iter: T) -> BTreeMap { let mut inputs: Vec<_> = iter.into_iter().collect(); @@ -2403,7 +2407,10 @@ where #[stable(feature = "std_collections_from_array", since = "1.56.0")] impl From<[(K, V); N]> for BTreeMap { - /// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`. + /// Converts a `[(K, V); N]` into a `BTreeMap`. + /// + /// If any entries in the array have equal keys, all but the last entry for each such key + /// are discarded. /// /// ``` /// use std::collections::BTreeMap; diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 6f8c3b2d152b..9f5a42b5f6d2 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1491,6 +1491,10 @@ impl BTreeSet { impl From<[T; N]> for BTreeSet { /// Converts a `[T; N]` into a `BTreeSet`. /// + /// If the array contains any equal values, all but the last instance of each are discarded. + /// + /// # Examples + /// /// ``` /// use std::collections::BTreeSet; /// diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 109bc3946346..5b2cd53763b9 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1446,6 +1446,11 @@ impl From<[(K, V); N]> for HashMap where K: Eq + Hash, { + /// Converts a `[(K, V); N]` into a `HashMap`. + /// + /// If any entries in the array have equal keys, all but the last entry for each such key + /// are discarded. + /// /// # Examples /// /// ``` @@ -3219,6 +3224,10 @@ where K: Eq + Hash, S: BuildHasher + Default, { + /// Constructs a `HashMap` from an iterator of key-value pairs. + /// + /// If the iterator produces any pairs with equal keys, + /// all but the last value for each such key are discarded. fn from_iter>(iter: T) -> HashMap { let mut map = HashMap::with_hasher(Default::default()); map.extend(iter); diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 4c81aaff4588..8e840aaa07f9 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1091,6 +1091,10 @@ impl From<[T; N]> for HashSet where T: Eq + Hash, { + /// Converts a `[T; N]` into a `HashSet`. + /// + /// If the array contains any equal values, all but the last instance of each are discarded. + /// /// # Examples /// /// ``` From f19ba15a2cdc396a353fff70431df23016dc5276 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Sat, 21 Dec 2024 22:45:04 -0800 Subject: [PATCH 009/113] Fix forgetting to save statx availability on success Signed-off-by: Alex Saveau --- library/std/src/sys/pal/unix/fs.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 37029bcd36e3..408f8020c565 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -168,7 +168,8 @@ cfg_has_statx! {{ ) -> c_int } - if STATX_SAVED_STATE.load(Ordering::Relaxed) == STATX_STATE::Unavailable as u8 { + let statx_availability = STATX_SAVED_STATE.load(Ordering::Relaxed); + if statx_availability == STATX_STATE::Unavailable as u8 { return None; } @@ -200,6 +201,9 @@ cfg_has_statx! {{ return None; } } + if statx_availability == STATX_STATE::Unknown as u8 { + STATX_SAVED_STATE.store(STATX_STATE::Present as u8, Ordering::Relaxed); + } // We cannot fill `stat64` exhaustively because of private padding fields. let mut stat: stat64 = mem::zeroed(); From 6a43716ada10c18d6991dd9408ce2f31214cb8f3 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sun, 22 Dec 2024 08:13:00 -0800 Subject: [PATCH 010/113] Specify only that duplicates are discarded, not the order. --- library/alloc/src/collections/btree/map.rs | 6 +++--- library/alloc/src/collections/btree/set.rs | 3 ++- library/std/src/collections/hash/map.rs | 6 +++--- library/std/src/collections/hash/set.rs | 3 ++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 56679eaa1189..6d305386dbfa 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2292,7 +2292,7 @@ impl FromIterator<(K, V)> for BTreeMap { /// Constructs a `BTreeMap` from an iterator of key-value pairs. /// /// If the iterator produces any pairs with equal keys, - /// all but the last value for each such key are discarded. + /// all but one of the corresponding values will be dropped. fn from_iter>(iter: T) -> BTreeMap { let mut inputs: Vec<_> = iter.into_iter().collect(); @@ -2409,8 +2409,8 @@ where impl From<[(K, V); N]> for BTreeMap { /// Converts a `[(K, V); N]` into a `BTreeMap`. /// - /// If any entries in the array have equal keys, all but the last entry for each such key - /// are discarded. + /// If any entries in the array have equal keys, + /// all but one of the corresponding values will be dropped. /// /// ``` /// use std::collections::BTreeMap; diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 9f5a42b5f6d2..9660023d6945 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1491,7 +1491,8 @@ impl BTreeSet { impl From<[T; N]> for BTreeSet { /// Converts a `[T; N]` into a `BTreeSet`. /// - /// If the array contains any equal values, all but the last instance of each are discarded. + /// If the array contains any equal values, + /// all but one will be dropped. /// /// # Examples /// diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 5b2cd53763b9..56d734ba2fbf 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1448,8 +1448,8 @@ where { /// Converts a `[(K, V); N]` into a `HashMap`. /// - /// If any entries in the array have equal keys, all but the last entry for each such key - /// are discarded. + /// If any entries in the array have equal keys, + /// all but one of the corresponding values will be dropped. /// /// # Examples /// @@ -3227,7 +3227,7 @@ where /// Constructs a `HashMap` from an iterator of key-value pairs. /// /// If the iterator produces any pairs with equal keys, - /// all but the last value for each such key are discarded. + /// all but one of the corresponding values will be dropped. fn from_iter>(iter: T) -> HashMap { let mut map = HashMap::with_hasher(Default::default()); map.extend(iter); diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 8e840aaa07f9..bcf6d6b4ccf3 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1093,7 +1093,8 @@ where { /// Converts a `[T; N]` into a `HashSet`. /// - /// If the array contains any equal values, all but the last instance of each are discarded. + /// If the array contains any equal values, + /// all but one will be dropped. /// /// # Examples /// From 7ee520491e5c13b7f572583198f4d9812bd3580a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sun, 22 Dec 2024 20:14:19 +0800 Subject: [PATCH 011/113] tests: migrate `incr-add-rust-src-component` to rmake.rs The Makefile version seems to contain a bug. Over the years, the directory structure of the `rust-src` component changed as the source tree directory structure changed. `libstd` is no longer a thing directly under `root/lib/rustlib/src/rust/src/`, it is moved to `root/lib/rustlib/src/rust/library/std`. Co-authored-by: Oneirical --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../incr-add-rust-src-component/Makefile | 45 ------ .../incr-add-rust-src-component/rmake.rs | 131 ++++++++++++++++++ 3 files changed, 131 insertions(+), 46 deletions(-) delete mode 100644 tests/run-make/incr-add-rust-src-component/Makefile create mode 100644 tests/run-make/incr-add-rust-src-component/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 0e156b9d1ac9..f7ecb4851529 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,7 +1,6 @@ run-make/branch-protection-check-IBT/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/extern-fn-reachable/Makefile -run-make/incr-add-rust-src-component/Makefile run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile run-make/split-debuginfo/Makefile diff --git a/tests/run-make/incr-add-rust-src-component/Makefile b/tests/run-make/incr-add-rust-src-component/Makefile deleted file mode 100644 index fd09c2299f98..000000000000 --- a/tests/run-make/incr-add-rust-src-component/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# rust-lang/rust#70924: Test that if we add rust-src component in between two -# incremental compiles, the compiler does not ICE on the second. - -# This test uses `ln -s` rather than copying to save testing time, but its -# usage doesn't work on windows. So ignore windows. - -# ignore-windows - -SYSROOT:=$(shell $(RUSTC) --print sysroot) -FAKEROOT=$(TMPDIR)/fakeroot -INCR=$(TMPDIR)/incr - -# Make a local copy of the sysroot; then remove the rust-src part of it, if -# present, for the *first* build. Then put in a facsimile of the rust-src -# component for the second build, in order to expose the ICE from issue #70924. -# -# Note that it is much easier to just do `cp -a $(SYSROOT)/* $(FAKEROOT)` as a -# first step, but I am concerned that would be too expensive in a unit test -# compared to making symbolic links. -# -# Anyway, the pattern you'll see here is: For every prefix in -# root/lib/rustlib/src, link all of prefix parent content, then remove the -# prefix, then loop on the next prefix. This way, we basically create a copy of -# the context around root/lib/rustlib/src, and can freely add/remove the src -# component itself. -all: - mkdir $(FAKEROOT) - ln -s $(SYSROOT)/* $(FAKEROOT) - rm -f $(FAKEROOT)/lib - mkdir $(FAKEROOT)/lib - ln -s $(SYSROOT)/lib/* $(FAKEROOT)/lib - rm -f $(FAKEROOT)/lib/rustlib - mkdir $(FAKEROOT)/lib/rustlib - ln -s $(SYSROOT)/lib/rustlib/* $(FAKEROOT)/lib/rustlib - rm -f $(FAKEROOT)/lib/rustlib/src - mkdir $(FAKEROOT)/lib/rustlib/src - ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src - rm -f $(FAKEROOT)/lib/rustlib/src/rust - $(RUSTC) --sysroot $(FAKEROOT) -C incremental=$(INCR) main.rs - mkdir -p $(FAKEROOT)/lib/rustlib/src/rust/src/libstd - touch $(FAKEROOT)/lib/rustlib/src/rust/src/libstd/lib.rs - $(RUSTC) --sysroot $(FAKEROOT) -C incremental=$(INCR) main.rs diff --git a/tests/run-make/incr-add-rust-src-component/rmake.rs b/tests/run-make/incr-add-rust-src-component/rmake.rs new file mode 100644 index 000000000000..964f1410a964 --- /dev/null +++ b/tests/run-make/incr-add-rust-src-component/rmake.rs @@ -0,0 +1,131 @@ +//! Regression test for rust-lang/rust#70924. Check that if we add the `rust-src` component in +//! between two incremental compiles, that the compiler doesn't ICE on the second invocation. +//! +//! This test uses symbolic links to save testing time. +//! +//! The way this test works is that, for every prefix in `root/lib/rustlib/src`, link all of prefix +//! parent content, then remove the prefix, then loop on the next prefix. This way, we basically +//! create a copy of the context around `root/lib/rustlib/src`, and can freely add/remove the src +//! component itself. + +//@ ignore-cross-compile +// Reason: test needs to run. + +//@ needs-symlink +// Reason: test needs symlink to create stub directories and files. + +use std::path::Path; + +use run_make_support::rfs::read_dir_entries; +use run_make_support::{bare_rustc, path, rfs, run}; + +#[derive(Debug, Copy, Clone)] +struct Symlink<'a, 'b> { + src_dir: &'a Path, + dst_dir: &'b Path, +} + +fn shallow_symlink_dir<'a, 'b>(Symlink { src_dir, dst_dir }: Symlink<'a, 'b>) { + eprintln!( + "shallow_symlink_dir: src_dir={} -> dst_dir={}", + src_dir.display(), + dst_dir.display() + ); + + read_dir_entries(src_dir, |src_path| { + let src_metadata = rfs::symlink_metadata(src_path); + let filename = src_path.file_name().unwrap(); + if src_metadata.is_dir() { + rfs::symlink_dir(src_path, dst_dir.join(filename)); + } else if src_metadata.is_file() { + rfs::symlink_file(src_path, dst_dir.join(filename)); + } else if src_metadata.is_symlink() { + rfs::copy_symlink(src_path, dst_dir.join(filename)); + } + }); +} + +fn recreate_dir(path: &Path) { + rfs::recursive_remove(path); + rfs::create_dir(path); +} + +fn main() { + let sysroot = bare_rustc().print("sysroot").run().stdout_utf8(); + let sysroot = sysroot.trim(); + let sysroot = path(sysroot); + + let incr = path("incr"); + + let fakeroot = path("fakeroot"); + rfs::create_dir(&fakeroot); + + shallow_symlink_dir(Symlink { src_dir: &sysroot, dst_dir: &fakeroot }); + recreate_dir(&fakeroot.join("lib")); + + shallow_symlink_dir(Symlink { src_dir: &sysroot.join("lib"), dst_dir: &fakeroot.join("lib") }); + recreate_dir(&fakeroot.join("lib").join("rustlib")); + + shallow_symlink_dir(Symlink { + src_dir: &sysroot.join("lib").join("rustlib"), + dst_dir: &fakeroot.join("lib").join("rustlib"), + }); + recreate_dir(&fakeroot.join("lib").join("rustlib").join("src")); + + shallow_symlink_dir(Symlink { + src_dir: &sysroot.join("lib").join("rustlib").join("src"), + dst_dir: &fakeroot.join("lib").join("rustlib").join("src"), + }); + + rfs::recursive_remove(&fakeroot.join("lib").join("rustlib").join("src").join("rust")); + + let run_incr_rustc = || { + bare_rustc() + .sysroot(&fakeroot) + .arg("-C") + .arg(format!("incremental={}", incr.to_str().unwrap())) + .input("main.rs") + .run(); + }; + + // Run rustc w/ incremental once... + run_incr_rustc(); + + // NOTE: the Makefile version of this used `$SYSROOT/lib/rustlib/src/rust/src/libstd/lib.rs`, + // but that actually got moved around and reorganized over the years. As of Dec 2024, the + // rust-src component is more like (specific for our purposes): + // + // ``` + // $SYSROOT/lib/rustlib/src/rust/ + // library/std/src/lib.rs + // src/ + // ``` + rfs::create_dir_all( + &fakeroot + .join("lib") + .join("rustlib") + .join("src") + .join("rust") + .join("library") + .join("std") + .join("src"), + ); + rfs::write( + &fakeroot + .join("lib") + .join("rustlib") + .join("src") + .join("rust") + .join("library") + .join("std") + .join("src") + .join("lib.rs"), + b"", + ); + + // ... and a second time. + run_incr_rustc(); + + // Basic sanity check that the compiled binary can run. + run("main"); +} From 6a89f8789ab918e4112f4f100c6750f3686d46a1 Mon Sep 17 00:00:00 2001 From: deltragon Date: Tue, 24 Dec 2024 14:37:17 +0100 Subject: [PATCH 012/113] Use scoped threads in `std::sync::Barrier` examples This removes boilerplate around `Arc`s and makes the code more clear. --- library/std/src/sync/barrier.rs | 60 ++++++++++++++------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs index 82cc13a74b7f..14e4a9abe6f1 100644 --- a/library/std/src/sync/barrier.rs +++ b/library/std/src/sync/barrier.rs @@ -10,26 +10,22 @@ use crate::sync::{Condvar, Mutex}; /// # Examples /// /// ``` -/// use std::sync::{Arc, Barrier}; +/// use std::sync::Barrier; /// use std::thread; /// /// let n = 10; -/// let mut handles = Vec::with_capacity(n); -/// let barrier = Arc::new(Barrier::new(n)); -/// for _ in 0..n { -/// let c = Arc::clone(&barrier); -/// // The same messages will be printed together. -/// // You will NOT see any interleaving. -/// handles.push(thread::spawn(move || { -/// println!("before wait"); -/// c.wait(); -/// println!("after wait"); -/// })); -/// } -/// // Wait for other threads to finish. -/// for handle in handles { -/// handle.join().unwrap(); -/// } +/// let barrier = Barrier::new(n); +/// thread::scope(|s| { +/// for _ in 0..n { +/// // The same messages will be printed together. +/// // You will NOT see any interleaving. +/// s.spawn(|| { +/// println!("before wait"); +/// barrier.wait(); +/// println!("after wait"); +/// }); +/// } +/// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct Barrier { @@ -105,26 +101,22 @@ impl Barrier { /// # Examples /// /// ``` - /// use std::sync::{Arc, Barrier}; + /// use std::sync::Barrier; /// use std::thread; /// /// let n = 10; - /// let mut handles = Vec::with_capacity(n); - /// let barrier = Arc::new(Barrier::new(n)); - /// for _ in 0..n { - /// let c = Arc::clone(&barrier); - /// // The same messages will be printed together. - /// // You will NOT see any interleaving. - /// handles.push(thread::spawn(move || { - /// println!("before wait"); - /// c.wait(); - /// println!("after wait"); - /// })); - /// } - /// // Wait for other threads to finish. - /// for handle in handles { - /// handle.join().unwrap(); - /// } + /// let barrier = Barrier::new(n); + /// thread::scope(|s| { + /// for _ in 0..n { + /// // The same messages will be printed together. + /// // You will NOT see any interleaving. + /// s.spawn(|| { + /// println!("before wait"); + /// barrier.wait(); + /// println!("after wait"); + /// }); + /// } + /// }); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn wait(&self) -> BarrierWaitResult { From 96cc078878c93aa0826af3b1c40d4f238a4f4555 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Tue, 24 Dec 2024 09:59:22 -0800 Subject: [PATCH 013/113] Fix compilation issues on other unixes Signed-off-by: Alex Saveau --- library/std/src/sys/pal/unix/fs.rs | 52 ++++++++++++++++++++- library/std/src/sys/pal/unix/kernel_copy.rs | 45 ++---------------- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index c18f4d566797..0dad0dc6b184 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1980,14 +1980,62 @@ fn open_to_and_set_permissions( Ok((writer, writer_metadata)) } +mod cfm { + use crate::fs::{File, Metadata}; + use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, Read, Result, Write}; + + #[allow(dead_code)] + pub struct CachedFileMetadata(pub File, pub Metadata); + + impl Read for CachedFileMetadata { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { + self.0.read_vectored(bufs) + } + fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { + self.0.read_buf(cursor) + } + #[inline] + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + fn read_to_end(&mut self, buf: &mut Vec) -> Result { + self.0.read_to_end(buf) + } + fn read_to_string(&mut self, buf: &mut String) -> Result { + self.0.read_to_string(buf) + } + } + impl Write for CachedFileMetadata { + fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { + self.0.write_vectored(bufs) + } + #[inline] + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } + #[inline] + fn flush(&mut self) -> Result<()> { + self.0.flush() + } + } +} +#[cfg(any(target_os = "linux", target_os = "android"))] +pub(crate) use cfm::CachedFileMetadata; + #[cfg(not(target_vendor = "apple"))] pub fn copy(from: &Path, to: &Path) -> io::Result { let (reader, reader_metadata) = open_from(from)?; let (writer, writer_metadata) = open_to_and_set_permissions(to, &reader_metadata)?; io::copy( - &mut crate::sys::kernel_copy::CachedFileMetadata(reader, reader_metadata), - &mut crate::sys::kernel_copy::CachedFileMetadata(writer, writer_metadata), + &mut cfm::CachedFileMetadata(reader, reader_metadata), + &mut cfm::CachedFileMetadata(writer, writer_metadata), ) } diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs index bddfe829f43a..36823a503b17 100644 --- a/library/std/src/sys/pal/unix/kernel_copy.rs +++ b/library/std/src/sys/pal/unix/kernel_copy.rs @@ -52,8 +52,8 @@ use crate::cmp::min; use crate::fs::{File, Metadata}; use crate::io::copy::generic_copy; use crate::io::{ - BorrowedCursor, BufRead, BufReader, BufWriter, Error, IoSlice, IoSliceMut, Read, Result, - StderrLock, StdinLock, StdoutLock, Take, Write, + BufRead, BufReader, BufWriter, Error, Read, Result, StderrLock, StdinLock, StdoutLock, Take, + Write, }; use crate::mem::ManuallyDrop; use crate::net::TcpStream; @@ -65,6 +65,7 @@ use crate::process::{ChildStderr, ChildStdin, ChildStdout}; use crate::ptr; use crate::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use crate::sys::cvt; +use crate::sys::fs::CachedFileMetadata; use crate::sys::weak::syscall; #[cfg(test)] @@ -537,46 +538,6 @@ impl CopyWrite for BufWriter { } } -pub(crate) struct CachedFileMetadata(pub File, pub Metadata); - -impl Read for CachedFileMetadata { - fn read(&mut self, buf: &mut [u8]) -> Result { - self.0.read(buf) - } - fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result { - self.0.read_vectored(bufs) - } - fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()> { - self.0.read_buf(cursor) - } - #[inline] - fn is_read_vectored(&self) -> bool { - self.0.is_read_vectored() - } - fn read_to_end(&mut self, buf: &mut Vec) -> Result { - self.0.read_to_end(buf) - } - fn read_to_string(&mut self, buf: &mut String) -> Result { - self.0.read_to_string(buf) - } -} -impl Write for CachedFileMetadata { - fn write(&mut self, buf: &[u8]) -> Result { - self.0.write(buf) - } - fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result { - self.0.write_vectored(bufs) - } - #[inline] - fn is_write_vectored(&self) -> bool { - self.0.is_write_vectored() - } - #[inline] - fn flush(&mut self) -> Result<()> { - self.0.flush() - } -} - impl CopyRead for CachedFileMetadata { fn properties(&self) -> CopyParams { CopyParams(FdMeta::Metadata(self.1.clone()), Some(self.0.as_raw_fd())) From 6de3a2e3a9c45e12f63a8e861131a39b1eb0e021 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 Dec 2024 10:36:32 +0100 Subject: [PATCH 014/113] stabilize const_swap --- library/core/src/intrinsics/mod.rs | 3 ++- library/core/src/lib.rs | 1 - library/core/src/mem/mod.rs | 2 +- library/core/src/ptr/mod.rs | 3 +-- library/core/src/ptr/mut_ptr.rs | 2 +- library/core/src/ptr/non_null.rs | 2 +- library/core/src/slice/mod.rs | 2 +- library/core/tests/lib.rs | 1 - tests/ui/consts/issue-94371.rs | 2 -- .../consts/qualif-indirect-mutation-fail.rs | 1 - .../qualif-indirect-mutation-fail.stderr | 22 +++++++++---------- tests/ui/thread-local/thread-local-static.rs | 1 - .../thread-local/thread-local-static.stderr | 4 ++-- 13 files changed, 20 insertions(+), 26 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 42b8eb33a1a9..9844243d168e 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3954,7 +3954,8 @@ pub const fn is_val_statically_known(_arg: T) -> bool { #[inline] #[rustc_intrinsic] // Const-unstable because `swap_nonoverlapping` is const-unstable. -#[rustc_const_unstable(feature = "const_typed_swap", issue = "none")] +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index a7f741a94089..c7646f9f2709 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -111,7 +111,6 @@ #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(const_eval_select)] -#![feature(const_typed_swap)] #![feature(core_intrinsics)] #![feature(coverage_attribute)] #![feature(internal_impls_macro)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 57acc9dcd6ee..1576eb431529 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -725,7 +725,7 @@ pub unsafe fn uninitialized() -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "mem_swap"] pub const fn swap(x: &mut T, y: &mut T) { // SAFETY: `&mut` guarantees these are typed readable and writable diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index e6e13eaff7b0..ac074c097d94 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1009,9 +1009,8 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "ptr_swap"] -#[rustc_const_stable_indirect] pub const unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 34567917b523..d75d570a969f 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1594,7 +1594,7 @@ impl *mut T { /// /// [`ptr::swap`]: crate::ptr::swap() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[inline(always)] pub const unsafe fn swap(self, with: *mut T) where diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index e0ba469272ed..1058fa42cc1e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1146,7 +1146,7 @@ impl NonNull { /// [`ptr::swap`]: crate::ptr::swap() #[inline(always)] #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn swap(self, with: NonNull) where T: Sized, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ab65f9d6d2fc..3e8c698a7aba 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -913,7 +913,7 @@ impl [T] { /// assert!(v == ["a", "b", "e", "d", "c"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[inline] #[track_caller] pub const fn swap(&mut self, a: usize, b: usize) { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 9f0ab7b3f297..fcb26530fcfe 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -15,7 +15,6 @@ #![feature(clone_to_uninit)] #![feature(const_black_box)] #![feature(const_eval_select)] -#![feature(const_swap)] #![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] diff --git a/tests/ui/consts/issue-94371.rs b/tests/ui/consts/issue-94371.rs index ad9ee9a5a3ef..b2dd7053c1f9 100644 --- a/tests/ui/consts/issue-94371.rs +++ b/tests/ui/consts/issue-94371.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(const_swap)] - #[repr(C)] struct Demo(u64, bool, u64, u32, u64, u64, u64); diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.rs b/tests/ui/consts/qualif-indirect-mutation-fail.rs index c6e08a557c8a..0f59a86b7cc0 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.rs +++ b/tests/ui/consts/qualif-indirect-mutation-fail.rs @@ -1,6 +1,5 @@ //@ compile-flags: --crate-type=lib #![feature(const_precise_live_drops)] -#![feature(const_swap)] // Mutable borrow of a field with drop impl. pub const fn f() { diff --git a/tests/ui/consts/qualif-indirect-mutation-fail.stderr b/tests/ui/consts/qualif-indirect-mutation-fail.stderr index f706b7cf699d..e76d7d3b6705 100644 --- a/tests/ui/consts/qualif-indirect-mutation-fail.stderr +++ b/tests/ui/consts/qualif-indirect-mutation-fail.stderr @@ -1,5 +1,5 @@ error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:13:9 + --> $DIR/qualif-indirect-mutation-fail.rs:12:9 | LL | let mut x = None; | ^^^^^ the destructor for this type cannot be evaluated in constants @@ -19,13 +19,13 @@ note: inside `std::ptr::drop_in_place:: - shim(Some(String))` note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `A1` - --> $DIR/qualif-indirect-mutation-fail.rs:19:1 + --> $DIR/qualif-indirect-mutation-fail.rs:18:1 | LL | }; | ^ error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:29:9 + --> $DIR/qualif-indirect-mutation-fail.rs:28:9 | LL | let _z = x; | ^^ the destructor for this type cannot be evaluated in constants @@ -44,13 +44,13 @@ note: inside `std::ptr::drop_in_place:: - shim(Some(String))` note: inside `std::ptr::drop_in_place::> - shim(Some(Option))` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL note: inside `A2` - --> $DIR/qualif-indirect-mutation-fail.rs:30:1 + --> $DIR/qualif-indirect-mutation-fail.rs:29:1 | LL | }; | ^ error[E0493]: destructor of `(u32, Option)` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:7:9 + --> $DIR/qualif-indirect-mutation-fail.rs:6:9 | LL | let mut a: (u32, Option) = (0, None); | ^^^^^ the destructor for this type cannot be evaluated in constant functions @@ -59,7 +59,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:34:9 + --> $DIR/qualif-indirect-mutation-fail.rs:33:9 | LL | let x: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions @@ -68,7 +68,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:42:9 + --> $DIR/qualif-indirect-mutation-fail.rs:41:9 | LL | let _y = x; | ^^ the destructor for this type cannot be evaluated in constant functions @@ -76,7 +76,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:50:9 + --> $DIR/qualif-indirect-mutation-fail.rs:49:9 | LL | let mut y: Option = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions @@ -85,7 +85,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:47:9 + --> $DIR/qualif-indirect-mutation-fail.rs:46:9 | LL | let mut x: Option = None; | ^^^^^ the destructor for this type cannot be evaluated in constant functions @@ -94,7 +94,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:60:9 + --> $DIR/qualif-indirect-mutation-fail.rs:59:9 | LL | let y: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions @@ -103,7 +103,7 @@ LL | } | - value is dropped here error[E0493]: destructor of `Option` cannot be evaluated at compile-time - --> $DIR/qualif-indirect-mutation-fail.rs:57:9 + --> $DIR/qualif-indirect-mutation-fail.rs:56:9 | LL | let x: Option = None; | ^ the destructor for this type cannot be evaluated in constant functions diff --git a/tests/ui/thread-local/thread-local-static.rs b/tests/ui/thread-local/thread-local-static.rs index af30f5383661..422dac410023 100644 --- a/tests/ui/thread-local/thread-local-static.rs +++ b/tests/ui/thread-local/thread-local-static.rs @@ -1,7 +1,6 @@ //@ edition:2018 #![feature(thread_local)] -#![feature(const_swap)] #![allow(static_mut_refs)] #[thread_local] diff --git a/tests/ui/thread-local/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr index 3bc1aec00c11..bb078b797487 100644 --- a/tests/ui/thread-local/thread-local-static.stderr +++ b/tests/ui/thread-local/thread-local-static.stderr @@ -1,5 +1,5 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or block - --> $DIR/thread-local-static.rs:10:28 + --> $DIR/thread-local-static.rs:9:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ use of mutable static @@ -7,7 +7,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2) = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error[E0625]: thread-local statics cannot be accessed at compile-time - --> $DIR/thread-local-static.rs:10:28 + --> $DIR/thread-local-static.rs:9:28 | LL | std::mem::swap(x, &mut STATIC_VAR_2) | ^^^^^^^^^^^^ From 00dfa3ba2d21577649e882ee65309fdbee08bf6d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 Dec 2024 10:45:48 +0100 Subject: [PATCH 015/113] miri: add test for overlapping typed_swap --- .../rustc_const_eval/src/interpret/intrinsics.rs | 2 +- .../tests/fail/intrinsics/typed-swap-overlap.rs | 13 +++++++++++++ .../fail/intrinsics/typed-swap-overlap.stderr | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs create mode 100644 src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index e9eca8814c3c..44f6335dc7f2 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -649,7 +649,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let kind = MemoryKind::Stack; let temp = self.allocate(left.layout, kind)?; self.copy_op(&left, &temp)?; - self.copy_op(&right, &left)?; + self.copy_op(&right, &left)?; // this checks that they are non-overlapping self.copy_op(&temp, &right)?; self.deallocate_ptr(temp.ptr(), None, kind)?; interp_ok(()) diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs new file mode 100644 index 000000000000..7a9ad63ad7b4 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs @@ -0,0 +1,13 @@ +#![feature(core_intrinsics)] +#![feature(rustc_attrs)] + +use std::intrinsics::typed_swap; +use std::ptr::addr_of_mut; + +fn main() { + let mut a = [0_u8; 100]; + unsafe { + let a = addr_of_mut!(a); + typed_swap(a, a); //~ERROR: called on overlapping ranges + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr new file mode 100644 index 000000000000..5c9cbb78c1ee --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges + --> tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC + | +LL | typed_swap(a, a); + | ^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From 7291b1eaf7db863720f017f9f8a675ada86528e9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 Dec 2024 10:49:23 +0100 Subject: [PATCH 016/113] =?UTF-8?q?rename=20typed=5Fswap=20=E2=86=92=20typ?= =?UTF-8?q?ed=5Fswap=5Fnonoverlapping?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rustc_codegen_ssa/src/mir/intrinsic.rs | 2 +- .../rustc_codegen_ssa/src/traits/builder.rs | 2 +- .../src/interpret/intrinsics.rs | 2 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 4 +++- compiler/rustc_span/src/symbol.rs | 2 +- library/core/src/intrinsics/mod.rs | 19 +++++++++++++++++-- library/core/src/mem/mod.rs | 2 +- .../intrinsics/typed-swap-invalid-array.rs | 4 ++-- .../typed-swap-invalid-array.stderr | 4 ++-- .../intrinsics/typed-swap-invalid-scalar.rs | 4 ++-- .../typed-swap-invalid-scalar.stderr | 4 ++-- .../fail/intrinsics/typed-swap-overlap.rs | 4 ++-- .../fail/intrinsics/typed-swap-overlap.stderr | 4 ++-- tests/codegen/intrinsics/typed_swap.rs | 12 ++++++------ 14 files changed, 43 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 299b98c0a4f0..304ac4544ee4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // If we're swapping something that's *not* an `OperandValue::Ref`, // then we can do it directly and avoid the alloca. // Otherwise, we'll let the fallback MIR body take care of it. - if let sym::typed_swap = name { + if let sym::typed_swap_nonoverlapping = name { let pointee_ty = fn_args.type_at(0); let pointee_layout = bx.layout_of(pointee_ty); if !bx.is_backend_ref(pointee_layout) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index b0138ac8bfed..3ee13b19f665 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -382,7 +382,7 @@ pub trait BuilderMethods<'a, 'tcx>: /// Avoids `alloca`s for Immediates and ScalarPairs. /// /// FIXME: Maybe do something smarter for Ref types too? - /// For now, the `typed_swap` intrinsic just doesn't call this for those + /// For now, the `typed_swap_nonoverlapping` intrinsic just doesn't call this for those /// cases (in non-debug), preferring the fallback body instead. fn typed_place_swap( &mut self, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 44f6335dc7f2..04346af41fc1 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -424,7 +424,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let result = self.raw_eq_intrinsic(&args[0], &args[1])?; self.write_scalar(result, dest)?; } - sym::typed_swap => { + sym::typed_swap_nonoverlapping => { self.typed_swap_intrinsic(&args[0], &args[1])?; } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 394794019109..0f329639cc16 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -496,7 +496,9 @@ pub fn check_intrinsic_type( (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], tcx.types.unit) } - sym::typed_swap => (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit), + sym::typed_swap_nonoverlapping => { + (1, 0, vec![Ty::new_mut_ptr(tcx, param(0)); 2], tcx.types.unit) + } sym::discriminant_value => { let assoc_items = tcx.associated_item_def_ids( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3d202f11722e..b2c259cc5ca1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2058,7 +2058,7 @@ symbols! { type_macros, type_name, type_privacy_lints, - typed_swap, + typed_swap_nonoverlapping, u128, u128_legacy_const_max, u128_legacy_const_min, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 9844243d168e..7d06fc8a692c 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3940,6 +3940,21 @@ pub const fn is_val_statically_known(_arg: T) -> bool { false } +#[rustc_nounwind] +#[inline] +#[rustc_intrinsic] +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(bootstrap)] +pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { + // SAFETY: The caller provided single non-overlapping items behind + // pointers, so swapping them with `count: 1` is fine. + unsafe { ptr::swap_nonoverlapping(x, y, 1) }; +} + +#[cfg(bootstrap)] +pub use typed_swap as typed_swap_nonoverlapping; + /// Non-overlapping *typed* swap of a single value. /// /// The codegen backends will replace this with a better implementation when @@ -3953,10 +3968,10 @@ pub const fn is_val_statically_known(_arg: T) -> bool { #[rustc_nounwind] #[inline] #[rustc_intrinsic] -// Const-unstable because `swap_nonoverlapping` is const-unstable. #[rustc_intrinsic_const_stable_indirect] #[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic -pub const unsafe fn typed_swap(x: *mut T, y: *mut T) { +#[cfg(not(bootstrap))] +pub const unsafe fn typed_swap_nonoverlapping(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. unsafe { ptr::swap_nonoverlapping(x, y, 1) }; diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 1576eb431529..2d66e5c2f2a7 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -730,7 +730,7 @@ pub unsafe fn uninitialized() -> T { pub const fn swap(x: &mut T, y: &mut T) { // SAFETY: `&mut` guarantees these are typed readable and writable // as well as non-overlapping. - unsafe { intrinsics::typed_swap(x, y) } + unsafe { intrinsics::typed_swap_nonoverlapping(x, y) } } /// Replaces `dest` with the default value of `T`, returning the previous `dest` value. diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs index 89fdd2a01ebc..de154d771a0c 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs @@ -1,7 +1,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_array() { @@ -10,7 +10,7 @@ fn invalid_array() { unsafe { let a = addr_of_mut!(a).cast::<[bool; 100]>(); let b = addr_of_mut!(b).cast::<[bool; 100]>(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 20b20412e75a..5884d13a2adc 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value at [0]: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs index 9d014a523f8f..3cc96e79fec5 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs @@ -1,7 +1,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_scalar() { @@ -10,7 +10,7 @@ fn invalid_scalar() { unsafe { let a = addr_of_mut!(a).cast::(); let b = addr_of_mut!(b).cast::(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr index 6062465f36a6..9804233c7fa8 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs index 7a9ad63ad7b4..7b1be4abb153 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs @@ -1,13 +1,13 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn main() { let mut a = [0_u8; 100]; unsafe { let a = addr_of_mut!(a); - typed_swap(a, a); //~ERROR: called on overlapping ranges + typed_swap_nonoverlapping(a, a); //~ERROR: called on overlapping ranges } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr index 5c9cbb78c1ee..6d578841fe5e 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges --> tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC | -LL | typed_swap(a, a); - | ^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges +LL | typed_swap_nonoverlapping(a, a); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/codegen/intrinsics/typed_swap.rs b/tests/codegen/intrinsics/typed_swap.rs index e73931d1d547..6b55078407a4 100644 --- a/tests/codegen/intrinsics/typed_swap.rs +++ b/tests/codegen/intrinsics/typed_swap.rs @@ -8,14 +8,14 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; // CHECK-LABEL: @swap_unit( #[no_mangle] pub unsafe fn swap_unit(x: &mut (), y: &mut ()) { // CHECK: start // CHECK-NEXT: ret void - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_i32( @@ -32,7 +32,7 @@ pub unsafe fn swap_i32(x: &mut i32, y: &mut i32) { // OPT3: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 4, i1 false) // CHECK: store i32 %[[TEMP]], ptr %y, align 4 // CHECK: ret void - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_pair( @@ -47,7 +47,7 @@ pub unsafe fn swap_pair(x: &mut (i32, u32), y: &mut (i32, u32)) { // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x, ptr align 4 %y, i64 8, i1 false) // CHECK: store i32 // CHECK: store i32 - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // CHECK-LABEL: @swap_str( @@ -63,7 +63,7 @@ pub unsafe fn swap_str<'a>(x: &mut &'a str, y: &mut &'a str) { // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 16, i1 false) // CHECK: store ptr // CHECK: store i64 - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } // OPT0-LABEL: @swap_string( @@ -73,5 +73,5 @@ pub unsafe fn swap_string(x: &mut String, y: &mut String) { // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TEMP]], ptr align 8 %x, i64 24, i1 false) // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 24, i1 false) // OPT0: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 %[[TEMP]], i64 24, i1 false) - typed_swap(x, y) + typed_swap_nonoverlapping(x, y) } From 335f7f59c1a4ffa0483f936a905b25f2f58c0263 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 Dec 2024 15:58:57 +0100 Subject: [PATCH 017/113] swap_typed_nonoverlapping: properly detect overlap even when swapping scalar values --- .../rustc_const_eval/src/interpret/call.rs | 14 +-------- .../src/interpret/intrinsics.rs | 28 +++++++++++++---- .../rustc_const_eval/src/interpret/place.rs | 31 +++---------------- ... => typed-swap-invalid-scalar.left.stderr} | 0 .../typed-swap-invalid-scalar.right.stderr | 20 ++++++++++++ .../intrinsics/typed-swap-invalid-scalar.rs | 6 ++-- .../fail/intrinsics/typed-swap-overlap.rs | 2 +- 7 files changed, 53 insertions(+), 48 deletions(-) rename src/tools/miri/tests/fail/intrinsics/{typed-swap-invalid-scalar.stderr => typed-swap-invalid-scalar.left.stderr} (100%) create mode 100644 src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 46720328ea47..99f0ac702c54 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -883,19 +883,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .local_to_op(mir::RETURN_PLACE, None) .expect("return place should always be live"); let dest = self.frame().return_place.clone(); - let res = if self.stack().len() == 1 { - // The initializer of constants and statics will get validated separately - // after the constant has been fully evaluated. While we could fall back to the default - // code path, that will cause -Zenforce-validity to cycle on static initializers. - // Reading from a static's memory is not allowed during its evaluation, and will always - // trigger a cycle error. Validation must read from the memory of the current item. - // For Miri this means we do not validate the root frame return value, - // but Miri anyway calls `read_target_isize` on that so separate validation - // is not needed. - self.copy_op_no_dest_validation(&op, &dest) - } else { - self.copy_op_allow_transmute(&op, &dest) - }; + let res = self.copy_op_allow_transmute(&op, &dest); trace!("return value: {:?}", self.dump_place(&dest.into())); // We delay actually short-circuiting on this error until *after* the stack frame is // popped, since we want this error to be attributed to the caller, whose type defines diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 04346af41fc1..0664a882c1d5 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -425,7 +425,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(result, dest)?; } sym::typed_swap_nonoverlapping => { - self.typed_swap_intrinsic(&args[0], &args[1])?; + self.typed_swap_nonoverlapping_intrinsic(&args[0], &args[1])?; } sym::vtable_size => { @@ -638,19 +638,35 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } /// Does a *typed* swap of `*left` and `*right`. - fn typed_swap_intrinsic( + fn typed_swap_nonoverlapping_intrinsic( &mut self, left: &OpTy<'tcx, >::Provenance>, right: &OpTy<'tcx, >::Provenance>, ) -> InterpResult<'tcx> { let left = self.deref_pointer(left)?; let right = self.deref_pointer(right)?; - debug_assert_eq!(left.layout, right.layout); + assert_eq!(left.layout, right.layout); + assert!(left.layout.is_sized()); let kind = MemoryKind::Stack; let temp = self.allocate(left.layout, kind)?; - self.copy_op(&left, &temp)?; - self.copy_op(&right, &left)?; // this checks that they are non-overlapping - self.copy_op(&temp, &right)?; + self.copy_op(&left, &temp)?; // checks alignment of `left` + + // We want to always enforce non-overlapping, even if this is a scalar type. + // Therefore we directly use the underlying `mem_copy` here. + self.mem_copy(right.ptr(), left.ptr(), left.layout.size, /*nonoverlapping*/ true)?; + // This means we also need to do the validation of the value that used to be in `right` + // ourselves. This value is now in `left.` The one that started out in `left` already got + // validated by the copy above. + if M::enforce_validity(self, left.layout) { + self.validate_operand( + &left.clone().into(), + M::enforce_validity_recursively(self, left.layout), + /*reset_provenance_and_padding*/ true, + )?; + } + + self.copy_op(&temp, &right)?; // checks alignment of `right` + self.deallocate_ptr(temp.ptr(), None, kind)?; interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 810e9356b26c..0d9740716193 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -773,22 +773,6 @@ where interp_ok(()) } - /// Copies the data from an operand to a place. - /// The layouts of the `src` and `dest` may disagree. - /// Does not perform validation of the destination. - /// The only known use case for this function is checking the return - /// value of a static during stack frame popping. - #[inline(always)] - pub(super) fn copy_op_no_dest_validation( - &mut self, - src: &impl Projectable<'tcx, M::Provenance>, - dest: &impl Writeable<'tcx, M::Provenance>, - ) -> InterpResult<'tcx> { - self.copy_op_inner( - src, dest, /* allow_transmute */ true, /* validate_dest */ false, - ) - } - /// Copies the data from an operand to a place. /// The layouts of the `src` and `dest` may disagree. #[inline(always)] @@ -797,9 +781,7 @@ where src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.copy_op_inner( - src, dest, /* allow_transmute */ true, /* validate_dest */ true, - ) + self.copy_op_inner(src, dest, /* allow_transmute */ true) } /// Copies the data from an operand to a place. @@ -810,9 +792,7 @@ where src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.copy_op_inner( - src, dest, /* allow_transmute */ false, /* validate_dest */ true, - ) + self.copy_op_inner(src, dest, /* allow_transmute */ false) } /// Copies the data from an operand to a place. @@ -824,22 +804,21 @@ where src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, allow_transmute: bool, - validate_dest: bool, ) -> InterpResult<'tcx> { // These are technically *two* typed copies: `src` is a not-yet-loaded value, - // so we're going a typed copy at `src` type from there to some intermediate storage. + // so we're doing a typed copy at `src` type from there to some intermediate storage. // And then we're doing a second typed copy from that intermediate storage to `dest`. // But as an optimization, we only make a single direct copy here. // Do the actual copy. self.copy_op_no_validate(src, dest, allow_transmute)?; - if validate_dest && M::enforce_validity(self, dest.layout()) { + if M::enforce_validity(self, dest.layout()) { let dest = dest.to_place(); // Given that there were two typed copies, we have to ensure this is valid at both types, // and we have to ensure this loses provenance and padding according to both types. // But if the types are identical, we only do one pass. - if allow_transmute && src.layout().ty != dest.layout().ty { + if src.layout().ty != dest.layout().ty { self.validate_operand( &dest.transmute(src.layout(), self)?, M::enforce_validity_recursively(self, src.layout()), diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr similarity index 100% rename from src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr rename to src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr new file mode 100644 index 000000000000..54b21f155caa --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: constructing invalid value: encountered 0x03, but expected a boolean + --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + | +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `invalid_scalar` at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC +note: inside `main` + --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + | +LL | invalid_scalar(); + | ^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs index 3cc96e79fec5..d5a72ea8612d 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs @@ -1,3 +1,4 @@ +//@revisions: left right #![feature(core_intrinsics)] #![feature(rustc_attrs)] @@ -5,8 +6,9 @@ use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_scalar() { - let mut a = 1_u8; - let mut b = 2_u8; + // We run the test twice, with either the left or the right side being invalid. + let mut a = if cfg!(left) { 2_u8} else { 1_u8 }; + let mut b = if cfg!(right) { 3_u8} else { 1_u8 }; unsafe { let a = addr_of_mut!(a).cast::(); let b = addr_of_mut!(b).cast::(); diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs index 7b1be4abb153..e643091a02ae 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs @@ -5,7 +5,7 @@ use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn main() { - let mut a = [0_u8; 100]; + let mut a = 0_u8; unsafe { let a = addr_of_mut!(a); typed_swap_nonoverlapping(a, a); //~ERROR: called on overlapping ranges From e5bf8b0f354ed6108f2c8f1806946112ed80989d Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Wed, 25 Dec 2024 16:49:20 +0100 Subject: [PATCH 018/113] Make x86_64-unknown-linux-gno panic=abort and mark as no_std Without a standard library, we cannot unwind, so it should be panic=abort by default. Additionally, it does not have std because while it is Linux, it cannot use libc, which std uses today for Linux. --- .../src/spec/targets/x86_64_unknown_linux_none.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs index 900dbed205c8..2e63ff215728 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs @@ -1,4 +1,4 @@ -use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, base}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, StackProbeType, Target, base}; pub(crate) fn target() -> Target { let mut base = base::linux::opts(); @@ -7,6 +7,7 @@ pub(crate) fn target() -> Target { base.stack_probes = StackProbeType::Inline; base.linker_flavor = LinkerFlavor::Gnu(Cc::No, Lld::Yes); base.linker = Some("rust-lld".into()); + base.panic_strategy = PanicStrategy::Abort; Target { llvm_target: "x86_64-unknown-linux-none".into(), @@ -14,7 +15,7 @@ pub(crate) fn target() -> Target { description: None, tier: None, host_tools: None, - std: Some(true), + std: Some(false), }, pointer_width: 64, data_layout: From bdc8df4cb5f370d23748ba92406a0ed1f0dbea63 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 25 Dec 2024 22:22:23 +0100 Subject: [PATCH 019/113] Improve rustdoc code --- src/librustdoc/clean/mod.rs | 6 +++--- src/librustdoc/doctest.rs | 2 +- src/librustdoc/doctest/make.rs | 2 +- src/librustdoc/formats/cache.rs | 2 +- src/librustdoc/html/escape.rs | 7 +++---- src/librustdoc/html/markdown.rs | 6 +++--- src/librustdoc/html/render/context.rs | 2 +- src/librustdoc/html/render/mod.rs | 2 +- src/librustdoc/html/render/print_item.rs | 2 +- src/librustdoc/json/conversions.rs | 11 +++++------ src/librustdoc/lib.rs | 2 +- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- 12 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4d46f0e75c84..27b7d55f4d08 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -894,7 +894,7 @@ fn clean_ty_generics<'tcx>( // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). // Since all potential trait bounds are at the front we can just check the first bound. - if bounds.first().map_or(true, |b| !b.is_trait_bound()) { + if bounds.first().is_none_or(|b| !b.is_trait_bound()) { bounds.insert(0, GenericBound::sized(cx)); } @@ -1811,7 +1811,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), TyKind::Pat(ty, pat) => Type::Pat(Box::new(clean_ty(ty, cx)), format!("{pat:?}").into()), - TyKind::Array(ty, ref const_arg) => { + TyKind::Array(ty, const_arg) => { // NOTE(min_const_generics): We can't use `const_eval_poly` for constants // as we currently do not supply the parent generics to anonymous constants // but do allow `ConstKind::Param`. @@ -2337,7 +2337,7 @@ fn clean_middle_opaque_bounds<'tcx>( // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). // Since all potential trait bounds are at the front we can just check the first bound. - if bounds.first().map_or(true, |b| !b.is_trait_bound()) { + if bounds.first().is_none_or(|b| !b.is_trait_bound()) { bounds.insert(0, GenericBound::sized(cx)); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e6e5123d0bba..009e9662933a 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -220,7 +220,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions } = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let collector = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); let opts = scrape_test_config(crate_name, crate_attrs, args_path); diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index a188bc8ebd91..7bcb9465948d 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -538,7 +538,7 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit // If it's complete, then we can clear the pending content. mod_attr_pending.clear(); } else { - mod_attr_pending.push_str("\n"); + mod_attr_pending.push('\n'); } } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b63122565c42..3890a9aab1b6 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -413,7 +413,7 @@ impl DocFolder for CacheBuilder<'_, '_> { let impl_item = Impl { impl_item: item }; let impl_did = impl_item.def_id(); let trait_did = impl_item.trait_did(); - if trait_did.map_or(true, |d| self.cache.traits.contains_key(&d)) { + if trait_did.is_none_or(|d| self.cache.traits.contains_key(&d)) { for did in dids { if self.impl_ids.entry(did).or_default().insert(impl_did) { self.cache.impls.entry(did).or_default().push(impl_item.clone()); diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 48771571f8ff..88654ed32da9 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -104,10 +104,9 @@ impl fmt::Display for EscapeBodyTextWithWbr<'_> { continue; } let is_uppercase = || s.chars().any(|c| c.is_uppercase()); - let next_is_uppercase = - || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase())); - let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_')); - let next_is_colon = || pk.map_or(true, |(_, t)| t.contains(':')); + let next_is_uppercase = || pk.is_none_or(|(_, t)| t.chars().any(|c| c.is_uppercase())); + let next_is_underscore = || pk.is_none_or(|(_, t)| t.contains('_')); + let next_is_colon = || pk.is_none_or(|(_, t)| t.contains(':')); // Check for CamelCase. // // `i - last > 3` avoids turning FmRadio into FmRadio, which is technically diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index aa8fdaaee4cb..7e835585b73e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -480,7 +480,7 @@ impl<'a, I: Iterator>> Iterator for SpannedLinkReplacer< type Item = SpannedEvent<'a>; fn next(&mut self) -> Option { - let Some((mut event, range)) = self.iter.next() else { return None }; + let (mut event, range) = self.iter.next()?; self.inner.handle_event(&mut event); // Yield the modified event Some((event, range)) @@ -2039,7 +2039,7 @@ impl IdMap { let candidate = candidate.to_string(); if is_default_id(&candidate) { let id = format!("{}-{}", candidate, 1); - self.map.insert(candidate.into(), 2); + self.map.insert(candidate, 2); id } else { candidate @@ -2052,7 +2052,7 @@ impl IdMap { } }; - self.map.insert(id.clone().into(), 1); + self.map.insert(id.clone(), 1); id } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 2d5df75e7dc1..5d96dbc0ee65 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -748,7 +748,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { &shared.layout, &page, "", - scrape_examples_help(&shared), + scrape_examples_help(shared), &shared.style_files, ); shared.fs.write(scrape_examples_help_file, v)?; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index dfdf2cd6ec32..9a9ce31caaa4 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1974,7 +1974,7 @@ fn render_impl( .opt_doc_value() .map(|dox| { Markdown { - content: &*dox, + content: &dox, links: &i.impl_item.links(cx), ids: &mut cx.id_map.borrow_mut(), error_codes: cx.shared.codes, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0fb77d38f165..e8230e63c0f6 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1420,7 +1420,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni ty: &'a clean::Type, ) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let v = ty.print(&self.cx); + let v = ty.print(self.cx); write!(f, "{v}") }) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 583d0214a468..7f072aa7e2fc 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -312,15 +312,15 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { StructFieldItem(f) => ItemEnum::StructField(f.into_json(renderer)), EnumItem(e) => ItemEnum::Enum(e.into_json(renderer)), VariantItem(v) => ItemEnum::Variant(v.into_json(renderer)), - FunctionItem(f) => ItemEnum::Function(from_function(f, true, header.unwrap(), renderer)), + FunctionItem(f) => ItemEnum::Function(from_function(*f, true, header.unwrap(), renderer)), ForeignFunctionItem(f, _) => { - ItemEnum::Function(from_function(f, false, header.unwrap(), renderer)) + ItemEnum::Function(from_function(*f, false, header.unwrap(), renderer)) } TraitItem(t) => ItemEnum::Trait((*t).into_json(renderer)), TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_json(renderer)), - MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), + MethodItem(m, _) => ItemEnum::Function(from_function(*m, true, header.unwrap(), renderer)), RequiredMethodItem(m) => { - ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)) + ItemEnum::Function(from_function(*m, false, header.unwrap(), renderer)) } ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), @@ -730,12 +730,11 @@ impl FromClean for Impl { } pub(crate) fn from_function( - function: Box, + clean::Function { decl, generics }: clean::Function, has_body: bool, header: rustc_hir::FnHeader, renderer: &JsonRenderer<'_>, ) -> Function { - let clean::Function { decl, generics } = *function; Function { sig: decl.into_json(renderer), generics: generics.into_json(renderer), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ff1c9c61720f..d74dcc98cb05 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -869,7 +869,7 @@ fn main_args( sess.dcx().fatal("Compilation failed, aborting rustdoc"); } - rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { core::run_global_ctxt(tcx, show_coverage, render_options, output_format) }); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3c1d0c35befa..a777b45b8070 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1977,7 +1977,7 @@ fn resolution_failure( } if !path_str.contains("::") { - if disambiguator.map_or(true, |d| d.ns() == MacroNS) + if disambiguator.is_none_or(|d| d.ns() == MacroNS) && collector .cx .tcx From 01307cf03f5b95759a8e84bce659f6326e247049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 24 Dec 2024 23:41:50 +0000 Subject: [PATCH 020/113] Implement `default_overrides_default_fields` lint Detect when a manual `Default` implementation isn't using the existing default field values and suggest using `..` instead: ``` error: `Default` impl doesn't use the declared default field values --> $DIR/manual-default-impl-could-be-derived.rs:14:1 | LL | / impl Default for A { LL | | fn default() -> Self { LL | | A { LL | | y: 0, | | - this field has a default value ... | LL | | } | |_^ | = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time note: the lint level is defined here --> $DIR/manual-default-impl-could-be-derived.rs:5:9 | LL | #![deny(default_overrides_default_fields)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` --- .../src/default_could_be_derived.rs | 185 +++++++++++++++++ compiler/rustc_lint/src/lib.rs | 3 + .../manual-default-impl-could-be-derived.rs | 194 ++++++++++++++++++ ...anual-default-impl-could-be-derived.stderr | 144 +++++++++++++ 4 files changed, 526 insertions(+) create mode 100644 compiler/rustc_lint/src/default_could_be_derived.rs create mode 100644 tests/ui/structs/manual-default-impl-could-be-derived.rs create mode 100644 tests/ui/structs/manual-default-impl-could-be-derived.stderr diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs new file mode 100644 index 000000000000..d95cbb051580 --- /dev/null +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -0,0 +1,185 @@ +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Diag; +use rustc_hir as hir; +use rustc_middle::ty; +use rustc_session::{declare_lint, impl_lint_pass}; +use rustc_span::Symbol; +use rustc_span::symbol::sym; + +use crate::{LateContext, LateLintPass}; + +declare_lint! { + /// The `default_overrides_default_fields` lint checks for manual `impl` blocks of the + /// `Default` trait of types with default field values. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![feature(default_field_values)] + /// struct Foo { + /// x: i32 = 101, + /// y: NonDefault, + /// } + /// + /// struct NonDefault; + /// + /// #[deny(default_overrides_default_fields)] + /// impl Default for Foo { + /// fn default() -> Foo { + /// Foo { x: 100, y: NonDefault } + /// } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Manually writing a `Default` implementation for a type that has + /// default field values runs the risk of diverging behavior between + /// `Type { .. }` and `::default()`, which would be a + /// foot-gun for users of that type that would expect these to be + /// equivalent. If `Default` can't be derived due to some fields not + /// having a `Default` implementation, we encourage the use of `..` for + /// the fields that do have a default field value. + pub DEFAULT_OVERRIDES_DEFAULT_FIELDS, + Deny, + "detect `Default` impl that should use the type's default field values", + @feature_gate = default_field_values; +} + +#[derive(Default)] +pub(crate) struct DefaultCouldBeDerived; + +impl_lint_pass!(DefaultCouldBeDerived => [DEFAULT_OVERRIDES_DEFAULT_FIELDS]); + +impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { + fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) { + // Look for manual implementations of `Default`. + let Some(default_def_id) = cx.tcx.get_diagnostic_item(sym::Default) else { return }; + let hir::ImplItemKind::Fn(_sig, body_id) = impl_item.kind else { return }; + let assoc = cx.tcx.associated_item(impl_item.owner_id); + let parent = assoc.container_id(cx.tcx); + if cx.tcx.has_attr(parent, sym::automatically_derived) { + // We don't care about what `#[derive(Default)]` produces in this lint. + return; + } + let Some(trait_ref) = cx.tcx.impl_trait_ref(parent) else { return }; + let trait_ref = trait_ref.instantiate_identity(); + if trait_ref.def_id != default_def_id { + return; + } + let ty = trait_ref.self_ty(); + let ty::Adt(def, _) = ty.kind() else { return }; + + // We now know we have a manually written definition of a `::default()`. + + let hir = cx.tcx.hir(); + + let type_def_id = def.did(); + let body = hir.body(body_id); + + // FIXME: evaluate bodies with statements and evaluate bindings to see if they would be + // derivable. + let hir::ExprKind::Block(hir::Block { stmts: _, expr: Some(expr), .. }, None) = + body.value.kind + else { + return; + }; + + // Keep a mapping of field name to `hir::FieldDef` for every field in the type. We'll use + // these to check for things like checking whether it has a default or using its span for + // suggestions. + let orig_fields = match hir.get_if_local(type_def_id) { + Some(hir::Node::Item(hir::Item { + kind: + hir::ItemKind::Struct(hir::VariantData::Struct { fields, recovered: _ }, _generics), + .. + })) => fields.iter().map(|f| (f.ident.name, f)).collect::>(), + _ => return, + }; + + // We check `fn default()` body is a single ADT literal and get all the fields that are + // being set. + let hir::ExprKind::Struct(_qpath, fields, tail) = expr.kind else { return }; + + // We have a struct literal + // + // struct Foo { + // field: Type, + // } + // + // impl Default for Foo { + // fn default() -> Foo { + // Foo { + // field: val, + // } + // } + // } + // + // We would suggest `#[derive(Default)]` if `field` has a default value, regardless of what + // it is; we don't want to encourage divergent behavior between `Default::default()` and + // `..`. + + if let hir::StructTailExpr::Base(_) = tail { + // This is *very* niche. We'd only get here if someone wrote + // impl Default for Ty { + // fn default() -> Ty { + // Ty { ..something() } + // } + // } + // where `something()` would have to be a call or path. + // We have nothing meaninful to do with this. + return; + } + + // At least one of the fields with a default value have been overriden in + // the `Default` implementation. We suggest removing it and relying on `..` + // instead. + let any_default_field_given = + fields.iter().any(|f| orig_fields.get(&f.ident.name).and_then(|f| f.default).is_some()); + + if !any_default_field_given { + // None of the default fields were actually provided explicitly, so the manual impl + // doesn't override them (the user used `..`), so there's no risk of divergent behavior. + return; + } + + let Some(local) = parent.as_local() else { return }; + let hir_id = cx.tcx.local_def_id_to_hir_id(local); + let hir::Node::Item(item) = cx.tcx.hir_node(hir_id) else { return }; + cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, item.span, |diag| { + mk_lint(diag, orig_fields, fields); + }); + } +} + +fn mk_lint( + diag: &mut Diag<'_, ()>, + orig_fields: FxHashMap>, + fields: &[hir::ExprField<'_>], +) { + diag.primary_message("`Default` impl doesn't use the declared default field values"); + + // For each field in the struct expression + // - if the field in the type has a default value, it should be removed + // - elif the field is an expression that could be a default value, it should be used as the + // field's default value (FIXME: not done). + // - else, we wouldn't touch this field, it would remain in the manual impl + let mut removed_all_fields = true; + for field in fields { + if orig_fields.get(&field.ident.name).and_then(|f| f.default).is_some() { + diag.span_label(field.expr.span, "this field has a default value"); + } else { + removed_all_fields = false; + } + } + + diag.help(if removed_all_fields { + "to avoid divergence in behavior between `Struct { .. }` and \ + `::default()`, derive the `Default`" + } else { + "use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them \ + diverging over time" + }); +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index d7f0d2a6941f..1465c2cff7bc 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -41,6 +41,7 @@ mod async_fn_in_trait; pub mod builtin; mod context; mod dangling; +mod default_could_be_derived; mod deref_into_dyn_supertrait; mod drop_forget_useless; mod early; @@ -85,6 +86,7 @@ use async_closures::AsyncClosureUsage; use async_fn_in_trait::AsyncFnInTrait; use builtin::*; use dangling::*; +use default_could_be_derived::DefaultCouldBeDerived; use deref_into_dyn_supertrait::*; use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; @@ -189,6 +191,7 @@ late_lint_methods!( BuiltinCombinedModuleLateLintPass, [ ForLoopsOverFallibles: ForLoopsOverFallibles, + DefaultCouldBeDerived: DefaultCouldBeDerived::default(), DerefIntoDynSupertrait: DerefIntoDynSupertrait, DropForgetUseless: DropForgetUseless, ImproperCTypesDeclarations: ImproperCTypesDeclarations, diff --git a/tests/ui/structs/manual-default-impl-could-be-derived.rs b/tests/ui/structs/manual-default-impl-could-be-derived.rs new file mode 100644 index 000000000000..773b73899886 --- /dev/null +++ b/tests/ui/structs/manual-default-impl-could-be-derived.rs @@ -0,0 +1,194 @@ +// Warn when we encounter a manual `Default` impl that could be derived. +// Restricted only to types using `default_field_values`. +#![feature(default_field_values)] +#![allow(dead_code)] +#![deny(default_overrides_default_fields)] +struct S(i32); +fn s() -> S { S(1) } + +struct A { + x: S, + y: i32 = 1, +} + +impl Default for A { //~ ERROR default_overrides_default_fields + fn default() -> Self { + A { + y: 0, + x: s(), + } + } +} + +struct B { + x: S = S(3), + y: i32 = 1, +} + +impl Default for B { //~ ERROR default_overrides_default_fields + fn default() -> Self { + B { + x: s(), + y: 0, + } + } +} + +struct C { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for C { //~ ERROR default_overrides_default_fields + fn default() -> Self { + C { + x: s(), + y: 0, + .. + } + } +} + +struct D { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for D { //~ ERROR default_overrides_default_fields + fn default() -> Self { + D { + y: 0, + x: s(), + .. + } + } +} + +struct E { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for E { //~ ERROR default_overrides_default_fields + fn default() -> Self { + E { + y: 0, + z: 0, + x: s(), + } + } +} + +// Let's ensure that the span for `x` and the span for `y` don't overlap when suggesting their +// removal in favor of their default field values. +struct E2 { + x: S, + y: i32 = 1, + z: i32 = 1, +} + +impl Default for E2 { //~ ERROR default_overrides_default_fields + fn default() -> Self { + E2 { + x: s(), + y: i(), + z: 0, + } + } +} + +fn i() -> i32 { + 1 +} + +// Account for a `const fn` being the `Default::default()` of a field's type. +struct F { + x: G, + y: i32 = 1, +} + +impl Default for F { //~ ERROR default_overrides_default_fields + fn default() -> Self { + F { + x: g_const(), + y: 0, + } + } +} + +struct G; + +impl Default for G { // ok + fn default() -> Self { + g_const() + } +} + +const fn g_const() -> G { + G +} + +// Account for a `const fn` being used in `Default::default()`, even if the type doesn't use it as +// its own `Default`. We suggest setting the default field value in that case. +struct H { + x: I, + y: i32 = 1, +} + +impl Default for H { //~ ERROR default_overrides_default_fields + fn default() -> Self { + H { + x: i_const(), + y: 0, + } + } +} + +struct I; + +const fn i_const() -> I { + I +} + +// Account for a `const` and struct literal being the `Default::default()` of a field's type. +struct M { + x: N, + y: i32 = 1, + z: A, +} + +impl Default for M { // ok, `y` is not specified + fn default() -> Self { + M { + x: N_CONST, + z: A { + x: S(0), + y: 0, + }, + .. + } + } +} + +struct N; + +const N_CONST: N = N; + +struct O { + x: Option, + y: i32 = 1, +} + +impl Default for O { //~ ERROR default_overrides_default_fields + fn default() -> Self { + O { + x: None, + y: 1, + } + } +} + +fn main() {} diff --git a/tests/ui/structs/manual-default-impl-could-be-derived.stderr b/tests/ui/structs/manual-default-impl-could-be-derived.stderr new file mode 100644 index 000000000000..e8f607fac7ed --- /dev/null +++ b/tests/ui/structs/manual-default-impl-could-be-derived.stderr @@ -0,0 +1,144 @@ +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:14:1 + | +LL | / impl Default for A { +LL | | fn default() -> Self { +LL | | A { +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time +note: the lint level is defined here + --> $DIR/manual-default-impl-could-be-derived.rs:5:9 + | +LL | #![deny(default_overrides_default_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:28:1 + | +LL | / impl Default for B { +LL | | fn default() -> Self { +LL | | B { +LL | | x: s(), + | | --- this field has a default value +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: to avoid divergence in behavior between `Struct { .. }` and `::default()`, derive the `Default` + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:43:1 + | +LL | / impl Default for C { +LL | | fn default() -> Self { +LL | | C { +LL | | x: s(), +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:59:1 + | +LL | / impl Default for D { +LL | | fn default() -> Self { +LL | | D { +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:75:1 + | +LL | / impl Default for E { +LL | | fn default() -> Self { +LL | | E { +LL | | y: 0, + | | - this field has a default value +LL | | z: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:93:1 + | +LL | / impl Default for E2 { +LL | | fn default() -> Self { +LL | | E2 { +LL | | x: s(), +LL | | y: i(), + | | --- this field has a default value +LL | | z: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:113:1 + | +LL | / impl Default for F { +LL | | fn default() -> Self { +LL | | F { +LL | | x: g_const(), +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:141:1 + | +LL | / impl Default for H { +LL | | fn default() -> Self { +LL | | H { +LL | | x: i_const(), +LL | | y: 0, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: `Default` impl doesn't use the declared default field values + --> $DIR/manual-default-impl-could-be-derived.rs:185:1 + | +LL | / impl Default for O { +LL | | fn default() -> Self { +LL | | O { +LL | | x: None, +LL | | y: 1, + | | - this field has a default value +... | +LL | | } + | |_^ + | + = help: use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them diverging over time + +error: aborting due to 9 previous errors + From d0c1975e4b458e30eeab37b9cd4e455f8c69cf4d Mon Sep 17 00:00:00 2001 From: wtlin1228 Date: Thu, 26 Dec 2024 13:56:45 +0800 Subject: [PATCH 021/113] docs: update code example for Iterator#rposition --- library/core/src/iter/traits/iterator.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index ff39e8ac25f8..91c3a4b29b53 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3051,6 +3051,7 @@ pub trait Iterator { /// /// // we can still use `iter`, as there are more elements. /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next_back(), Some(&3)); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] From 1511de3c9e7716a4fd7aa7ea53140b2c44c8a4dd Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 26 Dec 2024 15:47:26 +1100 Subject: [PATCH 022/113] Add more `begin_panic` normalizations to panic backtrace tests --- tests/ui/panics/issue-47429-short-backtraces.rs | 2 ++ tests/ui/panics/issue-47429-short-backtraces.run.stderr | 2 +- tests/ui/panics/runtime-switch.rs | 2 ++ tests/ui/panics/runtime-switch.run.stderr | 2 +- tests/ui/panics/short-ice-remove-middle-frames-2.rs | 2 ++ tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr | 2 +- tests/ui/panics/short-ice-remove-middle-frames.rs | 2 ++ tests/ui/panics/short-ice-remove-middle-frames.run.stderr | 2 +- 8 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/ui/panics/issue-47429-short-backtraces.rs b/tests/ui/panics/issue-47429-short-backtraces.rs index 0d216fdd6530..56b9cfcd3615 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.rs +++ b/tests/ui/panics/issue-47429-short-backtraces.rs @@ -9,6 +9,8 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. //@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. //@ normalize-stderr-test: "\n +at [^\n]+" -> "" diff --git a/tests/ui/panics/issue-47429-short-backtraces.run.stderr b/tests/ui/panics/issue-47429-short-backtraces.run.stderr index 1078a2fbc902..6a22e0215fee 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.run.stderr +++ b/tests/ui/panics/issue-47429-short-backtraces.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:24:5: +thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:26:5: explicit panic stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/runtime-switch.rs b/tests/ui/panics/runtime-switch.rs index 10dce2509093..e06f05d5fe8e 100644 --- a/tests/ui/panics/runtime-switch.rs +++ b/tests/ui/panics/runtime-switch.rs @@ -9,6 +9,8 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. //@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. //@ normalize-stderr-test: "\n +at [^\n]+" -> "" diff --git a/tests/ui/panics/runtime-switch.run.stderr b/tests/ui/panics/runtime-switch.run.stderr index abbb91eba60e..35be010d6be7 100644 --- a/tests/ui/panics/runtime-switch.run.stderr +++ b/tests/ui/panics/runtime-switch.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/runtime-switch.rs:27:5: +thread 'main' panicked at $DIR/runtime-switch.rs:29:5: explicit panic stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs index c2f04cd122c7..9b6d34d97b2f 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs @@ -12,6 +12,8 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. //@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. //@ normalize-stderr-test: "\n +at [^\n]+" -> "" diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr index 67577f3568e9..ab23ce780625 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:61:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:63:5: debug!!! stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs index c035e7e69bc6..b1af247130b1 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames.rs @@ -13,6 +13,8 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. //@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +// This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) +//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. //@ normalize-stderr-test: "\n +at [^\n]+" -> "" diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr index 63fa466ab24a..d2616911e3bf 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:57:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:59:5: debug!!! stack backtrace: 0: std::panicking::begin_panic From f806357999179a6be4bd8ecbfd3ab330eaf60a20 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 26 Dec 2024 16:09:30 +0100 Subject: [PATCH 023/113] unwinding: bump version to fix asm With #80608 the `unwinding` crate no longer builds. The upstream crate has been updated to build by manually adding directives to the naked_asm stream. Bump the dependency in Rust to get this newer version. This fixes the build for Xous, and closes #134403. Signed-off-by: Sean Cross --- library/Cargo.lock | 4 ++-- library/unwind/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index 22f6e1edf21f..15ca4cbff7b7 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -403,9 +403,9 @@ dependencies = [ [[package]] name = "unwinding" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2c6cb20f236dae10c69b0b45d82ef50af8b7e45c10e429e7901d26b49b4dbf3" +checksum = "51f06a05848f650946acef3bf525fe96612226b61f74ae23ffa4e98bfbb8ab3c" dependencies = [ "compiler_builtins", "gimli 0.31.1", diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 96ddae16f0ab..e13c9a06c05d 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -22,7 +22,7 @@ cfg-if = "1.0" libc = { version = "0.2.140", features = ['rustc-dep-of-std'], default-features = false } [target.'cfg(target_os = "xous")'.dependencies] -unwinding = { version = "0.2.3", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false } +unwinding = { version = "0.2.5", features = ['rustc-dep-of-std', 'unwinder', 'fde-custom'], default-features = false } [features] From 40b0026a2f1c50e88909f49e8ef8c7ae074f5a9b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 26 Dec 2024 08:58:17 -0700 Subject: [PATCH 024/113] docs: inline `std::ffi::c_str` types to `std::ffi` Rustdoc has no way to show that an item is stable, but only at a different path. `std::ffi::c_str::NulError` is not stable, but `std::ffi::NulError` is. To avoid marking these types as unstable when someone just wants to follow a link from `CString`, inline them into their stable paths. --- library/std/src/ffi/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 469136be8838..7d7cce09a3f0 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -179,19 +179,19 @@ pub use core::ffi::{ c_ulong, c_ulonglong, c_ushort, }; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use self::c_str::FromBytesUntilNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes", since = "1.10.0")] pub use self::c_str::FromBytesWithNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] pub use self::c_str::FromVecWithNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstring_into", since = "1.7.0")] pub use self::c_str::IntoStringError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use self::c_str::NulError; #[doc(inline)] From 485c20d2489d94e2e1aead9788b5ff5973550510 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 26 Dec 2024 12:33:10 +0300 Subject: [PATCH 025/113] replace bootstrap-self-test feature flag with cfg(test) This makes it in more rusty way. Signed-off-by: onur-ozkan --- src/bootstrap/Cargo.toml | 1 - src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 3 +-- src/bootstrap/src/core/config/config.rs | 10 +++++----- src/bootstrap/src/core/download.rs | 14 +++++++------- src/bootstrap/src/core/sanity.rs | 11 +++++------ 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 6da716b7a895..d8775a67e193 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -7,7 +7,6 @@ default-run = "bootstrap" [features] build-metrics = ["sysinfo"] -bootstrap-self-test = [] # enabled in the bootstrap unit tests [lib] path = "src/lib.rs" diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6700f3ba680b..a6893db094a2 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -417,7 +417,7 @@ fn copy_self_contained_objects( /// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.). pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec { // FIXME: Extend builder tests to cover the `crates` field of `Std` instances. - if cfg!(feature = "bootstrap-self-test") { + if cfg!(test) { return vec![]; } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 8d9d2b6b6a13..7955bd42cb9f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3148,9 +3148,8 @@ impl Step for Bootstrap { let mut cmd = command(&builder.initial_cargo); cmd.arg("test") - .args(["--features", "bootstrap-self-test"]) .current_dir(builder.src.join("src/bootstrap")) - .env("RUSTFLAGS", "-Cdebuginfo=2") + .env("RUSTFLAGS", "--cfg test -Cdebuginfo=2") .env("CARGO_TARGET_DIR", builder.out.join("bootstrap")) .env("RUSTC_BOOTSTRAP", "1") .env("RUSTDOC", builder.rustdoc(compiler)) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 435216ef534c..d54a93179d96 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1441,7 +1441,7 @@ impl Config { // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, // but not if `config.toml` hasn't been created. let mut toml = if !using_default_path || toml_path.exists() { - config.config = Some(if cfg!(not(feature = "bootstrap-self-test")) { + config.config = Some(if cfg!(not(test)) { toml_path.canonicalize().unwrap() } else { toml_path.clone() @@ -2793,11 +2793,11 @@ impl Config { } } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {} /// check rustc/cargo version is same or lower with 1 apart from the building one - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub fn check_stage0_version(&self, program_path: &Path, component_name: &'static str) { use build_helper::util::fail; @@ -2939,7 +2939,7 @@ impl Config { } // Fetching the LLVM submodule is unnecessary for self-tests. - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] self.update_submodule("src/llvm-project"); // Check for untracked changes in `src/llvm-project`. @@ -3014,7 +3014,7 @@ impl Config { /// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options. /// It does this by destructuring the `Llvm` instance to make sure every `Llvm` field is covered and not missing. -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] pub(crate) fn check_incompatible_options_for_ci_llvm( current_config_toml: TomlConfig, ci_config_toml: TomlConfig, diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index db35e6907e66..6a143467f600 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -444,14 +444,14 @@ impl Config { cargo_clippy } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn maybe_download_rustfmt(&self) -> Option { None } /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't /// reuse target directories or artifacts - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn maybe_download_rustfmt(&self) -> Option { use build_helper::stage0_parser::VersionMetadata; @@ -534,10 +534,10 @@ impl Config { ); } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn download_beta_toolchain(&self) {} - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn download_beta_toolchain(&self) { self.verbose(|| println!("downloading stage0 beta artifacts")); @@ -714,10 +714,10 @@ download-rustc = false self.unpack(&tarball, &bin_root, prefix); } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn maybe_download_ci_llvm(&self) {} - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn maybe_download_ci_llvm(&self) { use build_helper::exit; @@ -789,7 +789,7 @@ download-rustc = false }; } - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] fn download_ci_llvm(&self, llvm_sha: &str) { let llvm_assertions = self.llvm_assertions; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index dcf68cbeeda7..ed0155622c22 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -14,10 +14,10 @@ use std::path::PathBuf; use std::{env, fs}; use crate::Build; -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] use crate::builder::Builder; use crate::builder::Kind; -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] use crate::core::build_steps::tool; use crate::core::config::Target; use crate::utils::exec::command; @@ -38,7 +38,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ /// Minimum version threshold for libstdc++ required when using prebuilt LLVM /// from CI (with`llvm.download-ci-llvm` option). -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] const LIBSTDCXX_MIN_VERSION_THRESHOLD: usize = 8; impl Finder { @@ -106,7 +106,7 @@ pub fn check(build: &mut Build) { } // Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`. - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci { let builder = Builder::new(build); let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build }); @@ -226,8 +226,7 @@ than building it. } // Ignore fake targets that are only used for unit tests in bootstrap. - if cfg!(not(feature = "bootstrap-self-test")) && !skip_target_sanity && !build.local_rebuild - { + if cfg!(not(test)) && !skip_target_sanity && !build.local_rebuild { let mut has_target = false; let target_str = target.to_string(); From d6c5a6bd3adcc5bb5f077818432a5e3efb224ec0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Dec 2024 17:35:07 +0000 Subject: [PATCH 026/113] nit: Remove redundant function --- compiler/rustc_infer/src/infer/region_constraints/mod.rs | 4 ---- compiler/rustc_trait_selection/src/traits/auto_trait.rs | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 6dce4b2b21df..6496f38269a5 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -299,10 +299,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.storage.var_infos.len() } - pub fn region_constraint_data(&self) -> &RegionConstraintData<'tcx> { - &self.storage.data - } - /// Takes (and clears) the current set of constraints. Note that /// the set of variables remains intact, but all relationships /// between them are reset. This is used during NLL checking to diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6730f28893d1..9a53e8a5d519 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -161,8 +161,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let outlives_env = OutlivesEnvironment::new(full_env); let _ = infcx.process_registered_region_obligations(&outlives_env, |ty, _| Ok(ty)); - let region_data = - infcx.inner.borrow_mut().unwrap_region_constraints().region_constraint_data().clone(); + let region_data = infcx.inner.borrow_mut().unwrap_region_constraints().data().clone(); let vid_to_region = self.map_vid_to_region(®ion_data); From 12d66d95069ef79bdc4fa3a3de388718a8644a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 22 Dec 2024 20:20:02 +0000 Subject: [PATCH 027/113] Account for removal of multiline span in suggestion When highlighting the removed parts of a suggestion, properly account for spans that cover more than one line. Fix #134485. --- compiler/rustc_errors/src/emitter.rs | 86 ++- .../multiline-removal-suggestion.rs | 58 ++ .../multiline-removal-suggestion.svg | 504 ++++++++++++++++++ 3 files changed, 641 insertions(+), 7 deletions(-) create mode 100644 tests/ui/error-emitter/multiline-removal-suggestion.rs create mode 100644 tests/ui/error-emitter/multiline-removal-suggestion.svg diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 977721a5b8a2..f938352820df 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2216,6 +2216,11 @@ impl HumanEmitter { show_code_change { for part in parts { + let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) { + snippet + } else { + String::new() + }; let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display; @@ -2263,13 +2268,80 @@ impl HumanEmitter { } if let DisplaySuggestion::Diff = show_code_change { // Colorize removal with red in diff format. - buffer.set_style_range( - row_num - 2, - (padding as isize + span_start_pos as isize) as usize, - (padding as isize + span_end_pos as isize) as usize, - Style::Removal, - true, - ); + + // Below, there's some tricky buffer indexing going on. `row_num` at this + // point corresponds to: + // + // | + // LL | CODE + // | ++++ <- `row_num` + // + // in the buffer. When we have a diff format output, we end up with + // + // | + // LL - OLDER <- row_num - 2 + // LL + NEWER + // | <- row_num + // + // The `row_num - 2` is to select the buffer line that has the "old version + // of the diff" at that point. When the removal is a single line, `i` is + // `0`, `newlines` is `1` so `(newlines - i - 1)` ends up being `0`, so row + // points at `LL - OLDER`. When the removal corresponds to multiple lines, + // we end up with `newlines > 1` and `i` being `0..newlines - 1`. + // + // | + // LL - OLDER <- row_num - 2 - (newlines - last_i - 1) + // LL - CODE + // LL - BEING + // LL - REMOVED <- row_num - 2 - (newlines - first_i - 1) + // LL + NEWER + // | <- row_num + + let newlines = snippet.lines().count(); + if newlines > 0 && row_num > newlines { + // Account for removals where the part being removed spans multiple + // lines. + // FIXME: We check the number of rows because in some cases, like in + // `tests/ui/lint/invalid-nan-comparison-suggestion.rs`, the rendered + // suggestion will only show the first line of code being replaced. The + // proper way of doing this would be to change the suggestion rendering + // logic to show the whole prior snippet, but the current output is not + // too bad to begin with, so we side-step that issue here. + for (i, line) in snippet.lines().enumerate() { + let line = normalize_whitespace(line); + let row = row_num - 2 - (newlines - i - 1); + // On the first line, we highlight between the start of the part + // span, and the end of that line. + // On the last line, we highlight between the start of the line, and + // the column of the part span end. + // On all others, we highlight the whole line. + let start = if i == 0 { + (padding as isize + span_start_pos as isize) as usize + } else { + padding + }; + let end = if i == 0 { + (padding as isize + + span_start_pos as isize + + line.len() as isize) + as usize + } else if i == newlines - 1 { + (padding as isize + span_end_pos as isize) as usize + } else { + (padding as isize + line.len() as isize) as usize + }; + buffer.set_style_range(row, start, end, Style::Removal, true); + } + } else { + // The removed code fits all in one line. + buffer.set_style_range( + row_num - 2, + (padding as isize + span_start_pos as isize) as usize, + (padding as isize + span_end_pos as isize) as usize, + Style::Removal, + true, + ); + } } // length of the code after substitution diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.rs b/tests/ui/error-emitter/multiline-removal-suggestion.rs new file mode 100644 index 000000000000..72e9ea357c9e --- /dev/null +++ b/tests/ui/error-emitter/multiline-removal-suggestion.rs @@ -0,0 +1,58 @@ +// Make sure suggestion for removal of a span that covers multiple lines is properly highlighted. +//@ compile-flags: --error-format=human --color=always +//@ edition:2018 +//@ only-linux +// ignore-tidy-tab +// We use `\t` instead of spaces for indentation to ensure that the highlighting logic properly +// accounts for replaced characters (like we do for `\t` with ` `). The naïve way of highlighting +// could be counting chars of the original code, instead of operating on the code as it is being +// displayed. +use std::collections::{HashMap, HashSet}; +fn foo() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter() + .map(|t| { + ( + is_true, + t, + ) + }).flatten() + }) + .flatten() + .collect() +} +fn bar() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter() + .map(|t| (is_true, t)) + .flatten() + }) + .flatten() + .collect() +} +fn baz() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter().map(|t| { + (is_true, t) + }).flatten() + }) + .flatten() + .collect() +} +fn bay() -> Vec<(bool, HashSet)> { + let mut hm = HashMap::>>::new(); + hm.into_iter() + .map(|(is_true, ts)| { + ts.into_iter() + .map(|t| (is_true, t)).flatten() + }) + .flatten() + .collect() +} +fn main() {} diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg new file mode 100644 index 000000000000..95c7740f6995 --- /dev/null +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg @@ -0,0 +1,504 @@ + + + + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:21:8 + + | + + LL | }).flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter() + + LL - .map(|t| { + + LL - ( + + LL - is_true, + + LL - t, + + LL - ) + + LL - }).flatten() + + LL + ts.into_iter().flatten() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:13:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| { + + ... | + + LL | | }).flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:14:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:24:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| { + + ... | + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:16:10: 16:13}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:14:8: 14:23}>>: Iterator` + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:32:6 + + | + + LL | .flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter() + + LL - .map(|t| (is_true, t)) + + LL + ts.into_iter() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:28:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)) + + LL | | .flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:29:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:35:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)) + + ... | + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:31:10: 31:13}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:29:8: 29:23}>>: Iterator` + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:43:7 + + | + + LL | }).flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter().map(|t| { + + LL - (is_true, t) + + LL - }).flatten() + + LL + ts.into_iter().flatten() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:39:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter().map(|t| { + + LL | | (is_true, t) + + LL | | }).flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:40:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:46:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter().map(|t| { + + LL | | (is_true, t) + + ... | + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:41:23: 41:26}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:40:8: 40:23}>>: Iterator` + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:53:28 + + | + + LL | .map(|t| (is_true, t)).flatten() + + | ^^^^^^^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `flatten` + + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + + help: consider removing this method call, as the receiver has type `std::vec::IntoIter<HashSet<u8>>` and `std::vec::IntoIter<HashSet<u8>>: Iterator` trivially holds + + | + + LL - ts.into_iter() + + LL - .map(|t| (is_true, t)).flatten() + + LL + ts.into_iter().flatten() + + | + + + + error[E0277]: `(bool, HashSet<u8>)` is not an iterator + + --> $DIR/multiline-removal-suggestion.rs:50:2 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)).flatten() + + LL | | }) + + | |__________^ `(bool, HashSet<u8>)` is not an iterator + + | + + = help: the trait `Iterator` is not implemented for `(bool, HashSet<u8>)` + + = note: required for `(bool, HashSet<u8>)` to implement `IntoIterator` + + note: required by a bound in `Flatten` + + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + + + + error[E0599]: the method `collect` exists for struct `Flatten<Map<IntoIter<bool, Vec<HashSet<u8>>>, {closure@multiline-removal-suggestion.rs:51:8}>>`, but its trait bounds were not satisfied + + --> $DIR/multiline-removal-suggestion.rs:56:4 + + | + + LL | / hm.into_iter() + + LL | | .map(|(is_true, ts)| { + + LL | | ts.into_iter() + + LL | | .map(|t| (is_true, t)).flatten() + + LL | | }) + + LL | | .flatten() + + LL | | .collect() + + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + + | |_________| + + | + + | + + = note: the following trait bounds were not satisfied: + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>> as IntoIterator>::IntoIter = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + `<Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>> as IntoIterator>::Item = _` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + `Flatten<Map<std::vec::IntoIter<HashSet<u8>>, {closure@$DIR/multiline-removal-suggestion.rs:53:10: 53:13}>>: IntoIterator` + + which is required by `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + `Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + which is required by `&mut Flatten<Map<std::collections::hash_map::IntoIter<bool, Vec<HashSet<u8>>>, {closure@$DIR/multiline-removal-suggestion.rs:51:8: 51:23}>>: Iterator` + + + + error: aborting due to 12 previous errors + + + + Some errors have detailed explanations: E0277, E0599. + + For more information about an error, try `rustc --explain E0277`. + + + + + + From f349d720e785645c59d12cbf8709da5294e45709 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 Dec 2024 19:13:50 +0000 Subject: [PATCH 028/113] Make ty::Error implement auto traits --- .../src/traits/select/candidate_assembly.rs | 4 +++- tests/ui/consts/error-is-freeze.rs | 14 ++++++++++++++ tests/ui/consts/error-is-freeze.stderr | 14 ++++++++++++++ .../impl-trait/auto-trait-contains-err.rs} | 4 +++- tests/ui/impl-trait/auto-trait-contains-err.stderr | 11 +++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests/ui/consts/error-is-freeze.rs create mode 100644 tests/ui/consts/error-is-freeze.stderr rename tests/{crashes/131050.rs => ui/impl-trait/auto-trait-contains-err.rs} (89%) create mode 100644 tests/ui/impl-trait/auto-trait-contains-err.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index d6ac4baf8ad7..968dc631e50e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -819,7 +819,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { candidates.vec.push(AutoImplCandidate) } } - ty::Error(_) => {} // do not add an auto trait impl for `ty::Error` for now. + ty::Error(_) => { + candidates.vec.push(AutoImplCandidate); + } } } } diff --git a/tests/ui/consts/error-is-freeze.rs b/tests/ui/consts/error-is-freeze.rs new file mode 100644 index 000000000000..fe27d029e663 --- /dev/null +++ b/tests/ui/consts/error-is-freeze.rs @@ -0,0 +1,14 @@ +// Make sure we treat the error type as freeze to suppress useless errors. + +struct MyStruct { + foo: Option, + //~^ ERROR cannot find type `UndefinedType` in this scope +} +impl MyStruct { + pub const EMPTY_REF: &'static Self = &Self::EMPTY; + pub const EMPTY: Self = Self { + foo: None, + }; +} + +fn main() {} diff --git a/tests/ui/consts/error-is-freeze.stderr b/tests/ui/consts/error-is-freeze.stderr new file mode 100644 index 000000000000..f3bfd1ea5e29 --- /dev/null +++ b/tests/ui/consts/error-is-freeze.stderr @@ -0,0 +1,14 @@ +error[E0412]: cannot find type `UndefinedType` in this scope + --> $DIR/error-is-freeze.rs:4:17 + | +LL | foo: Option, + | ^^^^^^^^^^^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | struct MyStruct { + | +++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/crashes/131050.rs b/tests/ui/impl-trait/auto-trait-contains-err.rs similarity index 89% rename from tests/crashes/131050.rs rename to tests/ui/impl-trait/auto-trait-contains-err.rs index 3e3a600ef3de..d7f094211d7d 100644 --- a/tests/crashes/131050.rs +++ b/tests/ui/impl-trait/auto-trait-contains-err.rs @@ -1,9 +1,9 @@ -//@ known-bug: #131050 //@ compile-flags: --edition=2021 use std::future::Future; fn invalid_future() -> impl Future {} +//~^ ERROR `()` is not a future fn create_complex_future() -> impl Future { async { &|| async { invalid_future().await } } @@ -21,3 +21,5 @@ where R: Send, { } + +fn main() {} diff --git a/tests/ui/impl-trait/auto-trait-contains-err.stderr b/tests/ui/impl-trait/auto-trait-contains-err.stderr new file mode 100644 index 000000000000..4da6b285ae15 --- /dev/null +++ b/tests/ui/impl-trait/auto-trait-contains-err.stderr @@ -0,0 +1,11 @@ +error[E0277]: `()` is not a future + --> $DIR/auto-trait-contains-err.rs:5:24 + | +LL | fn invalid_future() -> impl Future {} + | ^^^^^^^^^^^ `()` is not a future + | + = help: the trait `Future` is not implemented for `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From e5f676521ceb97388c0d1ca60a171548f8a0ef76 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 26 Dec 2024 21:55:22 +0000 Subject: [PATCH 029/113] Strip debuginfo from rustc-main and rustdoc --- src/bootstrap/src/core/build_steps/compile.rs | 8 +++++++- src/bootstrap/src/core/build_steps/tool.rs | 7 ++++++- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index d30a0d028ff0..bbb770a7a222 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -984,6 +984,7 @@ impl Step for Rustc { true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files. ); + let target_root_dir = stamp.parent().unwrap(); // When building `librustc_driver.so` (like `libLLVM.so`) on linux, it can contain // unexpected debuginfo from dependencies, for example from the C++ standard library used in // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with @@ -992,11 +993,16 @@ impl Step for Rustc { if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { - let target_root_dir = stamp.parent().unwrap(); let rustc_driver = target_root_dir.join("librustc_driver.so"); strip_debug(builder, target, &rustc_driver); } + if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + strip_debug(builder, target, &target_root_dir.join("rustc-main")); + } + builder.ensure(RustcLink::from_rustc( self, builder.compiler(compiler.stage, builder.config.build), diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 04f1e10f4937..6b809a52bd29 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -5,7 +5,7 @@ use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, llvm}; use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; -use crate::core::config::TargetSelection; +use crate::core::config::{DebuginfoLevel, TargetSelection}; use crate::utils::channel::GitInfo; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{add_dylib_path, exe, t}; @@ -671,6 +671,11 @@ impl Step for Rustdoc { // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { + if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + compile::strip_debug(builder, target, &tool_rustdoc); + } let bin_rustdoc = bin_rustdoc(); builder.copy_link(&tool_rustdoc, &bin_rustdoc); bin_rustdoc diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index e857f38e68a8..c7b9772d934a 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -89,6 +89,7 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.lto=thin \ --set rust.codegen-units=1 +# Note that `rust.debug` is set to true *only* for `opt-dist` ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ From 16a4ad7d7b0d163f7be6803c786c3b83d42913bb Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 26 Dec 2024 15:43:43 -0700 Subject: [PATCH 030/113] rustdoc: use shorter paths as preferred canonical paths This is a solution to the `std::sync::poison` linking problem, and, in general, makes intra-doc links shorter and clearer. --- src/librustdoc/formats/cache.rs | 19 ++++----- .../inline_local/parent-path-is-better.rs | 40 +++++++++++++++++++ 2 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 tests/rustdoc/inline_local/parent-path-is-better.rs diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b63122565c42..361cea75f5e1 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -305,6 +305,7 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::MacroItem(..) | clean::ProcMacroItem(..) | clean::VariantItem(..) => { + use rustc_data_structures::fx::IndexEntry as Entry; if !self.cache.stripped_mod { // Re-exported items mean that the same id can show up twice // in the rustdoc ast that we're looking at. We know, @@ -313,15 +314,15 @@ impl DocFolder for CacheBuilder<'_, '_> { // paths map if there was already an entry present and we're // not a public item. let item_def_id = item.item_id.expect_def_id(); - if !self.cache.paths.contains_key(&item_def_id) - || self - .cache - .effective_visibilities - .is_directly_public(self.tcx, item_def_id) - { - self.cache - .paths - .insert(item_def_id, (self.cache.stack.clone(), item.type_())); + match self.cache.paths.entry(item_def_id) { + Entry::Vacant(entry) => { + entry.insert((self.cache.stack.clone(), item.type_())); + } + Entry::Occupied(mut entry) => { + if entry.get().0.len() > self.cache.stack.len() { + entry.insert((self.cache.stack.clone(), item.type_())); + } + } } } } diff --git a/tests/rustdoc/inline_local/parent-path-is-better.rs b/tests/rustdoc/inline_local/parent-path-is-better.rs new file mode 100644 index 000000000000..086540d54441 --- /dev/null +++ b/tests/rustdoc/inline_local/parent-path-is-better.rs @@ -0,0 +1,40 @@ +//! Test case for [134702] +//! +//! [134702]: https://github.com/rust-lang/rust/issues/134702 +#![crate_name = "foo"] + +pub mod inside1 { + pub use self::inner::Inside1; + mod inner { + pub struct Inside1; + impl Inside1 { + pub fn stuff(self) {} + } + } +} + +pub mod inside2 { + pub use self::inner::Inside2; + mod inner { + pub struct Inside2; + impl Inside2 { + pub fn stuff(self) {} + } + } +} + +pub mod nested { + //! [Inside1] [Inside2] + //@ has foo/nested/index.html '//a[@href="../struct.Inside1.html"]' 'Inside1' + //@ has foo/nested/index.html '//a[@href="../struct.Inside2.html"]' 'Inside2' + //! [Inside1::stuff] [Inside2::stuff] + //@ has foo/nested/index.html '//a[@href="../struct.Inside1.html#method.stuff"]' 'Inside1::stuff' + //@ has foo/nested/index.html '//a[@href="../struct.Inside2.html#method.stuff"]' 'Inside2::stuff' + use crate::inside1::Inside1; + use crate::inside2::Inside2; +} + +#[doc(inline)] +pub use inside1::Inside1; +#[doc(inline)] +pub use inside2::Inside2; From fc8a541eaa4b6555d948c382b75677b0e17040fa Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 26 Dec 2024 15:51:45 -0700 Subject: [PATCH 031/113] docs: inline `core::ffi::c_str` types to `core::ffi` --- library/core/src/ffi/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 7a161f595f41..5f32775822be 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -12,10 +12,10 @@ #[doc(inline)] #[stable(feature = "core_c_str", since = "1.64.0")] pub use self::c_str::CStr; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub use self::c_str::FromBytesUntilNulError; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "core_c_str", since = "1.64.0")] pub use self::c_str::FromBytesWithNulError; use crate::fmt; From da1c1c33abe43feb50ebe01b59dade8da4304909 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 26 Dec 2024 16:35:29 -0700 Subject: [PATCH 032/113] Adjust test for slightly changed inlining behavior --- tests/rustdoc-js-std/path-maxeditdistance.js | 8 ++-- tests/rustdoc-js-std/path-ordering.js | 10 ++--- tests/rustdoc-js-std/simd-type-signatures.js | 40 ++++++++++---------- tests/rustdoc/intra-doc/pub-use.rs | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/rustdoc-js-std/path-maxeditdistance.js b/tests/rustdoc-js-std/path-maxeditdistance.js index af71713f0558..fd12a0564966 100644 --- a/tests/rustdoc-js-std/path-maxeditdistance.js +++ b/tests/rustdoc-js-std/path-maxeditdistance.js @@ -17,10 +17,10 @@ const EXPECTED = [ { 'path': 'std::vec::IntoIter', 'name': 'into_iter' }, { 'path': 'std::vec::ExtractIf', 'name': 'into_iter' }, { 'path': 'std::vec::Splice', 'name': 'into_iter' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'iter' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'iter_mut' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'from_iter' }, - { 'path': 'std::collections::vec_deque::VecDeque', 'name': 'into_iter' }, + { 'path': 'std::collections::VecDeque', 'name': 'iter' }, + { 'path': 'std::collections::VecDeque', 'name': 'iter_mut' }, + { 'path': 'std::collections::VecDeque', 'name': 'from_iter' }, + { 'path': 'std::collections::VecDeque', 'name': 'into_iter' }, ], }, { diff --git a/tests/rustdoc-js-std/path-ordering.js b/tests/rustdoc-js-std/path-ordering.js index 4bfc6256052c..4bec4827d519 100644 --- a/tests/rustdoc-js-std/path-ordering.js +++ b/tests/rustdoc-js-std/path-ordering.js @@ -3,17 +3,17 @@ const EXPECTED = [ query: 'hashset::insert', others: [ // ensure hashset::insert comes first - { 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' }, - { 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert' }, - { 'path': 'std::collections::hash_set::HashSet', 'name': 'get_or_insert_with' }, + { 'path': 'std::collections::HashSet', 'name': 'insert' }, + { 'path': 'std::collections::HashSet', 'name': 'get_or_insert' }, + { 'path': 'std::collections::HashSet', 'name': 'get_or_insert_with' }, ], }, { query: 'hash::insert', others: [ // ensure hashset/hashmap::insert come first - { 'path': 'std::collections::hash_map::HashMap', 'name': 'insert' }, - { 'path': 'std::collections::hash_set::HashSet', 'name': 'insert' }, + { 'path': 'std::collections::HashMap', 'name': 'insert' }, + { 'path': 'std::collections::HashSet', 'name': 'insert' }, ], }, ]; diff --git a/tests/rustdoc-js-std/simd-type-signatures.js b/tests/rustdoc-js-std/simd-type-signatures.js index 4fc14e65ac42..fea34ff97f21 100644 --- a/tests/rustdoc-js-std/simd-type-signatures.js +++ b/tests/rustdoc-js-std/simd-type-signatures.js @@ -11,29 +11,29 @@ const EXPECTED = [ 'query': 'simd, simd -> simd', 'others': [ { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_max', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_max' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_max' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_min', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_min' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_min' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_add', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_add' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_add' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_sub', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_clamp', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp' }, ], }, @@ -41,29 +41,29 @@ const EXPECTED = [ 'query': 'simd, simd -> simd', 'others': [ { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_max', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_max' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_max' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_min', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_min' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_min' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_add', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_add' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_add' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'saturating_sub', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub' + 'href': '../std/simd/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub' }, { - 'path': 'std::simd::prelude::Simd', + 'path': 'std::simd::Simd', 'name': 'simd_clamp', - 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp' + 'href': '../std/simd/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp' }, ], }, diff --git a/tests/rustdoc/intra-doc/pub-use.rs b/tests/rustdoc/intra-doc/pub-use.rs index 7c70adad7d96..5aeb3eb149ee 100644 --- a/tests/rustdoc/intra-doc/pub-use.rs +++ b/tests/rustdoc/intra-doc/pub-use.rs @@ -7,7 +7,7 @@ extern crate inner; /// [mod@std::env] [g] //@ has outer/index.html //@ has - '//a[@href="{{channel}}/std/env/index.html"]' "std::env" -//@ has - '//a[@href="fn.f.html"]' "g" +//@ has - '//a[@href="fn.g.html"]' "g" pub use f as g; // Make sure the documentation is actually correct by documenting an inlined re-export From d997bc998e6522e86d04b210cef88e0e78b77ef6 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 25 Dec 2024 18:52:35 +1100 Subject: [PATCH 033/113] Simplify or delete normalize directives that don't care about bit-width --- tests/ui/const-generics/transmute-fail.rs | 3 +- tests/ui/const-generics/transmute-fail.stderr | 30 +++++++++---------- .../ui/consts/issue-17718-const-bad-values.rs | 3 +- .../issue-17718-const-bad-values.stderr | 4 +-- .../debuginfo-type-name-layout-ice-94961-1.rs | 2 -- .../debuginfo-type-name-layout-ice-94961-2.rs | 2 -- tests/ui/limits/huge-struct.rs | 3 +- tests/ui/limits/huge-struct.stderr | 2 +- tests/ui/limits/issue-55878.rs | 2 -- tests/ui/limits/issue-55878.stderr | 2 +- 10 files changed, 22 insertions(+), 31 deletions(-) diff --git a/tests/ui/const-generics/transmute-fail.rs b/tests/ui/const-generics/transmute-fail.rs index 95c711605675..ee041972a9fd 100644 --- a/tests/ui/const-generics/transmute-fail.rs +++ b/tests/ui/const-generics/transmute-fail.rs @@ -1,6 +1,5 @@ // ignore-tidy-linelength -//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" -//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" +//@ normalize-stderr-test: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" #![feature(transmute_generic_consts)] diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr index 638ce790345a..978a9744e88a 100644 --- a/tests/ui/const-generics/transmute-fail.stderr +++ b/tests/ui/const-generics/transmute-fail.stderr @@ -1,11 +1,11 @@ error: the constant `W` is not of type `usize` - --> $DIR/transmute-fail.rs:17:42 + --> $DIR/transmute-fail.rs:16:42 | LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { | ^^^^^^^^^^^^^ expected `usize`, found `bool` error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:12:9 + --> $DIR/transmute-fail.rs:11:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -14,13 +14,13 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W + 1]; H]` (size can vary because of [u32; W + 1]) error: the constant `W` is not of type `usize` - --> $DIR/transmute-fail.rs:20:9 + --> $DIR/transmute-fail.rs:19:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:27:9 + --> $DIR/transmute-fail.rs:26:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; W * H * H]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:34:9 + --> $DIR/transmute-fail.rs:33:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | std::mem::transmute(v) = note: target type: `[[[u32; 9999999]; 777777777]; 8888888]` (values of the type $REALLY_TOO_BIG are too big for the target architecture) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:40:14 + --> $DIR/transmute-fail.rs:39:14 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | unsafe { std::mem::transmute(v) } = note: target type: `[[[u32; 9999999]; 777777777]; 239]` (values of the type $REALLY_TOO_BIG are too big for the target architecture) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:46:9 + --> $DIR/transmute-fail.rs:45:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:57:9 + --> $DIR/transmute-fail.rs:56:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; W * H]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:64:9 + --> $DIR/transmute-fail.rs:63:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; W]; H]` (size can vary because of [u32; W]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:73:9 + --> $DIR/transmute-fail.rs:72:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | std::mem::transmute(v) = note: target type: `[u32; D * W * H]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:82:9 + --> $DIR/transmute-fail.rs:81:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u32; D * W]; H]` (size can vary because of [u32; D * W]) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:89:9 + --> $DIR/transmute-fail.rs:88:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -101,7 +101,7 @@ LL | std::mem::transmute(v) = note: target type: `[u8; L * 2]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:96:9 + --> $DIR/transmute-fail.rs:95:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | std::mem::transmute(v) = note: target type: `[u16; L]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:103:9 + --> $DIR/transmute-fail.rs:102:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | std::mem::transmute(v) = note: target type: `[[u8; 1]; L]` (this type does not have a fixed size) error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-fail.rs:112:9 + --> $DIR/transmute-fail.rs:111:9 | LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index fca6cb085379..894fa5ab22f1 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -1,5 +1,4 @@ -//@ normalize-stderr-32bit: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" -//@ normalize-stderr-64bit: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" +//@ normalize-stderr-test: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" //@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 102491e90bac..364fa7be5aae 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/issue-17718-const-bad-values.rs:7:34 + --> $DIR/issue-17718-const-bad-values.rs:6:34 | LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-17718-const-bad-values.rs:11:1 + --> $DIR/issue-17718-const-bad-values.rs:10:1 | LL | const C2: &'static mut i32 = unsafe { &mut S }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const` diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs index a1922c98ef6d..3bff44716985 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs @@ -4,8 +4,6 @@ //@ compile-flags:-C debuginfo=2 //@ build-fail //@ error-pattern: too big for the target architecture -//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit: "4294967295" -> "SIZE" #![crate_type = "rlib"] diff --git a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs index 3456cd55b758..6a3f8f4c249c 100644 --- a/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs +++ b/tests/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -6,8 +6,6 @@ //@ compile-flags:-C debuginfo=2 //@ build-fail //@ error-pattern: too big for the target architecture -//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit: "4294967295" -> "SIZE" #![crate_type = "rlib"] diff --git a/tests/ui/limits/huge-struct.rs b/tests/ui/limits/huge-struct.rs index f7ce4f26db18..bf132d359f5b 100644 --- a/tests/ui/limits/huge-struct.rs +++ b/tests/ui/limits/huge-struct.rs @@ -2,8 +2,7 @@ //@ build-fail //@ normalize-stderr-test: "S32" -> "SXX" //@ normalize-stderr-test: "S1M" -> "SXX" -//@ normalize-stderr-32bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" -//@ normalize-stderr-64bit: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" +//@ normalize-stderr-test: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" struct S32 { v0: T, diff --git a/tests/ui/limits/huge-struct.stderr b/tests/ui/limits/huge-struct.stderr index b10455ffd2dc..e03456f1c7b5 100644 --- a/tests/ui/limits/huge-struct.stderr +++ b/tests/ui/limits/huge-struct.stderr @@ -1,5 +1,5 @@ error: values of the type $REALLY_TOO_BIG are too big for the target architecture - --> $DIR/huge-struct.rs:48:9 + --> $DIR/huge-struct.rs:47:9 | LL | let fat: Option>>> = None; | ^^^ diff --git a/tests/ui/limits/issue-55878.rs b/tests/ui/limits/issue-55878.rs index 81696e226fd0..db4a2724452a 100644 --- a/tests/ui/limits/issue-55878.rs +++ b/tests/ui/limits/issue-55878.rs @@ -1,6 +1,4 @@ //@ build-fail -//@ normalize-stderr-64bit: "18446744073709551615" -> "SIZE" -//@ normalize-stderr-32bit: "4294967295" -> "SIZE" //@ error-pattern: are too big for the target architecture fn main() { diff --git a/tests/ui/limits/issue-55878.stderr b/tests/ui/limits/issue-55878.stderr index 51c4837f4583..d2b5150c5561 100644 --- a/tests/ui/limits/issue-55878.stderr +++ b/tests/ui/limits/issue-55878.stderr @@ -6,7 +6,7 @@ error[E0080]: evaluation of constant value failed note: inside `std::mem::size_of::<[u8; usize::MAX]>` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL note: inside `main` - --> $DIR/issue-55878.rs:7:26 + --> $DIR/issue-55878.rs:5:26 | LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 2855098a5195f507a7f2f77df28a5f52ca50a57e Mon Sep 17 00:00:00 2001 From: 9names <60134748+9names@users.noreply.github.com> Date: Fri, 27 Dec 2024 17:51:11 +1100 Subject: [PATCH 034/113] Sort triples by name in platform_support.md --- src/doc/rustc/src/platform-support.md | 112 +++++++++++++------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 00ab61051c3c..f3bd1489a7df 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -32,8 +32,8 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- -`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+) +`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) `i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI] `i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI] `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI] @@ -139,12 +139,12 @@ target | std | notes [`aarch64-apple-ios`](platform-support/apple-ios.md) | ✓ | ARM64 iOS [`aarch64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on ARM64 [`aarch64-apple-ios-sim`](platform-support/apple-ios.md) | ✓ | Apple iOS Simulator on ARM64 -[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ARM64 MinGW (Windows 10+), LLVM ABI +[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony -`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat +`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android `arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3 @@ -173,11 +173,11 @@ target | std | notes [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] -[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA) [`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IM ISA) -[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) +[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) +[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) @@ -194,16 +194,16 @@ target | std | notes [`wasm32-unknown-emscripten`](platform-support/wasm32-unknown-emscripten.md) | ✓ | WebAssembly via Emscripten [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASIp1 -[`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads +[`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 [`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64 [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX -[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android [`x86_64-pc-solaris`](platform-support/solaris.md) | ✓ | 64-bit x86 Solaris 11.4 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI +[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat @@ -245,34 +245,34 @@ host tools. target | std | host | notes -------|:---:|:----:|------- -[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin -[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS -[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS Simulator -[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS -[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-apple-visionos`](platform-support/apple-visionos.md) | ✓ | | ARM64 Apple visionOS [`aarch64-apple-visionos-sim`](platform-support/apple-visionos.md) | ✓ | | ARM64 Apple visionOS Simulator +[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS +[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon -[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | -[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | -[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit `aarch64-unknown-illumos` | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD +[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS +[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | [`aarch64-unknown-trusty`](platform-support/trusty.md) | ? | | `aarch64-uwp-windows-msvc` | ✓ | | [`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | ARM64 VxWorks OS -`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) +`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian) [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers +[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin +[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS +[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). [`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare Armv4T `armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux @@ -283,9 +283,9 @@ target | std | host | notes [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain) [`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? | | RTEMS OS for ARM BSPs [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat -[`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float [`armv7-unknown-trusty`](platform-support/trusty.md) | ? | | [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks @@ -300,8 +300,8 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) -[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3 +[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86, restricted to Pentium @@ -325,48 +325,56 @@ target | std | host | notes `mips64-unknown-linux-muslabi64` | ✓ | | MIPS64 Linux, N64 ABI, musl 1.2.3 `mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (little endian) Linux, N64 ABI (kernel 4.4, glibc 2.23) `mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.3 -`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) -`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 -[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) +`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) +`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc +[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat [`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian [`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian [`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers +[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD `powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 [`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | | -[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) -[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD -[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD -`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3 -[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 +[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) +[`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) +`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3 +[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 +[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD +[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) +[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) +[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) `riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) `riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.3 + RISCV32 support patches) [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) -[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) -[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF +[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) [`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF -[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit -`riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD -`riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia -[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD -[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 +[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF +[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX [`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android [`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +`riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD +`riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia +[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit +[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD +[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX +[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 +[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.3) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ @@ -374,9 +382,16 @@ target | std | host | notes [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE +[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX `thumbv7a-pc-windows-msvc` | ✓ | | `thumbv7a-uwp-windows-msvc` | ✓ | | +[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX +[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat +[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 +[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX +[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX +[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator @@ -384,9 +399,10 @@ target | std | host | notes [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku -[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd [`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit +[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd `x86_64-unknown-l4re-uclibc` | ? | | +[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD [`x86_64-unknown-trusty`](platform-support/trusty.md) | ? | | `x86_64-uwp-windows-gnu` | ✓ | | @@ -394,27 +410,11 @@ target | std | host | notes [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support [`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) -[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc -[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32 [`xtensa-esp32-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32 -[`xtensa-esp32s2-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S2 +[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32 [`xtensa-esp32s2-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32-S2 -[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 +[`xtensa-esp32s2-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S2 [`xtensa-esp32s3-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32-S3 -[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX -[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX -[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX -[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat -[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX -[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX -[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat -[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX -[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX -[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) -[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) -[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) +[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets From c5e4b72a4183f6fd78f31a228898f5e8595cef3e Mon Sep 17 00:00:00 2001 From: Integral Date: Fri, 27 Dec 2024 16:36:48 +0800 Subject: [PATCH 035/113] tools: fix build failure caused by PR #134420 --- src/tools/rustc-perf-wrapper/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs index 0b4c894e29d9..e6c885e23dee 100644 --- a/src/tools/rustc-perf-wrapper/src/main.rs +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -1,5 +1,5 @@ use std::fs::create_dir_all; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use clap::Parser; @@ -169,7 +169,7 @@ fn execute_benchmark(cmd: &mut Command, compiler: &Path) { const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); - let rustc_perf_dir = PathBuf::from(MANIFEST_DIR).join("../rustc-perf"); + let rustc_perf_dir = Path::new(MANIFEST_DIR).join("../rustc-perf"); // We need to set the working directory to `src/tools/perf`, so that it can find the directory // with compile-time benchmarks. From 5ba0dd4ef669ca7512031f1f7ee2ae19f1fd099b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 25 Dec 2024 22:07:16 +1100 Subject: [PATCH 036/113] Don't use `parse_cfg_name_directive` for normalize directives This is a little more verbose, but also more explicit, and avoids invoking the full condition engine when only the pointer-width conditions are used. --- src/tools/compiletest/src/header.rs | 61 +++++++++++++++++++------ src/tools/compiletest/src/header/cfg.rs | 4 +- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 91558d0c898b..f2a944e78cc4 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -12,7 +12,6 @@ use tracing::*; use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; -use crate::header::cfg::{MatchOutcome, parse_cfg_name_directive}; use crate::header::needs::CachedNeedsConditions; use crate::util::static_regex; @@ -472,11 +471,24 @@ impl TestProps { config.set_name_directive(ln, IGNORE_PASS, &mut self.ignore_pass); - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") { - self.normalize_stdout.push(rule); - } - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") { - self.normalize_stderr.push(rule); + if let Some(NormalizeRule { kind, regex, replacement }) = + config.parse_custom_normalization(ln) + { + let rule_tuple = (regex, replacement); + match kind { + NormalizeKind::Stdout => self.normalize_stdout.push(rule_tuple), + NormalizeKind::Stderr => self.normalize_stderr.push(rule_tuple), + NormalizeKind::Stderr32bit => { + if config.target_cfg().pointer_width == 32 { + self.normalize_stderr.push(rule_tuple); + } + } + NormalizeKind::Stderr64bit => { + if config.target_cfg().pointer_width == 64 { + self.normalize_stderr.push(rule_tuple); + } + } + } } if let Some(code) = config @@ -966,20 +978,28 @@ impl Config { } } - fn parse_custom_normalization(&self, line: &str, prefix: &str) -> Option<(String, String)> { - let parsed = parse_cfg_name_directive(self, line, prefix); - if parsed.outcome != MatchOutcome::Match { - return None; - } - let name = parsed.name.expect("successful match always has a name"); + fn parse_custom_normalization(&self, line: &str) -> Option { + // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine` + // instead of doing it here. + let (directive_name, _value) = line.split_once(':')?; + let kind = match directive_name { + "normalize-stdout-test" => NormalizeKind::Stdout, + "normalize-stderr-test" => NormalizeKind::Stderr, + "normalize-stderr-32bit" => NormalizeKind::Stderr32bit, + "normalize-stderr-64bit" => NormalizeKind::Stderr64bit, + _ => return None, + }; + + // FIXME(Zalathar): The normalize rule parser should only care about + // the value part, not the "line" (which isn't even the whole line). let Some((regex, replacement)) = parse_normalize_rule(line) else { panic!( "couldn't parse custom normalization rule: `{line}`\n\ - help: expected syntax is: `{prefix}-{name}: \"REGEX\" -> \"REPLACEMENT\"`" + help: expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`" ); }; - Some((regex, replacement)) + Some(NormalizeRule { kind, regex, replacement }) } fn parse_name_directive(&self, line: &str, directive: &str) -> bool { @@ -1105,6 +1125,19 @@ fn expand_variables(mut value: String, config: &Config) -> String { value } +struct NormalizeRule { + kind: NormalizeKind, + regex: String, + replacement: String, +} + +enum NormalizeKind { + Stdout, + Stderr, + Stderr32bit, + Stderr64bit, +} + /// Parses the regex and replacement values of a `//@ normalize-*` header, /// in the format: /// ```text diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs index 3ab552903dc6..3f7225195ce0 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/header/cfg.rs @@ -40,8 +40,8 @@ pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision { } /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86` -/// or `normalize-stderr-32bit`. -pub(super) fn parse_cfg_name_directive<'a>( +/// or `only-windows`. +fn parse_cfg_name_directive<'a>( config: &Config, line: &'a str, prefix: &str, From 835fbcbcab82ce728a7233de6c32a2d206e3336c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 25 Dec 2024 22:12:17 +1100 Subject: [PATCH 037/113] Remove the `-test` suffix from normalize directives --- src/tools/compiletest/src/directive-list.rs | 4 ++-- src/tools/compiletest/src/header.rs | 4 ++-- src/tools/tidy/src/style.rs | 7 +++---- tests/rustdoc-ui/2024-doctests-checks.rs | 6 +++--- .../2024-doctests-crate-attribute.rs | 6 +++--- .../commandline-argfile-missing-windows.rs | 4 ++-- .../argfile/commandline-argfile-missing.rs | 4 ++-- .../commandline-argfile-multiple-windows.rs | 6 +++--- .../argfile/commandline-argfile-multiple.rs | 6 +++--- .../disambiguator-endswith-named-suffix.rs | 2 +- tests/rustdoc-ui/doctest/block-doc-comment.rs | 2 +- tests/rustdoc-ui/doctest/cfg-test.rs | 4 ++-- tests/rustdoc-ui/doctest/check-cfg-test.rs | 6 +++--- .../doctest/comment-in-attr-134221-2.rs | 6 +++--- .../doctest/comment-in-attr-134221.rs | 6 +++--- tests/rustdoc-ui/doctest/dead-code-2024.rs | 4 ++-- tests/rustdoc-ui/doctest/dead-code.rs | 4 ++-- tests/rustdoc-ui/doctest/display-output.rs | 4 ++-- .../doctest/doc-comment-multi-line-attr.rs | 4 ++-- .../doc-comment-multi-line-cfg-attr.rs | 4 ++-- .../doctest/doc-test-doctest-feature.rs | 4 ++-- .../doctest/doc-test-rustdoc-feature.rs | 4 ++-- .../doctest-multiline-crate-attribute.rs | 4 ++-- .../doctest/doctest-output-include-fail.rs | 4 ++-- tests/rustdoc-ui/doctest/doctest-output.rs | 4 ++-- .../doctest/failed-doctest-compile-fail.rs | 4 ++-- .../failed-doctest-extra-semicolon-on-item.rs | 4 ++-- .../doctest/failed-doctest-missing-codes.rs | 4 ++-- .../doctest/failed-doctest-output-windows.rs | 4 ++-- .../doctest/failed-doctest-output.rs | 4 ++-- .../failed-doctest-should-panic-2021.rs | 4 ++-- .../doctest/failed-doctest-should-panic.rs | 4 ++-- .../doctest/merged-ignore-no_run.rs | 4 ++-- tests/rustdoc-ui/doctest/nested-main.rs | 4 ++-- tests/rustdoc-ui/doctest/no-run-flag.rs | 4 ++-- tests/rustdoc-ui/doctest/nocapture-fail.rs | 6 +++--- tests/rustdoc-ui/doctest/nocapture.rs | 4 ++-- .../rustdoc-ui/doctest/non-local-defs-impl.rs | 4 ++-- tests/rustdoc-ui/doctest/non_local_defs.rs | 6 +++--- .../relative-path-include-bytes-132203.rs | 4 ++-- tests/rustdoc-ui/doctest/run-directory.rs | 4 ++-- .../doctest/rustflags-multiple-args.rs | 4 ++-- tests/rustdoc-ui/doctest/rustflags.rs | 4 ++-- .../doctest/standalone-warning-2024.rs | 6 +++--- tests/rustdoc-ui/doctest/test-no_std.rs | 4 ++-- tests/rustdoc-ui/doctest/test-type.rs | 4 ++-- .../doctest/unparseable-doc-test.rs | 4 ++-- tests/rustdoc-ui/doctest/wrong-ast-2024.rs | 6 +++--- tests/rustdoc-ui/doctest/wrong-ast.rs | 4 ++-- ...finite-recursive-type-impl-trait-return.rs | 4 ++-- tests/rustdoc-ui/ice-bug-report-url.rs | 12 +++++------ .../intra-doc/email-address-localhost.rs | 2 +- .../intra-doc/unknown-disambiguator.rs | 2 +- tests/rustdoc-ui/issues/issue-80992.rs | 4 ++-- .../issues/issue-81662-shortness.rs | 4 ++-- .../issues/issue-83883-describe-lints.rs | 4 ++-- tests/rustdoc-ui/issues/issue-91134.rs | 4 ++-- tests/rustdoc-ui/lints/check.rs | 2 +- .../lints/no-crate-level-doc-lint.rs | 2 +- ...remap-path-prefix-failed-doctest-output.rs | 4 ++-- .../remap-path-prefix-invalid-doctest.rs | 2 +- ...remap-path-prefix-passed-doctest-output.rs | 2 +- tests/rustdoc-ui/track-diagnostics.rs | 2 +- tests/ui-fulldeps/codegen-backend/hotplug.rs | 4 ++-- tests/ui-fulldeps/fluent-messages/test.rs | 2 +- .../ui-fulldeps/missing-rustc-driver-error.rs | 4 ++-- .../diagnostic-derive-doc-comment-field.rs | 4 ++-- .../session-diagnostic/diagnostic-derive.rs | 4 ++-- tests/ui/abi/c-zst.rs | 2 +- tests/ui/abi/debug.rs | 10 +++++----- tests/ui/abi/sysv64-zst.rs | 2 +- tests/ui/abi/win64-zst.rs | 2 +- .../commandline-argfile-missing-windows.rs | 4 ++-- .../ui/argfile/commandline-argfile-missing.rs | 4 ++-- .../commandline-argfile-multiple-windows.rs | 6 +++--- .../argfile/commandline-argfile-multiple.rs | 6 +++--- .../associated-types-in-ambiguous-context.rs | 2 +- tests/ui/attributes/dump-preds.rs | 2 +- tests/ui/attributes/dump_def_parents.rs | 2 +- .../extented-attribute-macro-error.rs | 2 +- tests/ui/check-cfg/and-more-diagnostic.rs | 4 ++-- tests/ui/check-cfg/target_feature.rs | 2 +- tests/ui/codegen/mismatched-data-layouts.rs | 4 ++-- tests/ui/codegen/target-cpus.rs | 2 +- .../generic_const_exprs/issue-80742.rs | 6 +++--- tests/ui/const-generics/transmute-fail.rs | 2 +- tests/ui/const-ptr/forbidden_slices.rs | 4 ++-- .../const-eval/const-eval-query-stack.rs | 20 +++++++++---------- .../heap/dealloc_intrinsic_dangling.rs | 6 +++--- tests/ui/consts/const-eval/raw-bytes.rs | 2 +- tests/ui/consts/const-eval/ub-enum.rs | 6 +++--- tests/ui/consts/const-eval/ub-nonnull.rs | 4 ++-- tests/ui/consts/const-eval/ub-ref-ptr.rs | 4 ++-- tests/ui/consts/const-eval/ub-uninhabit.rs | 4 ++-- tests/ui/consts/const-eval/ub-wide-ptr.rs | 8 ++++---- .../consts/const-mut-refs/mut_ref_in_final.rs | 6 +++--- .../mut_ref_in_final_dynamic_check.rs | 6 +++--- tests/ui/consts/const_refs_to_static_fail.rs | 4 ++-- .../const_refs_to_static_fail_invalid.rs | 4 ++-- tests/ui/consts/dangling-alloc-id-ice.rs | 6 +++--- .../consts/dangling-zst-ice-issue-126393.rs | 6 +++--- .../ui/consts/issue-17718-const-bad-values.rs | 4 ++-- tests/ui/consts/issue-miri-1910.rs | 2 +- .../miri_unleashed/const_refers_to_static.rs | 4 ++-- .../const_refers_to_static_cross_crate.rs | 4 ++-- .../miri_unleashed/mutable_references.rs | 4 ++-- tests/ui/consts/offset_from_ub.rs | 2 +- tests/ui/consts/offset_ub.rs | 6 +++--- tests/ui/consts/overflowing-consts.rs | 4 ++-- tests/ui/consts/validate_never_arrays.rs | 4 ++-- tests/ui/coroutine/static-not-unpin.rs | 2 +- tests/ui/crate-loading/crateresolve1.rs | 6 +++--- tests/ui/crate-loading/crateresolve2.rs | 4 ++-- tests/ui/crate-loading/invalid-rlib.rs | 2 +- tests/ui/diagnostic-width/E0271.rs | 2 +- tests/ui/diagnostic-width/long-E0308.rs | 2 +- tests/ui/duplicate_entry_error.rs | 2 +- tests/ui/error-codes/E0017.rs | 4 ++-- tests/ui/error-codes/E0152.rs | 2 +- tests/ui/error-codes/E0275.rs | 2 +- tests/ui/error-codes/E0462.rs | 6 +++--- tests/ui/error-codes/E0464.rs | 6 +++--- tests/ui/error-codes/E0523.rs | 6 +++--- tests/ui/errors/remap-path-prefix-sysroot.rs | 2 +- tests/ui/errors/remap-path-prefix.rs | 2 +- .../extern-C-non-FFI-safe-arg-ice-52334.rs | 4 ++-- tests/ui/extern/extern-types-field-offset.rs | 2 +- tests/ui/extern/extern-types-size_of_val.rs | 2 +- .../trait-bounds/hang-on-deeply-nested-dyn.rs | 2 +- .../trait-bounds/hrtb-doesnt-borrow-self-1.rs | 2 +- .../trait-bounds/hrtb-doesnt-borrow-self-2.rs | 2 +- tests/ui/hygiene/panic-location.rs | 2 +- tests/ui/hygiene/unpretty-debug.rs | 2 +- tests/ui/hygiene/unpretty-debug.stdout | 2 +- .../impl-trait/erased-regions-in-hidden-ty.rs | 2 +- tests/ui/include-macros/parent_dir.rs | 2 +- tests/ui/infinite/infinite-instantiation.rs | 2 +- tests/ui/intrinsics/not-overridden.rs | 6 +++--- .../invalid-debugger-visualizer-option.rs | 4 ++-- .../non-ice-error-on-worker-io-fail.rs | 4 ++-- tests/ui/issues/issue-20413.rs | 2 +- tests/ui/issues/issue-21763.rs | 2 +- tests/ui/issues/issue-28625.rs | 2 +- tests/ui/issues/issue-32377.rs | 2 +- .../issue-37311.rs | 2 +- tests/ui/issues/issue-67552.rs | 2 +- tests/ui/issues/issue-8727.rs | 2 +- tests/ui/lang-items/duplicate.rs | 2 +- tests/ui/layout/debug.rs | 2 +- tests/ui/layout/enum-scalar-pair-int-ptr.rs | 6 +++--- tests/ui/layout/enum.rs | 2 +- .../layout/ice-type-error-in-tail-124031.rs | 2 +- ...6158-scalarpair-payload-might-be-uninit.rs | 2 +- .../ui/layout/issue-96185-overaligned-enum.rs | 2 +- tests/ui/layout/struct.rs | 2 +- tests/ui/layout/valid_range_oob.rs | 4 ++-- .../ui/layout/zero-sized-array-enum-niche.rs | 2 +- tests/ui/limits/huge-enum.rs | 4 ++-- tests/ui/limits/huge-struct.rs | 6 +++--- tests/ui/limits/issue-17913.rs | 2 +- .../link-native-libs/msvc-non-utf8-output.rs | 2 +- tests/ui/lint/lint-overflowing-ops.rs | 4 ++-- tests/ui/lto/lto-duplicate-symbols.rs | 2 +- tests/ui/macros/macros-nonfatal-errors.rs | 2 +- tests/ui/methods/inherent-bound-in-probe.rs | 2 +- tests/ui/mir/lint/storage-live.rs | 8 ++++---- tests/ui/modules/path-no-file-name.rs | 4 ++-- tests/ui/packed/packed-struct-transmute.rs | 2 +- tests/ui/panic-handler/panic-handler-std.rs | 2 +- tests/ui/panics/default-backtrace-ice.rs | 12 +++++------ .../ui/panics/issue-47429-short-backtraces.rs | 6 +++--- tests/ui/panics/panic-in-cleanup.rs | 6 +++--- tests/ui/panics/panic-in-ffi.rs | 6 +++--- tests/ui/panics/panic-in-message-fmt.rs | 6 +++--- .../panic-short-backtrace-windows-x86_64.rs | 2 +- tests/ui/panics/runtime-switch.rs | 6 +++--- .../short-ice-remove-middle-frames-2.rs | 6 +++--- .../panics/short-ice-remove-middle-frames.rs | 6 +++--- tests/ui/parser/issues/issue-5806.rs | 4 ++-- tests/ui/parser/mod_file_with_path_attr.rs | 2 +- tests/ui/print-request/macos-target.rs | 6 +++--- tests/ui/proc-macro/load-panic-backtrace.rs | 4 ++-- tests/ui/proc-macro/meta-macro-hygiene.rs | 6 +++--- tests/ui/proc-macro/meta-macro-hygiene.stdout | 6 +++--- .../proc-macro/nonterminal-token-hygiene.rs | 6 +++--- .../nonterminal-token-hygiene.stdout | 6 +++--- tests/ui/process/println-with-broken-pipe.rs | 2 +- tests/ui/recursion/issue-23122-2.rs | 2 +- tests/ui/recursion/issue-83150.rs | 2 +- tests/ui/recursion/recursion.rs | 2 +- tests/ui/regions/issue-102374.rs | 2 +- tests/ui/repr/repr-c-dead-variants.rs | 2 +- tests/ui/repr/repr-c-int-dead-variants.rs | 2 +- .../multiple_definitions_attribute_merging.rs | 6 +++--- .../ui/resolve/proc_macro_generated_packed.rs | 6 +++--- .../rfcs/rfc-2627-raw-dylib/dlltool-failed.rs | 12 +++++------ tests/ui/statics/mutable_memory_validation.rs | 4 ++-- tests/ui/svh/changing-crates.rs | 2 +- tests/ui/svh/svh-change-lit.rs | 2 +- tests/ui/svh/svh-change-significant-cfg.rs | 2 +- tests/ui/svh/svh-change-trait-bound.rs | 2 +- tests/ui/svh/svh-change-type-arg.rs | 2 +- tests/ui/svh/svh-change-type-ret.rs | 2 +- tests/ui/svh/svh-change-type-static.rs | 2 +- tests/ui/svh/svh-use-trait.rs | 2 +- .../symbol-names/const-generics-demangling.rs | 4 ++-- .../const-generics-str-demangling.rs | 2 +- .../const-generics-structural-demangling.rs | 2 +- tests/ui/symbol-names/impl1.rs | 2 +- tests/ui/symbol-names/issue-75326.rs | 2 +- tests/ui/symbol-names/trait-objects.rs | 2 +- tests/ui/symbol-names/types.rs | 4 ++-- tests/ui/test-attrs/terse.rs | 2 +- tests/ui/test-attrs/test-filter-multiple.rs | 2 +- .../test-attrs/test-panic-abort-nocapture.rs | 2 +- tests/ui/test-attrs/test-panic-abort.rs | 2 +- tests/ui/test-attrs/test-passed.rs | 2 +- tests/ui/test-attrs/test-thread-capture.rs | 2 +- tests/ui/test-attrs/test-thread-nocapture.rs | 2 +- tests/ui/test-attrs/test-type.rs | 2 +- .../test-attrs/tests-listing-format-json.rs | 4 ++-- tests/ui/track-diagnostics/track.rs | 6 +++--- tests/ui/track-diagnostics/track2.rs | 2 +- tests/ui/track-diagnostics/track3.rs | 2 +- tests/ui/track-diagnostics/track4.rs | 2 +- tests/ui/track-diagnostics/track5.rs | 2 +- tests/ui/track-diagnostics/track6.rs | 2 +- .../ui/traits/on_unimplemented_long_types.rs | 2 +- .../illegal-upcast-to-impl-opaque.rs | 8 ++++---- .../ui/transmute/transmute-different-sizes.rs | 2 +- tests/ui/transmute/transmute-fat-pointers.rs | 2 +- tests/ui/transmute/transmute-impl.rs | 2 +- tests/ui/treat-err-as-bug/err.rs | 4 ++-- tests/ui/treat-err-as-bug/span_delayed_bug.rs | 4 ++-- tests/ui/type/pattern_types/range_patterns.rs | 2 +- tests/ui/unknown-llvm-arg.rs | 4 ++-- tests/ui/unpretty/avoid-crash.rs | 2 +- .../staged-api-invalid-path-108697.rs | 2 +- 238 files changed, 442 insertions(+), 443 deletions(-) diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 5638d4718902..01068af3e8c2 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -160,10 +160,10 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-xray", "no-auto-check-cfg", "no-prefer-dynamic", + "normalize-stderr", "normalize-stderr-32bit", "normalize-stderr-64bit", - "normalize-stderr-test", - "normalize-stdout-test", + "normalize-stdout", "only-16bit", "only-32bit", "only-64bit", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index f2a944e78cc4..67ecdaf9e5e1 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -984,8 +984,8 @@ impl Config { let (directive_name, _value) = line.split_once(':')?; let kind = match directive_name { - "normalize-stdout-test" => NormalizeKind::Stdout, - "normalize-stderr-test" => NormalizeKind::Stderr, + "normalize-stdout" => NormalizeKind::Stdout, + "normalize-stderr" => NormalizeKind::Stderr, "normalize-stderr-32bit" => NormalizeKind::Stderr32bit, "normalize-stderr-64bit" => NormalizeKind::Stderr64bit, _ => return None, diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 35cda17e1688..aefcd2bb0ccc 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -69,8 +69,7 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[ "// gdb", "// lldb", "// cdb", - "// normalize-stderr-test", - "//@ normalize-stderr-test", + "//@ normalize-stderr", ]; fn generate_problems<'a>( @@ -198,8 +197,8 @@ fn should_ignore(line: &str) -> bool { // For `ui_test`-style UI test directives, also ignore // - `//@[rev] compile-flags` - // - `//@[rev] normalize-stderr-test` - || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*") + // - `//@[rev] normalize-stderr` + || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr|error-pattern).*") .is_match(line) // Matching for rustdoc tests commands. // It allows to prevent them emitting warnings like `line longer than 100 chars`. diff --git a/tests/rustdoc-ui/2024-doctests-checks.rs b/tests/rustdoc-ui/2024-doctests-checks.rs index f3e4e10f5714..0c3a11771f34 100644 --- a/tests/rustdoc-ui/2024-doctests-checks.rs +++ b/tests/rustdoc-ui/2024-doctests-checks.rs @@ -1,9 +1,9 @@ //@ check-pass //@ edition: 2024 //@ compile-flags: --test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" /// ``` /// let x = 12; diff --git a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs index a353fc7cc445..c9887cbc63ba 100644 --- a/tests/rustdoc-ui/2024-doctests-crate-attribute.rs +++ b/tests/rustdoc-ui/2024-doctests-crate-attribute.rs @@ -1,9 +1,9 @@ //@ check-pass //@ edition: 2024 //@ compile-flags: --test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" /// This doctest is used to ensure that if a crate attribute is present, /// it will not be part of the merged doctests. diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs index 24cfd25ccadb..1a1cf6b9e75e 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing-windows.rs @@ -5,8 +5,8 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs index fe6a849b0c8b..8d9335f5add5 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-missing.rs @@ -6,8 +6,8 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs index 84c050d84e25..9cbbd505c57b 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple-windows.rs @@ -5,9 +5,9 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs index f658ee34fbb0..f211a50892c5 100644 --- a/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs +++ b/tests/rustdoc-ui/argfile/commandline-argfile-multiple.rs @@ -6,9 +6,9 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs index c3da1fdd7cc6..1174e16dd53f 100644 --- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" //! [struct@m!()] //~ WARN: unmatched disambiguator `struct` and suffix `!()` //! [struct@m!{}] diff --git a/tests/rustdoc-ui/doctest/block-doc-comment.rs b/tests/rustdoc-ui/doctest/block-doc-comment.rs index df953dc49bee..84bb5abb244a 100644 --- a/tests/rustdoc-ui/doctest/block-doc-comment.rs +++ b/tests/rustdoc-ui/doctest/block-doc-comment.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // This test ensures that no code block is detected in the doc comments. diff --git a/tests/rustdoc-ui/doctest/cfg-test.rs b/tests/rustdoc-ui/doctest/cfg-test.rs index 573172349acb..340a2eec87a8 100644 --- a/tests/rustdoc-ui/doctest/cfg-test.rs +++ b/tests/rustdoc-ui/doctest/cfg-test.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test --test-args --test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Crates like core have doctests gated on `cfg(not(test))` so we need to make // sure `cfg(test)` is not active when running `rustdoc --test`. diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.rs b/tests/rustdoc-ui/doctest/check-cfg-test.rs index b3bff381d64a..39fdb3a5853f 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.rs +++ b/tests/rustdoc-ui/doctest/check-cfg-test.rs @@ -1,8 +1,8 @@ //@ check-pass //@ compile-flags: --test --nocapture --check-cfg=cfg(feature,values("test")) -Z unstable-options -//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// The doctest will produce a warning because feature invalid is unexpected /// ``` diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs index 8cdd665ff69d..944939c8efe8 100644 --- a/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221-2.rs @@ -1,8 +1,8 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ failure-status: 101 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" //! ``` #![doc = "#![all\ diff --git a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs index 3689ebe166ad..2fbc8a215607 100644 --- a/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs +++ b/tests/rustdoc-ui/doctest/comment-in-attr-134221.rs @@ -4,9 +4,9 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ failure-status: 101 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" /*! ```rust diff --git a/tests/rustdoc-ui/doctest/dead-code-2024.rs b/tests/rustdoc-ui/doctest/dead-code-2024.rs index 41459c5e6512..079d44570bba 100644 --- a/tests/rustdoc-ui/doctest/dead-code-2024.rs +++ b/tests/rustdoc-ui/doctest/dead-code-2024.rs @@ -2,8 +2,8 @@ //@ edition: 2024 //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 #![doc(test(attr(allow(unused_variables), deny(warnings))))] diff --git a/tests/rustdoc-ui/doctest/dead-code.rs b/tests/rustdoc-ui/doctest/dead-code.rs index cb9b4c28f6ce..1ea3e1d53ac2 100644 --- a/tests/rustdoc-ui/doctest/dead-code.rs +++ b/tests/rustdoc-ui/doctest/dead-code.rs @@ -1,8 +1,8 @@ // This test ensures that the doctest will not use `#[allow(unused)]`. //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 #![doc(test(attr(allow(unused_variables), deny(warnings))))] diff --git a/tests/rustdoc-ui/doctest/display-output.rs b/tests/rustdoc-ui/doctest/display-output.rs index 70d15ea6f8a5..d5de341b6962 100644 --- a/tests/rustdoc-ui/doctest/display-output.rs +++ b/tests/rustdoc-ui/doctest/display-output.rs @@ -3,8 +3,8 @@ //@ check-pass //@ edition:2018 //@ compile-flags:--test --test-args=--show-output -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #![warn(unused)] diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs index f95d6f82933a..135ecca7ffd9 100644 --- a/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-attr.rs @@ -1,7 +1,7 @@ // Regression test for #97440: Multiline inner attribute triggers ICE during doctest //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass //! ```rust diff --git a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs index 8cafadfdc829..16adb3c6c547 100644 --- a/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-comment-multi-line-cfg-attr.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ``` diff --git a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs index fca1f51ed216..9c2d200329a9 100644 --- a/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-test-doctest-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Make sure `cfg(doctest)` is set when finding doctests but not inside // the doctests. diff --git a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs index 6d12d7af56ac..dd04adfe6179 100644 --- a/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs +++ b/tests/rustdoc-ui/doctest/doc-test-rustdoc-feature.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" #![feature(doc_cfg)] diff --git a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs index b446492e4724..1f80e002ef5d 100644 --- a/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs +++ b/tests/rustdoc-ui/doctest/doctest-multiline-crate-attribute.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ``` diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs index 58612b682a00..a47bac3daefe 100644 --- a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs +++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs @@ -1,7 +1,7 @@ //@ edition:2024 //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // https://github.com/rust-lang/rust/issues/130470 diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs index 946bc550b12f..fb4ab0680001 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.rs +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -5,8 +5,8 @@ //@[edition2024]edition:2015 //@[edition2024]aux-build:extern_macros.rs //@[edition2024]compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass //! ``` diff --git a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs index 4d0e035f86e0..6f7b2672b564 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-compile-fail.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```compile_fail diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs index b65ef4327058..508faadcf672 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// diff --git a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs index 766d94861437..ded674bf18ae 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-missing-codes.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```compile_fail,E0004 diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs index cf0d8b9daa1c..3a08faf626f1 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.rs @@ -7,8 +7,8 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // doctest fails at runtime diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.rs b/tests/rustdoc-ui/doctest/failed-doctest-output.rs index 160796065f33..84c722688812 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-output.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-output.rs @@ -7,8 +7,8 @@ //@ compile-flags:--test --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 // doctest fails at runtime diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs index 4fe513b40669..d8c43100d2fc 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic-2021.rs @@ -2,8 +2,8 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test --edition 2021 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```should_panic diff --git a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs index d057218688c4..793f86546610 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-should-panic.rs @@ -3,8 +3,8 @@ //@ edition: 2024 //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```should_panic diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs index 754791361e8b..7dac64e6de42 100644 --- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs @@ -1,7 +1,7 @@ //@ edition: 2024 //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass /// ```ignore (test) diff --git a/tests/rustdoc-ui/doctest/nested-main.rs b/tests/rustdoc-ui/doctest/nested-main.rs index e939ba81214c..d1b3bd6da40c 100644 --- a/tests/rustdoc-ui/doctest/nested-main.rs +++ b/tests/rustdoc-ui/doctest/nested-main.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Regression test for . // It ensures that if a function called `main` is nested, it will not consider diff --git a/tests/rustdoc-ui/doctest/no-run-flag.rs b/tests/rustdoc-ui/doctest/no-run-flag.rs index 0f7a0a175f12..8f1381e07604 100644 --- a/tests/rustdoc-ui/doctest/no-run-flag.rs +++ b/tests/rustdoc-ui/doctest/no-run-flag.rs @@ -2,8 +2,8 @@ //@ check-pass //@ compile-flags:-Z unstable-options --test --no-run --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// let a = true; diff --git a/tests/rustdoc-ui/doctest/nocapture-fail.rs b/tests/rustdoc-ui/doctest/nocapture-fail.rs index db4062e84941..8c64a49f6500 100644 --- a/tests/rustdoc-ui/doctest/nocapture-fail.rs +++ b/tests/rustdoc-ui/doctest/nocapture-fail.rs @@ -1,8 +1,8 @@ //@ check-pass //@ compile-flags:--test -Zunstable-options --nocapture -//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ```compile_fail /// fn foo() { diff --git a/tests/rustdoc-ui/doctest/nocapture.rs b/tests/rustdoc-ui/doctest/nocapture.rs index 3b87dad49f95..c4360341864f 100644 --- a/tests/rustdoc-ui/doctest/nocapture.rs +++ b/tests/rustdoc-ui/doctest/nocapture.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -Zunstable-options --nocapture -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// println!("hello!"); diff --git a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs index b1ab5323a2bc..04fdd2855067 100644 --- a/tests/rustdoc-ui/doctest/non-local-defs-impl.rs +++ b/tests/rustdoc-ui/doctest/non-local-defs-impl.rs @@ -3,8 +3,8 @@ //@ failure-status: 101 //@ aux-build:pub_trait.rs //@ compile-flags: --test --test-args --test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" #![doc(test(attr(deny(non_local_definitions))))] #![doc(test(attr(allow(dead_code))))] diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs index a2f66c392231..ce65ad2cf72c 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.rs +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -1,8 +1,8 @@ //@ check-pass //@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stderr: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //! ``` //! #[macro_export] diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs index 5a1d4d0a60dd..5c9e2978e48a 100644 --- a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs @@ -7,8 +7,8 @@ //@[edition2024]edition:2024 //@[edition2024]check-pass //@[edition2024]compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // https://github.com/rust-lang/rust/issues/132203 // This version, because it's edition2024, passes thanks to the new diff --git a/tests/rustdoc-ui/doctest/run-directory.rs b/tests/rustdoc-ui/doctest/run-directory.rs index 0e3a30ba4614..090bd19c4d90 100644 --- a/tests/rustdoc-ui/doctest/run-directory.rs +++ b/tests/rustdoc-ui/doctest/run-directory.rs @@ -4,8 +4,8 @@ //@ check-pass //@ [correct]compile-flags:--test --test-run-directory={{src-base}} //@ [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// assert_eq!( diff --git a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs index 8519920e53be..8d8c60ede585 100644 --- a/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs +++ b/tests/rustdoc-ui/doctest/rustflags-multiple-args.rs @@ -4,8 +4,8 @@ //@ check-pass //@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present //@ compile-flags: --doctest-compilation-args=--cfg=another -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #[cfg(testcase_must_be_present)] diff --git a/tests/rustdoc-ui/doctest/rustflags.rs b/tests/rustdoc-ui/doctest/rustflags.rs index fa460e355472..9f1e6017ea15 100644 --- a/tests/rustdoc-ui/doctest/rustflags.rs +++ b/tests/rustdoc-ui/doctest/rustflags.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags: --test -Zunstable-options --doctest-compilation-args=--cfg=testcase_must_be_present -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// #[cfg(testcase_must_be_present)] diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs index 35d1c738bb16..c53a8b48749c 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs @@ -2,9 +2,9 @@ //@ edition: 2024 //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" #![deny(warnings)] diff --git a/tests/rustdoc-ui/doctest/test-no_std.rs b/tests/rustdoc-ui/doctest/test-no_std.rs index b8af892552de..9abfa4a37286 100644 --- a/tests/rustdoc-ui/doctest/test-no_std.rs +++ b/tests/rustdoc-ui/doctest/test-no_std.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass #![no_std] diff --git a/tests/rustdoc-ui/doctest/test-type.rs b/tests/rustdoc-ui/doctest/test-type.rs index 846a98a853b5..28c862fb69b6 100644 --- a/tests/rustdoc-ui/doctest/test-type.rs +++ b/tests/rustdoc-ui/doctest/test-type.rs @@ -1,7 +1,7 @@ //@ compile-flags: --test --test-args=--test-threads=1 //@ check-pass -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" /// ``` /// let a = true; diff --git a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs index 43acfa6de3f9..d90e152aadab 100644 --- a/tests/rustdoc-ui/doctest/unparseable-doc-test.rs +++ b/tests/rustdoc-ui/doctest/unparseable-doc-test.rs @@ -1,6 +1,6 @@ //@ compile-flags: --test -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 //@ rustc-env: RUST_BACKTRACE=0 diff --git a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs index a1455c01bc69..3b4fb3f34433 100644 --- a/tests/rustdoc-ui/doctest/wrong-ast-2024.rs +++ b/tests/rustdoc-ui/doctest/wrong-ast-2024.rs @@ -1,8 +1,8 @@ //@ edition: 2024 //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" //@ failure-status: 101 /// ``` diff --git a/tests/rustdoc-ui/doctest/wrong-ast.rs b/tests/rustdoc-ui/doctest/wrong-ast.rs index 92286b33dcfb..be8f54175869 100644 --- a/tests/rustdoc-ui/doctest/wrong-ast.rs +++ b/tests/rustdoc-ui/doctest/wrong-ast.rs @@ -1,6 +1,6 @@ //@ compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ``` diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs index dfa528acb263..032da8f53f0f 100644 --- a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "`.*`" -> "`DEF_ID`" -//@ normalize-stdout-test: "`.*`" -> "`DEF_ID`" +//@ normalize-stderr: "`.*`" -> "`DEF_ID`" +//@ normalize-stdout: "`.*`" -> "`DEF_ID`" //@ edition:2018 pub async fn f() -> impl std::fmt::Debug { diff --git a/tests/rustdoc-ui/ice-bug-report-url.rs b/tests/rustdoc-ui/ice-bug-report-url.rs index f270340e07e8..9260644e44f1 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.rs +++ b/tests/rustdoc-ui/ice-bug-report-url.rs @@ -4,12 +4,12 @@ //@ error-pattern: aborting due to //@ error-pattern: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md -//@ normalize-stderr-test: "note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" -//@ normalize-stderr-test: "thread.*panicked at compiler.*" -> "" -//@ normalize-stderr-test: " +\d{1,}: .*\n" -> "" -//@ normalize-stderr-test: " + at .*\n" -> "" -//@ normalize-stderr-test: ".*note: Some details are omitted.*\n" -> "" +//@ normalize-stderr: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr: "note: rustc.*running on.*" -> "note: rustc {version} running on {platform}" +//@ normalize-stderr: "thread.*panicked at compiler.*" -> "" +//@ normalize-stderr: " +\d{1,}: .*\n" -> "" +//@ normalize-stderr: " + at .*\n" -> "" +//@ normalize-stderr: ".*note: Some details are omitted.*\n" -> "" fn wrong() //~^ ERROR expected one of diff --git a/tests/rustdoc-ui/intra-doc/email-address-localhost.rs b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs index adef39527eb0..3faff8a3cca5 100644 --- a/tests/rustdoc-ui/intra-doc/email-address-localhost.rs +++ b/tests/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" //@ check-pass #![deny(warnings)] diff --git a/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs index 68b818e32b35..86b31cb14d85 100644 --- a/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs +++ b/tests/rustdoc-ui/intra-doc/unknown-disambiguator.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" #![deny(warnings)] //! Linking to [foo@banana] and [`bar@banana!()`]. diff --git a/tests/rustdoc-ui/issues/issue-80992.rs b/tests/rustdoc-ui/issues/issue-80992.rs index 31cc8b78ecc4..c328ac53e538 100644 --- a/tests/rustdoc-ui/issues/issue-80992.rs +++ b/tests/rustdoc-ui/issues/issue-80992.rs @@ -1,7 +1,7 @@ //@ check-pass //@ compile-flags:--test -//@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" pub fn test() -> Result<(), ()> { //! ```compile_fail diff --git a/tests/rustdoc-ui/issues/issue-81662-shortness.rs b/tests/rustdoc-ui/issues/issue-81662-shortness.rs index 7df63261ce7e..8719442c34f9 100644 --- a/tests/rustdoc-ui/issues/issue-81662-shortness.rs +++ b/tests/rustdoc-ui/issues/issue-81662-shortness.rs @@ -1,8 +1,8 @@ //@ compile-flags:--test --error-format=short //@ check-stdout //@ error-pattern:cannot find function `foo` -//@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ failure-status: 101 /// ```rust diff --git a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs index a7b1c734d7f5..35d2fda45850 100644 --- a/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs +++ b/tests/rustdoc-ui/issues/issue-83883-describe-lints.rs @@ -6,5 +6,5 @@ // // ignore-tidy-linelength // -//@ normalize-stdout-test: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" -//@ normalize-stdout-test: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" +//@ normalize-stdout: "( +name default meaning\n +---- ------- -------\n)?( *[[:word:]:-]+ (allow |warn |deny |forbid ) [^\n]+\n)+" -> " $$NAMES $$LEVELS $$MEANINGS" +//@ normalize-stdout: " +name sub-lints\n +---- ---------\n( *[[:word:]:-]+ [^\n]+\n)+" -> " $$NAMES $$SUB_LINTS" diff --git a/tests/rustdoc-ui/issues/issue-91134.rs b/tests/rustdoc-ui/issues/issue-91134.rs index 6b1fec957eac..1c53ecfeb8b7 100644 --- a/tests/rustdoc-ui/issues/issue-91134.rs +++ b/tests/rustdoc-ui/issues/issue-91134.rs @@ -1,8 +1,8 @@ //@ compile-flags: --test --crate-name=empty_fn --extern=empty_fn --test-args=--test-threads=1 //@ aux-build:empty-fn.rs //@ check-pass -//@ normalize-stdout-test: "tests/rustdoc-ui/issues" -> "$$DIR" -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "tests/rustdoc-ui/issues" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ edition:2021 /// diff --git a/tests/rustdoc-ui/lints/check.rs b/tests/rustdoc-ui/lints/check.rs index 058c5d6c468f..61c9f1889529 100644 --- a/tests/rustdoc-ui/lints/check.rs +++ b/tests/rustdoc-ui/lints/check.rs @@ -1,6 +1,6 @@ //@ check-pass //@ compile-flags: -Z unstable-options --check -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" #![feature(rustdoc_missing_doc_code_examples)] //~^ WARN diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs index 12d4892d36a8..6e631061e8ac 100644 --- a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs +++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.rs @@ -1,5 +1,5 @@ //@ error-pattern: no documentation found -//@ normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +//@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" #![deny(rustdoc::missing_crate_level_docs)] //^~ NOTE defined here diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs index 57c0c1af031b..72c3330709a7 100644 --- a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs @@ -4,8 +4,8 @@ //@ failure-status: 101 //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" -//@ normalize-stdout-test: "exit (status|code): 101" -> "exit status: 101" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "exit (status|code): 101" -> "exit status: 101" // doctest fails at runtime /// ``` diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs index 96a79e85f6be..c18a416d43f0 100644 --- a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs @@ -4,7 +4,7 @@ //@ failure-status: 101 //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // doctest fails to compile /// ``` diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs index 4c61c43578cd..6fa04ef77f32 100644 --- a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs @@ -5,7 +5,7 @@ // adapted to use that, and that normalize line can go away //@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // doctest passes at runtime /// ``` diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index 403b8c789174..5c950a11082f 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.rs b/tests/ui-fulldeps/codegen-backend/hotplug.rs index dc0fb3f9efd0..917b20fcdb56 100644 --- a/tests/ui-fulldeps/codegen-backend/hotplug.rs +++ b/tests/ui-fulldeps/codegen-backend/hotplug.rs @@ -3,8 +3,8 @@ //@ ignore-stage1 (requires matching sysroot built with in-tree compiler) //@ aux-codegen-backend: the_backend.rs -//@ normalize-stdout-test: "libthe_backend.dylib" -> "libthe_backend.so" -//@ normalize-stdout-test: "the_backend.dll" -> "libthe_backend.so" +//@ normalize-stdout: "libthe_backend.dylib" -> "libthe_backend.so" +//@ normalize-stdout: "the_backend.dll" -> "libthe_backend.so" //@ revisions: normal dep bindep //@ compile-flags: --crate-type=lib diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 3361ebcef018..c1f5fe730c76 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" +//@ normalize-stderr: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" #![feature(rustc_private)] #![crate_type = "lib"] diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.rs b/tests/ui-fulldeps/missing-rustc-driver-error.rs index 23ca39363bcd..03ab5ce7b253 100644 --- a/tests/ui-fulldeps/missing-rustc-driver-error.rs +++ b/tests/ui-fulldeps/missing-rustc-driver-error.rs @@ -1,8 +1,8 @@ // Test that we get the following hint when trying to use a compiler crate without rustc_driver. //@ error-pattern: try adding `extern crate rustc_driver;` at the top level of this crate //@ compile-flags: --emit link -//@ normalize-stderr-test: ".*crate .* required.*\n\n" -> "" -//@ normalize-stderr-test: "aborting due to [0-9]+" -> "aborting due to NUMBER" +//@ normalize-stderr: ".*crate .* required.*\n\n" -> "" +//@ normalize-stderr: "aborting due to [0-9]+" -> "aborting due to NUMBER" #![feature(rustc_private)] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index 7921ede23c57..37f78a7777c4 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -1,7 +1,7 @@ //@ check-fail // Tests that a doc comment will not preclude a field from being considered a diagnostic argument -//@ normalize-stderr-test: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr-test: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" +//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Subdiagnostic is strictly internal to the compiler diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 1577b68e748f..fa2d037064d2 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -1,7 +1,7 @@ //@ check-fail // Tests error conditions for specifying diagnostics using #[derive(Diagnostic)] -//@ normalize-stderr-test: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr-test: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" +//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Diagnostic is strictly internal to the compiler diff --git a/tests/ui/abi/c-zst.rs b/tests/ui/abi/c-zst.rs index 69ebefa09acb..6b299ffadb7b 100644 --- a/tests/ui/abi/c-zst.rs +++ b/tests/ui/abi/c-zst.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" /*! C doesn't have zero-sized types... except it does. diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index 16d616027341..565743bf978e 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -1,9 +1,9 @@ -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" -//@ normalize-stderr-test: "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" -//@ normalize-stderr-test: "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" -//@ normalize-stderr-test: "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(size): Size\([48] bytes\)" -> "$1: $$SOME_SIZE" +//@ normalize-stderr: "(can_unwind): (true|false)" -> "$1: $$SOME_BOOL" +//@ normalize-stderr: "(valid_range): 0\.\.=(4294967295|18446744073709551615)" -> "$1: $$FULL" // This pattern is prepared for when we account for alignment in the niche. -//@ normalize-stderr-test: "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" +//@ normalize-stderr: "(valid_range): [1-9]\.\.=(429496729[0-9]|1844674407370955161[0-9])" -> "$1: $$NON_NULL" // Some attributes are only computed for release builds: //@ compile-flags: -O #![feature(rustc_attrs)] diff --git a/tests/ui/abi/sysv64-zst.rs b/tests/ui/abi/sysv64-zst.rs index 6f4497e77a18..42ba1fb5f03a 100644 --- a/tests/ui/abi/sysv64-zst.rs +++ b/tests/ui/abi/sysv64-zst.rs @@ -1,5 +1,5 @@ //@ only-x86_64 -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" #![feature(rustc_attrs)] #![crate_type = "lib"] diff --git a/tests/ui/abi/win64-zst.rs b/tests/ui/abi/win64-zst.rs index a2f7d19eb459..bc4e0e629eb4 100644 --- a/tests/ui/abi/win64-zst.rs +++ b/tests/ui/abi/win64-zst.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" +//@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" //@ only-x86_64 //@ revisions: x86_64-linux diff --git a/tests/ui/argfile/commandline-argfile-missing-windows.rs b/tests/ui/argfile/commandline-argfile-missing-windows.rs index 24cfd25ccadb..1a1cf6b9e75e 100644 --- a/tests/ui/argfile/commandline-argfile-missing-windows.rs +++ b/tests/ui/argfile/commandline-argfile-missing-windows.rs @@ -5,8 +5,8 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/argfile/commandline-argfile-missing.rs b/tests/ui/argfile/commandline-argfile-missing.rs index fe6a849b0c8b..8d9335f5add5 100644 --- a/tests/ui/argfile/commandline-argfile-missing.rs +++ b/tests/ui/argfile/commandline-argfile-missing.rs @@ -6,8 +6,8 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/argfile/commandline-argfile-multiple-windows.rs b/tests/ui/argfile/commandline-argfile-multiple-windows.rs index 84c050d84e25..9cbbd505c57b 100644 --- a/tests/ui/argfile/commandline-argfile-multiple-windows.rs +++ b/tests/ui/argfile/commandline-argfile-multiple-windows.rs @@ -5,9 +5,9 @@ // line arguments and is only run on windows. // //@ only-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}\argfile\commandline-argfile-missing.args @{{src-base}}\argfile\commandline-argfile-badutf8.args @{{src-base}}\argfile\commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/argfile/commandline-argfile-multiple.rs b/tests/ui/argfile/commandline-argfile-multiple.rs index f658ee34fbb0..f211a50892c5 100644 --- a/tests/ui/argfile/commandline-argfile-multiple.rs +++ b/tests/ui/argfile/commandline-argfile-multiple.rs @@ -6,9 +6,9 @@ // windows. // //@ ignore-windows -//@ normalize-stderr-test: "os error \d+" -> "os error $$ERR" -//@ normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -//@ normalize-stderr-test: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " +//@ normalize-stderr: "os error \d+" -> "os error $$ERR" +//@ normalize-stderr: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +//@ normalize-stderr: "commandline-argfile-missing2.args:[^(]*" -> "commandline-argfile-missing2.args: $$FILE_MISSING " //@ compile-flags: --cfg cmdline_set @{{src-base}}/argfile/commandline-argfile-missing.args @{{src-base}}/argfile/commandline-argfile-badutf8.args @{{src-base}}/argfile/commandline-argfile-missing2.args #[cfg(not(cmdline_set))] diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.rs b/tests/ui/associated-types/associated-types-in-ambiguous-context.rs index 98bbff794ca4..3c0d66f8a0d2 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.rs +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "and \d+ other candidates" -> "and N other candidates" +//@ normalize-stderr: "and \d+ other candidates" -> "and N other candidates" trait Get { type Value; diff --git a/tests/ui/attributes/dump-preds.rs b/tests/ui/attributes/dump-preds.rs index ca38e23b237c..071a7baede52 100644 --- a/tests/ui/attributes/dump-preds.rs +++ b/tests/ui/attributes/dump-preds.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\(.+?\)" -> "DefId(..)" #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs index 04a725f6c144..af117e4fa636 100644 --- a/tests/ui/attributes/dump_def_parents.rs +++ b/tests/ui/attributes/dump_def_parents.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\(.+?\)" -> "DefId(..)" #![feature(rustc_attrs)] fn bar() { diff --git a/tests/ui/attributes/extented-attribute-macro-error.rs b/tests/ui/attributes/extented-attribute-macro-error.rs index 5dcb38d7da9d..83060024dac9 100644 --- a/tests/ui/attributes/extented-attribute-macro-error.rs +++ b/tests/ui/attributes/extented-attribute-macro-error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "couldn't read.*" -> "couldn't read the file" +//@ normalize-stderr: "couldn't read.*" -> "couldn't read the file" #![doc = include_str!("../not_existing_file.md")] struct Documented {} diff --git a/tests/ui/check-cfg/and-more-diagnostic.rs b/tests/ui/check-cfg/and-more-diagnostic.rs index 82867f3b4354..977f55e8a6d1 100644 --- a/tests/ui/check-cfg/and-more-diagnostic.rs +++ b/tests/ui/check-cfg/and-more-diagnostic.rs @@ -4,8 +4,8 @@ //@ check-pass //@ no-auto-check-cfg //@ compile-flags: --check-cfg=cfg() -//@ normalize-stderr-test: "and \d+ more" -> "and X more" -//@ normalize-stderr-test: "`[a-zA-Z0-9_-]+`" -> "`xxx`" +//@ normalize-stderr: "and \d+ more" -> "and X more" +//@ normalize-stderr: "`[a-zA-Z0-9_-]+`" -> "`xxx`" fn main() { cfg!(target_feature = "zebra"); diff --git a/tests/ui/check-cfg/target_feature.rs b/tests/ui/check-cfg/target_feature.rs index 6028dae66c4d..3c0f1a3c2f62 100644 --- a/tests/ui/check-cfg/target_feature.rs +++ b/tests/ui/check-cfg/target_feature.rs @@ -10,7 +10,7 @@ //@ check-pass //@ no-auto-check-cfg //@ compile-flags: --check-cfg=cfg() -Zcheck-cfg-all-expected -//@ normalize-stderr-test: "`, `" -> "`\n`" +//@ normalize-stderr: "`, `" -> "`\n`" fn main() { cfg!(target_feature = "_UNEXPECTED_VALUE"); diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index 7d63895c65ba..955f917ee332 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -4,8 +4,8 @@ //@ needs-llvm-components: x86 //@ compile-flags: --crate-type=lib --target={{src-base}}/codegen/mismatched-data-layout.json -Z unstable-options //@ error-pattern: differs from LLVM target's -//@ normalize-stderr-test: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" -//@ normalize-stderr-test: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" +//@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" +//@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" #![feature(lang_items, no_core, auto_traits)] #![no_core] diff --git a/tests/ui/codegen/target-cpus.rs b/tests/ui/codegen/target-cpus.rs index 363915c6419b..f26203171f33 100644 --- a/tests/ui/codegen/target-cpus.rs +++ b/tests/ui/codegen/target-cpus.rs @@ -6,4 +6,4 @@ // output so that the stdout with LLVM-at-HEAD matches the output of the LLVM // versions currently used by default. // FIXME(#133919): Once Rust upgrades to LLVM 20, remove this. -//@ normalize-stdout-test: "(?m)^ *lime1\n" -> "" +//@ normalize-stdout: "(?m)^ *lime1\n" -> "" diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index 30851b49cdca..73357d208c04 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -1,9 +1,9 @@ //@ check-fail //@ known-bug: #97477 //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place diff --git a/tests/ui/const-generics/transmute-fail.rs b/tests/ui/const-generics/transmute-fail.rs index ee041972a9fd..cf9064bd8f4b 100644 --- a/tests/ui/const-generics/transmute-fail.rs +++ b/tests/ui/const-generics/transmute-fail.rs @@ -1,5 +1,5 @@ // ignore-tidy-linelength -//@ normalize-stderr-test: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" +//@ normalize-stderr: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" #![feature(transmute_generic_consts)] diff --git a/tests/ui/const-ptr/forbidden_slices.rs b/tests/ui/const-ptr/forbidden_slices.rs index bc4993466eb1..59ea92c5ab38 100644 --- a/tests/ui/const-ptr/forbidden_slices.rs +++ b/tests/ui/const-ptr/forbidden_slices.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature( slice_from_ptr_range, diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.rs b/tests/ui/consts/const-eval/const-eval-query-stack.rs index c015c5e0c498..8de398787b41 100644 --- a/tests/ui/consts/const-eval/const-eval-query-stack.rs +++ b/tests/ui/consts/const-eval/const-eval-query-stack.rs @@ -1,16 +1,16 @@ //@ compile-flags: -Ztreat-err-as-bug=1 //@ failure-status: 101 //@ rustc-env:RUST_BACKTRACE=1 -//@ normalize-stderr-test: "\nerror: .*unexpectedly panicked.*\n\n" -> "" -//@ normalize-stderr-test: "note: we would appreciate a bug report.*\n\n" -> "" -//@ normalize-stderr-test: "note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test: "note: rustc.*running on.*\n\n" -> "" -//@ normalize-stderr-test: "thread.*panicked.*:\n.*\n" -> "" -//@ normalize-stderr-test: "stack backtrace:\n" -> "" -//@ normalize-stderr-test: "\s\d{1,}: .*\n" -> "" -//@ normalize-stderr-test: "\s at .*\n" -> "" -//@ normalize-stderr-test: ".*note: Some details.*\n" -> "" -//@ normalize-stderr-test: ".*omitted \d{1,} frame.*\n" -> "" +//@ normalize-stderr: "\nerror: .*unexpectedly panicked.*\n\n" -> "" +//@ normalize-stderr: "note: we would appreciate a bug report.*\n\n" -> "" +//@ normalize-stderr: "note: compiler flags.*\n\n" -> "" +//@ normalize-stderr: "note: rustc.*running on.*\n\n" -> "" +//@ normalize-stderr: "thread.*panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "stack backtrace:\n" -> "" +//@ normalize-stderr: "\s\d{1,}: .*\n" -> "" +//@ normalize-stderr: "\s at .*\n" -> "" +//@ normalize-stderr: ".*note: Some details.*\n" -> "" +//@ normalize-stderr: ".*omitted \d{1,} frame.*\n" -> "" #![allow(unconditional_panic)] const X: i32 = 1 / 0; //~ERROR constant diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs index 3054e79770d9..509c872f6095 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs @@ -2,9 +2,9 @@ #![feature(const_heap)] // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::intrinsics; diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs index 0df732df30e1..9187de563620 100644 --- a/tests/ui/consts/const-eval/raw-bytes.rs +++ b/tests/ui/consts/const-eval/raw-bytes.rs @@ -1,7 +1,7 @@ //@ stderr-per-bitwidth //@ ignore-endian-big // ignore-tidy-linelength -//@ normalize-stderr-test: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" +//@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" #![allow(invalid_value)] #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)] diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 728c1666deb6..11cd87023d17 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -1,7 +1,7 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "0x0+" -> "0x0" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "0x0+" -> "0x0" #![feature(never_type)] #![allow(invalid_value)] diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs index 47d3ca97fda7..b8e312759b4c 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.rs +++ b/tests/ui/consts/const-eval/ub-nonnull.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] // make sure we cannot allow away the errors tested here #![feature(rustc_attrs, ptr_metadata)] diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index 44b25a6438ea..78d6fb5b65ba 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -1,7 +1,7 @@ // ignore-tidy-linelength // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(invalid_value)] use std::mem; diff --git a/tests/ui/consts/const-eval/ub-uninhabit.rs b/tests/ui/consts/const-eval/ub-uninhabit.rs index 0167de26e942..d0515a4e6f06 100644 --- a/tests/ui/consts/const-eval/ub-uninhabit.rs +++ b/tests/ui/consts/const-eval/ub-uninhabit.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(core_intrinsics)] #![feature(never_type)] diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index 991d4424dcf9..a071a44272b4 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -5,10 +5,10 @@ use std::{ptr, mem}; // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "offset \d+" -> "offset N" -//@ normalize-stderr-test: "size \d+" -> "size N" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "offset \d+" -> "offset N" +//@ normalize-stderr: "size \d+" -> "size N" /// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs index af7463e6574f..283c1224e013 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::cell::UnsafeCell; use std::mem; diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs index 2539fcccb848..ac903fca20ae 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> " HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" use std::sync::Mutex; diff --git a/tests/ui/consts/const_refs_to_static_fail.rs b/tests/ui/consts/const_refs_to_static_fail.rs index 44e848ab6377..596ed50af385 100644 --- a/tests/ui/consts/const_refs_to_static_fail.rs +++ b/tests/ui/consts/const_refs_to_static_fail.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(sync_unsafe_cell)] diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.rs b/tests/ui/consts/const_refs_to_static_fail_invalid.rs index aa101cf9d8a6..3383a208345d 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.rs +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] fn invalid() { diff --git a/tests/ui/consts/dangling-alloc-id-ice.rs b/tests/ui/consts/dangling-alloc-id-ice.rs index da95d4d13476..8e9493c8d285 100644 --- a/tests/ui/consts/dangling-alloc-id-ice.rs +++ b/tests/ui/consts/dangling-alloc-id-ice.rs @@ -1,8 +1,8 @@ // https://github.com/rust-lang/rust/issues/55223 // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" union Foo<'a> { y: &'a (), diff --git a/tests/ui/consts/dangling-zst-ice-issue-126393.rs b/tests/ui/consts/dangling-zst-ice-issue-126393.rs index b56fcd235c7d..4beee913a978 100644 --- a/tests/ui/consts/dangling-zst-ice-issue-126393.rs +++ b/tests/ui/consts/dangling-zst-ice-issue-126393.rs @@ -1,7 +1,7 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" -//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP" pub struct Wrapper; pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { diff --git a/tests/ui/consts/issue-17718-const-bad-values.rs b/tests/ui/consts/issue-17718-const-bad-values.rs index 894fa5ab22f1..c4de7b61f07d 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.rs +++ b/tests/ui/consts/issue-17718-const-bad-values.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "\(size: \d+, align: \d+\)" -> "(size: $$PTR, align: $$PTR)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] diff --git a/tests/ui/consts/issue-miri-1910.rs b/tests/ui/consts/issue-miri-1910.rs index a66cb6b66651..107d9742b92a 100644 --- a/tests/ui/consts/issue-miri-1910.rs +++ b/tests/ui/consts/issue-miri-1910.rs @@ -1,5 +1,5 @@ //@ error-pattern unable to turn pointer into raw bytes -//@ normalize-stderr-test: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC" +//@ normalize-stderr: "alloc[0-9]+\+0x[a-z0-9]+" -> "ALLOC" const C: () = unsafe { let foo = Some(&42 as *const i32); diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs index 562595325733..a6691fa2a2f1 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs index facb21a04ef0..b33ebfb06be9 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you //@ aux-build:static_cross_crate.rs -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(half_open_range_patterns_in_slices)] #![allow(static_mut_refs)] diff --git a/tests/ui/consts/miri_unleashed/mutable_references.rs b/tests/ui/consts/miri_unleashed/mutable_references.rs index a60058cc5c01..039d0fadfcc4 100644 --- a/tests/ui/consts/miri_unleashed/mutable_references.rs +++ b/tests/ui/consts/miri_unleashed/mutable_references.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zunleash-the-miri-inside-of-you -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![allow(static_mut_refs)] use std::cell::UnsafeCell; diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 7efc5dd3e28b..0232b03a813e 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bytes" -> "$$BYTES bytes" +//@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" #![feature(const_ptr_sub_ptr)] #![feature(core_intrinsics)] diff --git a/tests/ui/consts/offset_ub.rs b/tests/ui/consts/offset_ub.rs index 5026d9a27132..dda6dd388f28 100644 --- a/tests/ui/consts/offset_ub.rs +++ b/tests/ui/consts/offset_ub.rs @@ -1,8 +1,8 @@ use std::ptr; -//@ normalize-stderr-test: "0xf+" -> "0xf..f" -//@ normalize-stderr-test: "0x7f+" -> "0x7f..f" -//@ normalize-stderr-test: "\d+ bytes" -> "$$BYTES bytes" +//@ normalize-stderr: "0xf+" -> "0xf..f" +//@ normalize-stderr: "0x7f+" -> "0x7f..f" +//@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; //~NOTE diff --git a/tests/ui/consts/overflowing-consts.rs b/tests/ui/consts/overflowing-consts.rs index 68282750dce2..5ff205ce58e6 100644 --- a/tests/ui/consts/overflowing-consts.rs +++ b/tests/ui/consts/overflowing-consts.rs @@ -6,8 +6,8 @@ //@ [opt]compile-flags: -O //@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O //@ ignore-pass (test tests codegen-time behaviour) -//@ normalize-stderr-test: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" -//@ normalize-stderr-test: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" +//@ normalize-stderr: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" +//@ normalize-stderr: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" #[cfg(target_pointer_width = "32")] diff --git a/tests/ui/consts/validate_never_arrays.rs b/tests/ui/consts/validate_never_arrays.rs index 7585a78a0d35..055bb1c69c89 100644 --- a/tests/ui/consts/validate_never_arrays.rs +++ b/tests/ui/consts/validate_never_arrays.rs @@ -1,6 +1,6 @@ // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" #![feature(never_type)] const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs index b66a248654e9..9be7eca63cbb 100644 --- a/tests/ui/coroutine/static-not-unpin.rs +++ b/tests/ui/coroutine/static-not-unpin.rs @@ -5,7 +5,7 @@ #![feature(coroutines, stmt_expr_attributes)] -//@ normalize-stderr-test: "std::pin::Unpin" -> "std::marker::Unpin" +//@ normalize-stderr: "std::pin::Unpin" -> "std::marker::Unpin" use std::marker::Unpin; diff --git a/tests/ui/crate-loading/crateresolve1.rs b/tests/ui/crate-loading/crateresolve1.rs index 2fccb744e82c..9200b6a62314 100644 --- a/tests/ui/crate-loading/crateresolve1.rs +++ b/tests/ui/crate-loading/crateresolve1.rs @@ -2,9 +2,9 @@ //@ aux-build:crateresolve1-2.rs //@ aux-build:crateresolve1-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" // NOTE: This test is duplicated at `tests/ui/error-codes/E0464.rs`. diff --git a/tests/ui/crate-loading/crateresolve2.rs b/tests/ui/crate-loading/crateresolve2.rs index 159ce04c3c4a..bec692eb8d2b 100644 --- a/tests/ui/crate-loading/crateresolve2.rs +++ b/tests/ui/crate-loading/crateresolve2.rs @@ -4,8 +4,8 @@ //@ aux-build:crateresolve2-2.rs //@ aux-build:crateresolve2-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" extern crate crateresolve2; //~^ ERROR multiple candidates for `rmeta` dependency `crateresolve2` found diff --git a/tests/ui/crate-loading/invalid-rlib.rs b/tests/ui/crate-loading/invalid-rlib.rs index 0b401add8e49..6b4635262445 100644 --- a/tests/ui/crate-loading/invalid-rlib.rs +++ b/tests/ui/crate-loading/invalid-rlib.rs @@ -1,5 +1,5 @@ //@ compile-flags: --crate-type lib --extern foo={{src-base}}/crate-loading/auxiliary/libfoo.rlib -//@ normalize-stderr-test: "failed to mmap file '.*auxiliary/libfoo.rlib':.*" -> "failed to mmap file 'auxiliary/libfoo.rlib'" +//@ normalize-stderr: "failed to mmap file '.*auxiliary/libfoo.rlib':.*" -> "failed to mmap file 'auxiliary/libfoo.rlib'" // don't emit warn logging, it's basically the same as the errors and it's annoying to normalize //@ rustc-env:RUSTC_LOG=error //@ edition:2018 diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index dedae4365e88..061ba45c2198 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,7 +1,7 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=40 //@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Future { type Error; } diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 695852f83ac0..939872260209 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -1,7 +1,7 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes //@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" mod a { // Force the "short path for unique types" machinery to trip up diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs index e8b905a65f60..5a25802c6e78 100644 --- a/tests/ui/duplicate_entry_error.rs +++ b/tests/ui/duplicate_entry_error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" // note-pattern: first defined in crate `std`. // Test for issue #31788 and E0152 diff --git a/tests/ui/error-codes/E0017.rs b/tests/ui/error-codes/E0017.rs index e103d3bf5b11..8c685aad0308 100644 --- a/tests/ui/error-codes/E0017.rs +++ b/tests/ui/error-codes/E0017.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "\(size: ., align: .\)" -> "" -//@ normalize-stderr-test: " +│ ╾─+╼" -> "" +//@ normalize-stderr: "\(size: ., align: .\)" -> "" +//@ normalize-stderr: " +│ ╾─+╼" -> "" static X: i32 = 1; const C: i32 = 2; diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs index 44d462c27e68..565e92baf02e 100644 --- a/tests/ui/error-codes/E0152.rs +++ b/tests/ui/error-codes/E0152.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +//@ normalize-stderr: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" #![feature(lang_items)] #[lang = "owned_box"] diff --git a/tests/ui/error-codes/E0275.rs b/tests/ui/error-codes/E0275.rs index 889d9d8be903..df7b606155eb 100644 --- a/tests/ui/error-codes/E0275.rs +++ b/tests/ui/error-codes/E0275.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo {} struct Bar(T); diff --git a/tests/ui/error-codes/E0462.rs b/tests/ui/error-codes/E0462.rs index 2dd3b16394d5..12214331445f 100644 --- a/tests/ui/error-codes/E0462.rs +++ b/tests/ui/error-codes/E0462.rs @@ -1,8 +1,8 @@ //@ aux-build:found-staticlib.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?found_staticlib\.[a-z]+" -> "libfound_staticlib.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?found_staticlib\.[a-z]+" -> "libfound_staticlib.somelib" extern crate found_staticlib; //~ ERROR E0462 diff --git a/tests/ui/error-codes/E0464.rs b/tests/ui/error-codes/E0464.rs index 4ecf21996ccf..aaf4d3a8f500 100644 --- a/tests/ui/error-codes/E0464.rs +++ b/tests/ui/error-codes/E0464.rs @@ -2,9 +2,9 @@ //@ aux-build:crateresolve1-2.rs //@ aux-build:crateresolve1-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" // NOTE: This test is duplicated from `tests/ui/crate-loading/crateresolve1.rs`. diff --git a/tests/ui/error-codes/E0523.rs b/tests/ui/error-codes/E0523.rs index 4ecf21996ccf..aaf4d3a8f500 100644 --- a/tests/ui/error-codes/E0523.rs +++ b/tests/ui/error-codes/E0523.rs @@ -2,9 +2,9 @@ //@ aux-build:crateresolve1-2.rs //@ aux-build:crateresolve1-3.rs -//@ normalize-stderr-test: "\.nll/" -> "/" -//@ normalize-stderr-test: "\\\?\\" -> "" -//@ normalize-stderr-test: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" +//@ normalize-stderr: "\.nll/" -> "/" +//@ normalize-stderr: "\\\?\\" -> "" +//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib" // NOTE: This test is duplicated from `tests/ui/crate-loading/crateresolve1.rs`. diff --git a/tests/ui/errors/remap-path-prefix-sysroot.rs b/tests/ui/errors/remap-path-prefix-sysroot.rs index 4cbb38709bea..7281e6da0944 100644 --- a/tests/ui/errors/remap-path-prefix-sysroot.rs +++ b/tests/ui/errors/remap-path-prefix-sysroot.rs @@ -8,7 +8,7 @@ // The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically // as the remapped revision will not begin with $SRC_DIR_REAL, // so we have to do it ourselves. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:COL" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL" use std::thread; struct Worker { diff --git a/tests/ui/errors/remap-path-prefix.rs b/tests/ui/errors/remap-path-prefix.rs index 6283a8737ff2..8809caa4d4f1 100644 --- a/tests/ui/errors/remap-path-prefix.rs +++ b/tests/ui/errors/remap-path-prefix.rs @@ -5,7 +5,7 @@ // no-remap-src-base: Manually remap, so the remapped path remains in .stderr file. // The remapped paths are not normalized by compiletest. -//@ normalize-stderr-test: "\\(errors)" -> "/$1" +//@ normalize-stderr: "\\(errors)" -> "/$1" // The remapped paths aren't recognized by compiletest, so we // cannot use line-specific patterns. diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs index bf060b3d1683..33d295f7ebe1 100644 --- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs +++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.rs @@ -1,8 +1,8 @@ // test for ICE when casting extern "C" fn when it has a non-FFI-safe argument // issue: rust-lang/rust#52334 //@ check-pass -//@ normalize-stderr-test: "\[i8\]" -> "[i8 or u8 (arch dependant)]" -//@ normalize-stderr-test: "\[u8\]" -> "[i8 or u8 (arch dependant)]" +//@ normalize-stderr: "\[i8\]" -> "[i8 or u8 (arch dependant)]" +//@ normalize-stderr: "\[u8\]" -> "[i8 or u8 (arch dependant)]" type Foo = extern "C" fn(::std::ffi::CStr); //~^ WARN `extern` fn uses type diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs index e9c4bb7b2304..75f3eab3e275 100644 --- a/tests/ui/extern/extern-types-field-offset.rs +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -1,7 +1,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" #![feature(extern_types)] extern "C" { diff --git a/tests/ui/extern/extern-types-size_of_val.rs b/tests/ui/extern/extern-types-size_of_val.rs index cc4d34e59fa9..399a5828ff3b 100644 --- a/tests/ui/extern/extern-types-size_of_val.rs +++ b/tests/ui/extern/extern-types-size_of_val.rs @@ -1,7 +1,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ revisions: size align #![feature(extern_types)] diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs index a884c94734a7..7b6ba9f7f169 100644 --- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" fn id( f: &dyn Fn(u32), diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs index 799df8cae9fd..f880749ec835 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream` // should act as assertion that item does not borrow from its stream; diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs index 92e2e7f796ea..ff4c0cf24d69 100644 --- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" // // Regression test for issue #70963 // The reported panic location should not be `<::core::macros::panic macros>`. diff --git a/tests/ui/hygiene/unpretty-debug.rs b/tests/ui/hygiene/unpretty-debug.rs index 8e05d60e2184..4d3d139deda3 100644 --- a/tests/ui/hygiene/unpretty-debug.rs +++ b/tests/ui/hygiene/unpretty-debug.rs @@ -2,7 +2,7 @@ //@ compile-flags: -Zunpretty=expanded,hygiene // Don't break whenever Symbol numbering changes -//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout: "\d+#" -> "0#" // minimal junk #![feature(no_core)] diff --git a/tests/ui/hygiene/unpretty-debug.stdout b/tests/ui/hygiene/unpretty-debug.stdout index 1f620cef239f..e475cfac2fc1 100644 --- a/tests/ui/hygiene/unpretty-debug.stdout +++ b/tests/ui/hygiene/unpretty-debug.stdout @@ -2,7 +2,7 @@ //@ compile-flags: -Zunpretty=expanded,hygiene // Don't break whenever Symbol numbering changes -//@ normalize-stdout-test: "\d+#" -> "0#" +//@ normalize-stdout: "\d+#" -> "0#" // minimal junk #![feature /* 0#0 */(no_core)] diff --git a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs index 294b27e1dc18..766c37419cd8 100644 --- a/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs +++ b/tests/ui/impl-trait/erased-regions-in-hidden-ty.rs @@ -2,7 +2,7 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@ compile-flags: -Zverbose-internals //@[next] compile-flags: -Znext-solver -//@ normalize-stderr-test: "DefId\([^\)]+\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\([^\)]+\)" -> "DefId(..)" #![feature(rustc_attrs)] #![rustc_hidden_type_of_opaques] diff --git a/tests/ui/include-macros/parent_dir.rs b/tests/ui/include-macros/parent_dir.rs index 5fadff77a37e..1dcf27324d1f 100644 --- a/tests/ui/include-macros/parent_dir.rs +++ b/tests/ui/include-macros/parent_dir.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" +//@ normalize-stderr: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" fn main() { let _ = include_str!("include-macros/file.txt"); //~ ERROR couldn't read diff --git a/tests/ui/infinite/infinite-instantiation.rs b/tests/ui/infinite/infinite-instantiation.rs index ed6fe693ebf4..7e1bff6b1242 100644 --- a/tests/ui/infinite/infinite-instantiation.rs +++ b/tests/ui/infinite/infinite-instantiation.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" trait ToOpt: Sized { fn to_option(&self) -> Option; diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs index 16f8e9bcf6a7..b57b4e5bc06d 100644 --- a/tests/ui/intrinsics/not-overridden.rs +++ b/tests/ui/intrinsics/not-overridden.rs @@ -3,9 +3,9 @@ #![feature(intrinsics)] //@ build-fail //@ failure-status:101 -//@ normalize-stderr-test: ".*note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" -//@ normalize-stderr-test: "internal compiler error:.*: intrinsic const_deallocate " -> "" +//@ normalize-stderr: ".*note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "internal compiler error:.*: intrinsic const_deallocate " -> "" //@ rustc-env:RUST_BACKTRACE=0 #[rustc_intrinsic] diff --git a/tests/ui/invalid/invalid-debugger-visualizer-option.rs b/tests/ui/invalid/invalid-debugger-visualizer-option.rs index 16e5619e8e49..0f1cf15a6879 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-option.rs +++ b/tests/ui/invalid/invalid-debugger-visualizer-option.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" -//@ normalize-stderr-test: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" +//@ normalize-stderr: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" +//@ normalize-stderr: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" #![debugger_visualizer(random_file = "../foo.random")] //~ ERROR invalid argument #![debugger_visualizer(natvis_file = "../foo.random")] //~ ERROR diff --git a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs index a6deb8bab29c..7cae77eb67f4 100644 --- a/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs +++ b/tests/ui/io-checks/non-ice-error-on-worker-io-fail.rs @@ -19,10 +19,10 @@ //@ error-pattern: error // On Mac OS X, we get an error like the below -//@ normalize-stderr-test: "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/" +//@ normalize-stderr: "failed to write bytecode to ./does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying ./does-not-exist/" // On Linux, we get an error like the below -//@ normalize-stderr-test: "couldn't create a temp dir.*" -> "io error modifying ./does-not-exist/" +//@ normalize-stderr: "couldn't create a temp dir.*" -> "io error modifying ./does-not-exist/" //@ ignore-windows - this is a unix-specific test //@ ignore-emscripten - the file-system issues do not replicate here diff --git a/tests/ui/issues/issue-20413.rs b/tests/ui/issues/issue-20413.rs index 0f602b32fabe..7766f3755993 100644 --- a/tests/ui/issues/issue-20413.rs +++ b/tests/ui/issues/issue-20413.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Foo { fn answer(self); } diff --git a/tests/ui/issues/issue-21763.rs b/tests/ui/issues/issue-21763.rs index 1d0a0705cbbd..c1ed5d94f9b5 100644 --- a/tests/ui/issues/issue-21763.rs +++ b/tests/ui/issues/issue-21763.rs @@ -1,6 +1,6 @@ // Regression test for HashMap only impl'ing Send/Sync if its contents do -//@ normalize-stderr-test: "\S+[\\/]hashbrown\S+" -> "$$HASHBROWN_SRC_LOCATION" +//@ normalize-stderr: "\S+[\\/]hashbrown\S+" -> "$$HASHBROWN_SRC_LOCATION" use std::collections::HashMap; use std::rc::Rc; diff --git a/tests/ui/issues/issue-28625.rs b/tests/ui/issues/issue-28625.rs index 23f96d10bf26..54ed408e7488 100644 --- a/tests/ui/issues/issue-28625.rs +++ b/tests/ui/issues/issue-28625.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" trait Bar { type Bar; diff --git a/tests/ui/issues/issue-32377.rs b/tests/ui/issues/issue-32377.rs index 3a4942deb834..6737f9820efd 100644 --- a/tests/ui/issues/issue-32377.rs +++ b/tests/ui/issues/issue-32377.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" use std::mem; use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs index 96e2691164ba..edf4f2fce26a 100644 --- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs +++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" trait Mirror { type Image; diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs index 26466bf838c4..343ae4f262fc 100644 --- a/tests/ui/issues/issue-67552.rs +++ b/tests/ui/issues/issue-67552.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" fn main() { rec(Empty); diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/issues/issue-8727.rs index 4ef660003748..b824be7c12fe 100644 --- a/tests/ui/issues/issue-8727.rs +++ b/tests/ui/issues/issue-8727.rs @@ -2,7 +2,7 @@ // recursions. //@ build-fail -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" fn generic() { //~ WARN function cannot return without recursing generic::>(); diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs index 3aa7dd2b0bee..4594e9456a4c 100644 --- a/tests/ui/lang-items/duplicate.rs +++ b/tests/ui/lang-items/duplicate.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" +//@ normalize-stderr: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" #![feature(lang_items)] #[lang = "sized"] diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 166321798de3..5602c4e711f6 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" #![feature(never_type, rustc_attrs, type_alias_impl_trait, repr_simd)] #![crate_type = "lib"] diff --git a/tests/ui/layout/enum-scalar-pair-int-ptr.rs b/tests/ui/layout/enum-scalar-pair-int-ptr.rs index ebb3fdb1514c..60cada5e05a8 100644 --- a/tests/ui/layout/enum-scalar-pair-int-ptr.rs +++ b/tests/ui/layout/enum-scalar-pair-int-ptr.rs @@ -1,6 +1,6 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" -//@ normalize-stderr-test: "Int\(I[0-9]+," -> "Int(I?," -//@ normalize-stderr-test: "valid_range: 0..=[0-9]+" -> "valid_range: $$VALID_RANGE" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "Int\(I[0-9]+," -> "Int(I?," +//@ normalize-stderr: "valid_range: 0..=[0-9]+" -> "valid_range: $$VALID_RANGE" //! Enum layout tests related to scalar pairs with an int/ptr common primitive. diff --git a/tests/ui/layout/enum.rs b/tests/ui/layout/enum.rs index b58d390a2eff..005faf8ee508 100644 --- a/tests/ui/layout/enum.rs +++ b/tests/ui/layout/enum.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" //! Various enum layout tests. #![feature(rustc_attrs)] diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.rs b/tests/ui/layout/ice-type-error-in-tail-124031.rs index ecd6f3d56f3f..ef5b27cd1952 100644 --- a/tests/ui/layout/ice-type-error-in-tail-124031.rs +++ b/tests/ui/layout/ice-type-error-in-tail-124031.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "$$BITS bits" +//@ normalize-stderr: "\d+ bits" -> "$$BITS bits" // Regression test for issue #124031 // Checks that we don't ICE when the tail diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs index 2c8179a63d80..328d204aa3cd 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/issue-96185-overaligned-enum.rs b/tests/ui/layout/issue-96185-overaligned-enum.rs index 88863d14cb7f..341233a7890e 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.rs +++ b/tests/ui/layout/issue-96185-overaligned-enum.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/layout/struct.rs b/tests/ui/layout/struct.rs index 309624e667cc..5f652b3d570d 100644 --- a/tests/ui/layout/struct.rs +++ b/tests/ui/layout/struct.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" //! Various struct layout tests. #![feature(rustc_attrs)] diff --git a/tests/ui/layout/valid_range_oob.rs b/tests/ui/layout/valid_range_oob.rs index 38ab5cec7a66..df816e740663 100644 --- a/tests/ui/layout/valid_range_oob.rs +++ b/tests/ui/layout/valid_range_oob.rs @@ -1,6 +1,6 @@ //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] diff --git a/tests/ui/layout/zero-sized-array-enum-niche.rs b/tests/ui/layout/zero-sized-array-enum-niche.rs index 433db46b7a00..152f44bd8637 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.rs +++ b/tests/ui/layout/zero-sized-array-enum-niche.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN" #![crate_type = "lib"] #![feature(rustc_attrs)] diff --git a/tests/ui/limits/huge-enum.rs b/tests/ui/limits/huge-enum.rs index 5664d0ba5166..66c5be20693d 100644 --- a/tests/ui/limits/huge-enum.rs +++ b/tests/ui/limits/huge-enum.rs @@ -1,6 +1,6 @@ //@ build-fail -//@ normalize-stderr-test: "std::option::Option<\[u32; \d+\]>" -> "TYPE" -//@ normalize-stderr-test: "\[u32; \d+\]" -> "TYPE" +//@ normalize-stderr: "std::option::Option<\[u32; \d+\]>" -> "TYPE" +//@ normalize-stderr: "\[u32; \d+\]" -> "TYPE" #[cfg(target_pointer_width = "32")] type BIG = Option<[u32; (1<<29)-1]>; diff --git a/tests/ui/limits/huge-struct.rs b/tests/ui/limits/huge-struct.rs index bf132d359f5b..296147015bfe 100644 --- a/tests/ui/limits/huge-struct.rs +++ b/tests/ui/limits/huge-struct.rs @@ -1,8 +1,8 @@ // ignore-tidy-linelength //@ build-fail -//@ normalize-stderr-test: "S32" -> "SXX" -//@ normalize-stderr-test: "S1M" -> "SXX" -//@ normalize-stderr-test: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" +//@ normalize-stderr: "S32" -> "SXX" +//@ normalize-stderr: "S1M" -> "SXX" +//@ normalize-stderr: "values of the type `[^`]+` are too big" -> "values of the type $$REALLY_TOO_BIG are too big" struct S32 { v0: T, diff --git a/tests/ui/limits/issue-17913.rs b/tests/ui/limits/issue-17913.rs index 24fd3b542e6a..5407902daba5 100644 --- a/tests/ui/limits/issue-17913.rs +++ b/tests/ui/limits/issue-17913.rs @@ -1,5 +1,5 @@ //@ build-fail -//@ normalize-stderr-test: "\[&usize; \d+\]" -> "[&usize; usize::MAX]" +//@ normalize-stderr: "\[&usize; \d+\]" -> "[&usize; usize::MAX]" //@ error-pattern: too big for the target architecture #[cfg(target_pointer_width = "64")] diff --git a/tests/ui/link-native-libs/msvc-non-utf8-output.rs b/tests/ui/link-native-libs/msvc-non-utf8-output.rs index 659a832247a9..03b1f6516ab9 100644 --- a/tests/ui/link-native-libs/msvc-non-utf8-output.rs +++ b/tests/ui/link-native-libs/msvc-non-utf8-output.rs @@ -1,5 +1,5 @@ //@ build-fail //@ compile-flags:-C link-arg=⦺ⅈ⽯⭏⽽◃⡽⚞ //@ only-msvc -//@ normalize-stderr-test: "(?:.|\n)*(⦺ⅈ⽯⭏⽽◃⡽⚞)(?:.|\n)*" -> "$1" +//@ normalize-stderr: "(?:.|\n)*(⦺ⅈ⽯⭏⽽◃⡽⚞)(?:.|\n)*" -> "$1" pub fn main() {} diff --git a/tests/ui/lint/lint-overflowing-ops.rs b/tests/ui/lint/lint-overflowing-ops.rs index eec347010ad6..116460f11cc0 100644 --- a/tests/ui/lint/lint-overflowing-ops.rs +++ b/tests/ui/lint/lint-overflowing-ops.rs @@ -11,8 +11,8 @@ //@ [opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -Z deduplicate-diagnostics=yes //@ build-fail //@ ignore-pass (test tests codegen-time behaviour) -//@ normalize-stderr-test: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" -//@ normalize-stderr-test: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" +//@ normalize-stderr: "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" +//@ normalize-stderr: "shift right by `(64|32)_usize`, which" -> "shift right by `%BITS%`, which" #![deny(arithmetic_overflow)] diff --git a/tests/ui/lto/lto-duplicate-symbols.rs b/tests/ui/lto/lto-duplicate-symbols.rs index 679d44baae78..27bdde418f85 100644 --- a/tests/ui/lto/lto-duplicate-symbols.rs +++ b/tests/ui/lto/lto-duplicate-symbols.rs @@ -4,7 +4,7 @@ //@ error-pattern:Linking globals named 'foo': symbol multiply defined! //@ compile-flags: -C lto //@ no-prefer-dynamic -//@ normalize-stderr-test: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu" +//@ normalize-stderr: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu" extern crate lto_duplicate_symbols1; extern crate lto_duplicate_symbols2; diff --git a/tests/ui/macros/macros-nonfatal-errors.rs b/tests/ui/macros/macros-nonfatal-errors.rs index 658455b1b5b8..79beffbe986e 100644 --- a/tests/ui/macros/macros-nonfatal-errors.rs +++ b/tests/ui/macros/macros-nonfatal-errors.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" +//@ normalize-stderr: "`: .*" -> "`: $$FILE_NOT_FOUND_MSG" // test that errors in a (selection) of macros don't kill compilation // immediately, so that we get more errors listed at a time. diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs index 265ef93425a2..9b9eb91559b3 100644 --- a/tests/ui/methods/inherent-bound-in-probe.rs +++ b/tests/ui/methods/inherent-bound-in-probe.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" // Fixes #110131 // diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index ded02150342d..3e0cc4ee0614 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -2,10 +2,10 @@ //@ failure-status: 101 //@ error-pattern: broken MIR in //@ error-pattern: StorageLive(_1) which already has storage here -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "storage_live\[....\]" -> "storage_live[HASH]" -//@ normalize-stderr-test: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "storage_live\[....\]" -> "storage_live[HASH]" +//@ normalize-stderr: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " //@ rustc-env:RUST_BACKTRACE=0 #![feature(custom_mir, core_intrinsics)] diff --git a/tests/ui/modules/path-no-file-name.rs b/tests/ui/modules/path-no-file-name.rs index c36043686fcf..23127346e02a 100644 --- a/tests/ui/modules/path-no-file-name.rs +++ b/tests/ui/modules/path-no-file-name.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "\.:.*\(" -> ".: $$ACCESS_DENIED_MSG (" -//@ normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" +//@ normalize-stderr: "\.:.*\(" -> ".: $$ACCESS_DENIED_MSG (" +//@ normalize-stderr: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" #[path = "."] mod m; //~ ERROR couldn't read diff --git a/tests/ui/packed/packed-struct-transmute.rs b/tests/ui/packed/packed-struct-transmute.rs index 0a887e3886d5..98feeea88714 100644 --- a/tests/ui/packed/packed-struct-transmute.rs +++ b/tests/ui/packed/packed-struct-transmute.rs @@ -3,7 +3,7 @@ // the error points to the start of the file, not the line with the // transmute -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" //@ error-pattern: cannot transmute between types of different sizes, or dependently-sized types use std::mem; diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 82e6de43a2ec..4eb05b5365fe 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" //@ error-pattern: found duplicate lang item `panic_impl` extern crate core; diff --git a/tests/ui/panics/default-backtrace-ice.rs b/tests/ui/panics/default-backtrace-ice.rs index 7953283f0281..c47f458f6e97 100644 --- a/tests/ui/panics/default-backtrace-ice.rs +++ b/tests/ui/panics/default-backtrace-ice.rs @@ -5,12 +5,12 @@ //@ error-pattern:__rust_begin_short_backtrace //@ failure-status:101 //@ ignore-msvc -//@ normalize-stderr-test: "note: .*" -> "" -//@ normalize-stderr-test: "thread 'rustc' .*" -> "" -//@ normalize-stderr-test: " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" -//@ normalize-stderr-test: " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" -//@ normalize-stderr-test: " +\d+:.*\n" -> "" -//@ normalize-stderr-test: " +at .*\n" -> "" +//@ normalize-stderr: "note: .*" -> "" +//@ normalize-stderr: "thread 'rustc' .*" -> "" +//@ normalize-stderr: " +\d+:.*__rust_begin_short_backtrace.*" -> "(begin_short_backtrace)" +//@ normalize-stderr: " +\d+:.*__rust_end_short_backtrace.*" -> "(end_short_backtrace)" +//@ normalize-stderr: " +\d+:.*\n" -> "" +//@ normalize-stderr: " +at .*\n" -> "" // // This test makes sure that full backtraces are used for ICEs when // RUST_BACKTRACE is not set. It does this by checking for the presence of diff --git a/tests/ui/panics/issue-47429-short-backtraces.rs b/tests/ui/panics/issue-47429-short-backtraces.rs index 56b9cfcd3615..dff885af1b87 100644 --- a/tests/ui/panics/issue-47429-short-backtraces.rs +++ b/tests/ui/panics/issue-47429-short-backtraces.rs @@ -8,11 +8,11 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" // This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) -//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test //@ ignore-android FIXME #17520 diff --git a/tests/ui/panics/panic-in-cleanup.rs b/tests/ui/panics/panic-in-cleanup.rs index c3639c7034eb..8cddeb37348d 100644 --- a/tests/ui/panics/panic-in-cleanup.rs +++ b/tests/ui/panics/panic-in-cleanup.rs @@ -2,9 +2,9 @@ //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panic in a destructor during cleanup -//@ normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output //@ ignore-msvc SEH doesn't do panic-during-cleanup the same way as everyone else diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs index c0ae1899f4c2..6068e4fdc59b 100644 --- a/tests/ui/panics/panic-in-ffi.rs +++ b/tests/ui/panics/panic-in-ffi.rs @@ -3,9 +3,9 @@ //@ check-run-results //@ error-pattern: panic in a function that cannot unwind //@ error-pattern: Noisy Drop -//@ normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output diff --git a/tests/ui/panics/panic-in-message-fmt.rs b/tests/ui/panics/panic-in-message-fmt.rs index e5bedf96b357..1e9bbaf45c54 100644 --- a/tests/ui/panics/panic-in-message-fmt.rs +++ b/tests/ui/panics/panic-in-message-fmt.rs @@ -4,9 +4,9 @@ //@ exec-env:RUST_BACKTRACE=0 //@ check-run-results //@ error-pattern: panicked while processing panic -//@ normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" -//@ normalize-stderr-test: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" //@ ignore-emscripten "RuntimeError" junk in output use std::fmt::{Display, self}; diff --git a/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs b/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs index 70c4a5aaf2b9..a56214b73bf0 100644 --- a/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs +++ b/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -17,7 +17,7 @@ // We need to normalize out frame 5 because without debug info, dbghelp.dll doesn't know where CGU // internal functions like `main` start or end and so it will return whatever symbol happens // to be located near the address. -//@ normalize-stderr-test: "5: .*" -> "5: some Rust fn" +//@ normalize-stderr: "5: .*" -> "5: some Rust fn" // Backtraces are pretty broken in general on i686-pc-windows-msvc (#62897). //@ only-x86_64-pc-windows-msvc diff --git a/tests/ui/panics/runtime-switch.rs b/tests/ui/panics/runtime-switch.rs index e06f05d5fe8e..ffd038f95351 100644 --- a/tests/ui/panics/runtime-switch.rs +++ b/tests/ui/panics/runtime-switch.rs @@ -8,11 +8,11 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" // This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) -//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" //@ ignore-msvc see #62897 and `backtrace-debuginfo.rs` test //@ ignore-android FIXME #17520 diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs index 9b6d34d97b2f..48f60b141706 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs @@ -11,11 +11,11 @@ //@ ignore-msvc the `__rust_{begin,end}_short_backtrace` symbols aren't reliable. // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" // This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) -//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" /// This test case make sure that we can have multiple pairs of `__rust_{begin,end}_short_backtrace` diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs index b1af247130b1..216c51277995 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames.rs @@ -12,11 +12,11 @@ // This is needed to avoid test output differences across std being built with v0 symbols vs legacy // symbols. -//@ normalize-stderr-test: "begin_panic::<&str>" -> "begin_panic" +//@ normalize-stderr: "begin_panic::<&str>" -> "begin_panic" // This variant occurs on macOS with `rust.debuginfo-level = "line-tables-only"` (#133997) -//@ normalize-stderr-test: " begin_panic<&str>" -> " std::panicking::begin_panic" +//@ normalize-stderr: " begin_panic<&str>" -> " std::panicking::begin_panic" // And this is for differences between std with and without debuginfo. -//@ normalize-stderr-test: "\n +at [^\n]+" -> "" +//@ normalize-stderr: "\n +at [^\n]+" -> "" #[inline(never)] fn __rust_begin_short_backtrace T>(f: F) -> T { diff --git a/tests/ui/parser/issues/issue-5806.rs b/tests/ui/parser/issues/issue-5806.rs index 3f1b7cda9316..dbd53a7adc43 100644 --- a/tests/ui/parser/issues/issue-5806.rs +++ b/tests/ui/parser/issues/issue-5806.rs @@ -1,5 +1,5 @@ -//@ normalize-stderr-test: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG (" -//@ normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" +//@ normalize-stderr: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG (" +//@ normalize-stderr: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" #[path = "../parser"] mod foo; //~ ERROR couldn't read diff --git a/tests/ui/parser/mod_file_with_path_attr.rs b/tests/ui/parser/mod_file_with_path_attr.rs index e2854f3cc8d9..ff964f750e29 100644 --- a/tests/ui/parser/mod_file_with_path_attr.rs +++ b/tests/ui/parser/mod_file_with_path_attr.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG (" +//@ normalize-stderr: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG (" #[path = "not_a_real_file.rs"] mod m; //~ ERROR not_a_real_file.rs diff --git a/tests/ui/print-request/macos-target.rs b/tests/ui/print-request/macos-target.rs index af74babbed48..70122a525802 100644 --- a/tests/ui/print-request/macos-target.rs +++ b/tests/ui/print-request/macos-target.rs @@ -1,8 +1,8 @@ //@ only-apple //@ compile-flags: --print deployment-target -//@ normalize-stdout-test: "\w*_DEPLOYMENT_TARGET" -> "$$OS_DEPLOYMENT_TARGET" -//@ normalize-stdout-test: "\d+\." -> "$$CURRENT_MAJOR_VERSION." -//@ normalize-stdout-test: "\d+" -> "$$CURRENT_MINOR_VERSION" +//@ normalize-stdout: "\w*_DEPLOYMENT_TARGET" -> "$$OS_DEPLOYMENT_TARGET" +//@ normalize-stdout: "\d+\." -> "$$CURRENT_MAJOR_VERSION." +//@ normalize-stdout: "\d+" -> "$$CURRENT_MINOR_VERSION" //@ check-pass fn main() {} diff --git a/tests/ui/proc-macro/load-panic-backtrace.rs b/tests/ui/proc-macro/load-panic-backtrace.rs index 302bcaea75e6..848bdaf9f372 100644 --- a/tests/ui/proc-macro/load-panic-backtrace.rs +++ b/tests/ui/proc-macro/load-panic-backtrace.rs @@ -1,8 +1,8 @@ //@ proc-macro: test-macros.rs //@ compile-flags: -Z proc-macro-backtrace //@ rustc-env:RUST_BACKTRACE=0 -//@ normalize-stderr-test: "thread '.*' panicked " -> "" -//@ normalize-stderr-test: "note:.*RUST_BACKTRACE=1.*\n" -> "" +//@ normalize-stderr: "thread '.*' panicked " -> "" +//@ normalize-stderr: "note:.*RUST_BACKTRACE=1.*\n" -> "" //@ needs-unwind proc macro panics to report errors #[macro_use] diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs index 9fbe9763b44d..afe0e1fb601a 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.rs +++ b/tests/ui/proc-macro/meta-macro-hygiene.rs @@ -4,9 +4,9 @@ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index ae02b24e1d0e..fae8446515af 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -8,9 +8,9 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no //@ check-pass // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs index 76c71441c808..e2aedb245d07 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs @@ -4,9 +4,9 @@ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene //@ compile-flags: -Z trim-diagnostic-paths=no // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" //@ proc-macro: test-macros.rs #![feature(decl_macro)] diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 1ad140590281..e7dda7d3c160 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -28,9 +28,9 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ //@ compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene //@ compile-flags: -Z trim-diagnostic-paths=no // ignore-tidy-linelength -//@ normalize-stdout-test: "\d+#" -> "0#" -//@ normalize-stdout-test: "expn\d{3,}" -> "expnNNN" -//@ normalize-stdout-test: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" +//@ normalize-stdout: "\d+#" -> "0#" +//@ normalize-stdout: "expn\d{3,}" -> "expnNNN" +//@ normalize-stdout: "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" //@ proc-macro: test-macros.rs #![feature /* 0#0 */(decl_macro)] diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index 4ac1f7c98cbd..d88c6dcc12b3 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -5,7 +5,7 @@ //@ ignore-fuchsia //@ ignore-horizon //@ ignore-android -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ compile-flags: -Zon-broken-pipe=error // Test what the error message looks like when `println!()` panics because of diff --git a/tests/ui/recursion/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs index 2880b9564170..3e14fa92dd0f 100644 --- a/tests/ui/recursion/issue-23122-2.rs +++ b/tests/ui/recursion/issue-23122-2.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" trait Next { type Next: Next; } diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs index e919a2d93096..ea1bef4fce39 100644 --- a/tests/ui/recursion/issue-83150.rs +++ b/tests/ui/recursion/issue-83150.rs @@ -1,7 +1,7 @@ //~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator` //@ build-fail //@ compile-flags: -Copt-level=0 -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" fn main() { let mut iter = 0u8..1; diff --git a/tests/ui/recursion/recursion.rs b/tests/ui/recursion/recursion.rs index 074e9ed6947a..f3c633983b19 100644 --- a/tests/ui/recursion/recursion.rs +++ b/tests/ui/recursion/recursion.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags:-C overflow-checks=off -//@ normalize-stderr-test: ".nll/" -> "/" +//@ normalize-stderr: ".nll/" -> "/" enum Nil {NilValue} struct Cons {head:isize, tail:T} diff --git a/tests/ui/regions/issue-102374.rs b/tests/ui/regions/issue-102374.rs index db2b38334b5d..d640c29b2f4c 100644 --- a/tests/ui/regions/issue-102374.rs +++ b/tests/ui/regions/issue-102374.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" use std::cell::Cell; #[rustfmt::skip] diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index cc080b2e59ad..3e8ae3d096d8 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -6,7 +6,7 @@ // See also: repr-c-int-dead-variants.rs -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" // This test depends on the value of the `c_enum_min_bits` target option. // As there's no way to actually check it from UI test, we only run this test on a subset of archs. diff --git a/tests/ui/repr/repr-c-int-dead-variants.rs b/tests/ui/repr/repr-c-int-dead-variants.rs index ed26174343a4..627569e080d4 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.rs +++ b/tests/ui/repr/repr-c-int-dead-variants.rs @@ -3,7 +3,7 @@ // See also: repr-c-dead-variants.rs -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" // A simple uninhabited type. enum Void {} diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs index 7d649476ad2a..155abafdd9d9 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.rs +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -4,9 +4,9 @@ //@known-bug: #120873 //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 #[repr(packed)] diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs index 8459fb79f1ed..0cba3c1616d7 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.rs +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -4,9 +4,9 @@ //@proc-macro: proc_macro_generate_packed.rs //@known-bug: #120873 //@ failure-status: 101 -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*\n" -> "" -//@ normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> "" +//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " //@ rustc-env:RUST_BACKTRACE=0 extern crate proc_macro_generate_packed; diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs index ea9d48e7859d..e69a45379352 100644 --- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs +++ b/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs @@ -2,12 +2,12 @@ //@ needs-dlltool //@ compile-flags: --crate-type lib --emit link -//@ normalize-stderr-test: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" -//@ normalize-stderr-test: "[^ ]*/foo.dll_imports.def" -> "$$DEF_FILE" -//@ normalize-stderr-test: "[^ ]*/foo.dll_imports.lib" -> "$$LIB_FILE" -//@ normalize-stderr-test: "-m [^ ]*" -> "$$TARGET_MACHINE" -//@ normalize-stderr-test: "-f [^ ]*" -> "$$ASM_FLAGS" -//@ normalize-stderr-test: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX" +//@ normalize-stderr: "[^ ']*/dlltool.exe" -> "$$DLLTOOL" +//@ normalize-stderr: "[^ ]*/foo.dll_imports.def" -> "$$DEF_FILE" +//@ normalize-stderr: "[^ ]*/foo.dll_imports.lib" -> "$$LIB_FILE" +//@ normalize-stderr: "-m [^ ]*" -> "$$TARGET_MACHINE" +//@ normalize-stderr: "-f [^ ]*" -> "$$ASM_FLAGS" +//@ normalize-stderr: "--temp-prefix [^ ]*/foo.dll" -> "$$TEMP_PREFIX" #[link(name = "foo", kind = "raw-dylib")] extern "C" { // `@1` is an invalid name to export, as it usually indicates that something diff --git a/tests/ui/statics/mutable_memory_validation.rs b/tests/ui/statics/mutable_memory_validation.rs index 032b903f64e5..3bb572d38bc5 100644 --- a/tests/ui/statics/mutable_memory_validation.rs +++ b/tests/ui/statics/mutable_memory_validation.rs @@ -1,8 +1,8 @@ //issue: rust-lang/rust#122548 // Strip out raw byte dumps to make comparison platform-independent: -//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" -//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" use std::cell::UnsafeCell; diff --git a/tests/ui/svh/changing-crates.rs b/tests/ui/svh/changing-crates.rs index 78075a5c75fa..39a6473c8d91 100644 --- a/tests/ui/svh/changing-crates.rs +++ b/tests/ui/svh/changing-crates.rs @@ -2,7 +2,7 @@ //@ aux-build:changing-crates-a1.rs //@ aux-build:changing-crates-b.rs //@ aux-build:changing-crates-a2.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-lit.rs b/tests/ui/svh/svh-change-lit.rs index 6ecdd9f2c084..66f739e144ef 100644 --- a/tests/ui/svh/svh-change-lit.rs +++ b/tests/ui/svh/svh-change-lit.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-lit.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-significant-cfg.rs b/tests/ui/svh/svh-change-significant-cfg.rs index c03560ee5112..9e736788d138 100644 --- a/tests/ui/svh/svh-change-significant-cfg.rs +++ b/tests/ui/svh/svh-change-significant-cfg.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-significant-cfg.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-trait-bound.rs b/tests/ui/svh/svh-change-trait-bound.rs index 4bbbf45a8866..1e0fa15b94a0 100644 --- a/tests/ui/svh/svh-change-trait-bound.rs +++ b/tests/ui/svh/svh-change-trait-bound.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-trait-bound.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-type-arg.rs b/tests/ui/svh/svh-change-type-arg.rs index cdc5cf24272f..f275a38acc48 100644 --- a/tests/ui/svh/svh-change-type-arg.rs +++ b/tests/ui/svh/svh-change-type-arg.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-type-arg.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-type-ret.rs b/tests/ui/svh/svh-change-type-ret.rs index f2a579fab630..76118dc9f696 100644 --- a/tests/ui/svh/svh-change-type-ret.rs +++ b/tests/ui/svh/svh-change-type-ret.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-type-ret.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-change-type-static.rs b/tests/ui/svh/svh-change-type-static.rs index 489923ddecf5..6a658ca36dc9 100644 --- a/tests/ui/svh/svh-change-type-static.rs +++ b/tests/ui/svh/svh-change-type-static.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-a-base.rs //@ aux-build:svh-b.rs //@ aux-build:svh-a-change-type-static.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" extern crate a; extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on diff --git a/tests/ui/svh/svh-use-trait.rs b/tests/ui/svh/svh-use-trait.rs index 8ac4cc426054..4791bfb50066 100644 --- a/tests/ui/svh/svh-use-trait.rs +++ b/tests/ui/svh/svh-use-trait.rs @@ -2,7 +2,7 @@ //@ aux-build:svh-uta-base.rs //@ aux-build:svh-utb.rs //@ aux-build:svh-uta-change-use-trait.rs -//@ normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" +//@ normalize-stderr: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" //! "svh-uta-trait.rs" is checking that we detect a //! change from `use foo::TraitB` to use `foo::TraitB` in the hash diff --git a/tests/ui/symbol-names/const-generics-demangling.rs b/tests/ui/symbol-names/const-generics-demangling.rs index 86f24f6af6ad..9c078d4192a9 100644 --- a/tests/ui/symbol-names/const-generics-demangling.rs +++ b/tests/ui/symbol-names/const-generics-demangling.rs @@ -3,8 +3,8 @@ //@ compile-flags: --crate-name=c //@[legacy]compile-flags: -C symbol-mangling-version=legacy -Z unstable-options //@ [v0]compile-flags: -C symbol-mangling-version=v0 -//@[legacy]normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]" -//@ [v0]normalize-stderr-test: "c\[.*?\]" -> "c[HASH]" +//@[legacy]normalize-stderr: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0]normalize-stderr: "c\[.*?\]" -> "c[HASH]" #![feature(rustc_attrs)] pub struct Unsigned; diff --git a/tests/ui/symbol-names/const-generics-str-demangling.rs b/tests/ui/symbol-names/const-generics-str-demangling.rs index 87b1fdf8a479..94c3b4c44488 100644 --- a/tests/ui/symbol-names/const-generics-str-demangling.rs +++ b/tests/ui/symbol-names/const-generics-str-demangling.rs @@ -1,6 +1,6 @@ //@ build-fail //@ compile-flags: -C symbol-mangling-version=v0 --crate-name=c -//@ normalize-stderr-test: "c\[.*?\]" -> "c[HASH]" +//@ normalize-stderr: "c\[.*?\]" -> "c[HASH]" #![feature(adt_const_params, unsized_const_params, rustc_attrs)] #![allow(incomplete_features)] diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.rs b/tests/ui/symbol-names/const-generics-structural-demangling.rs index 9f5f31177b38..06e3ce51fa6a 100644 --- a/tests/ui/symbol-names/const-generics-structural-demangling.rs +++ b/tests/ui/symbol-names/const-generics-structural-demangling.rs @@ -1,7 +1,7 @@ //@ build-fail //@ compile-flags: -C symbol-mangling-version=v0 --crate-name=c -//@ normalize-stderr-test: "c\[[0-9a-f]+\]" -> "c[HASH]" +//@ normalize-stderr: "c\[[0-9a-f]+\]" -> "c[HASH]" #![feature(adt_const_params, unsized_const_params, decl_macro, rustc_attrs)] #![allow(incomplete_features)] diff --git a/tests/ui/symbol-names/impl1.rs b/tests/ui/symbol-names/impl1.rs index 9aefca47447f..694cd89bd80f 100644 --- a/tests/ui/symbol-names/impl1.rs +++ b/tests/ui/symbol-names/impl1.rs @@ -2,7 +2,7 @@ //@ revisions: legacy v0 //@[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy //@[v0]compile-flags: -C symbol-mangling-version=v0 -//@[legacy]normalize-stderr-test: "h[\w]{16}E?\)" -> ")" +//@[legacy]normalize-stderr: "h[\w]{16}E?\)" -> ")" #![feature(auto_traits, rustc_attrs)] #![allow(dead_code)] diff --git a/tests/ui/symbol-names/issue-75326.rs b/tests/ui/symbol-names/issue-75326.rs index a6aef3ddd7df..c60b872b0a23 100644 --- a/tests/ui/symbol-names/issue-75326.rs +++ b/tests/ui/symbol-names/issue-75326.rs @@ -2,7 +2,7 @@ //@ revisions: legacy v0 //@[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy //@[v0]compile-flags: -C symbol-mangling-version=v0 -//@[legacy]normalize-stderr-test: "h[\w{16}]+" -> "SYMBOL_HASH" +//@[legacy]normalize-stderr: "h[\w{16}]+" -> "SYMBOL_HASH" #![feature(rustc_attrs)] diff --git a/tests/ui/symbol-names/trait-objects.rs b/tests/ui/symbol-names/trait-objects.rs index d3fa40d1f391..da48190285da 100644 --- a/tests/ui/symbol-names/trait-objects.rs +++ b/tests/ui/symbol-names/trait-objects.rs @@ -3,7 +3,7 @@ //@ build-fail //@ revisions: v0 //@[v0]compile-flags: -C symbol-mangling-version=v0 -//@[v0]normalize-stderr-test: "core\[.*?\]" -> "core[HASH]" +//@[v0]normalize-stderr: "core\[.*?\]" -> "core[HASH]" #![feature(rustc_attrs)] diff --git a/tests/ui/symbol-names/types.rs b/tests/ui/symbol-names/types.rs index 38735e1aa509..a4bbbaa02f27 100644 --- a/tests/ui/symbol-names/types.rs +++ b/tests/ui/symbol-names/types.rs @@ -4,8 +4,8 @@ //@ [legacy] compile-flags: -Csymbol-mangling-version=legacy //@ [verbose-legacy] compile-flags: -Csymbol-mangling-version=legacy -Zverbose-internals //@ [v0] compile-flags: -Csymbol-mangling-version=v0 -//@ normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]" -//@ [v0] normalize-stderr-test: "\[[[:xdigit:]]{16}\]" -> "[HASH]" +//@ normalize-stderr: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0] normalize-stderr: "\[[[:xdigit:]]{16}\]" -> "[HASH]" #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/tests/ui/test-attrs/terse.rs b/tests/ui/test-attrs/terse.rs index 74e189158570..6c3f29ed10f9 100644 --- a/tests/ui/test-attrs/terse.rs +++ b/tests/ui/test-attrs/terse.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 --quiet //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-filter-multiple.rs b/tests/ui/test-attrs/test-filter-multiple.rs index c875929e6724..49211c61e18a 100644 --- a/tests/ui/test-attrs/test-filter-multiple.rs +++ b/tests/ui/test-attrs/test-filter-multiple.rs @@ -2,7 +2,7 @@ //@ compile-flags: --test //@ run-flags: --test-threads=1 test1 test2 //@ check-run-results -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ needs-threads #[test] diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.rs b/tests/ui/test-attrs/test-panic-abort-nocapture.rs index f3485d9c1fa9..4377ae1ac3bd 100644 --- a/tests/ui/test-attrs/test-panic-abort-nocapture.rs +++ b/tests/ui/test-attrs/test-panic-abort-nocapture.rs @@ -4,7 +4,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-android #120567 //@ ignore-wasm no panic or subprocess support diff --git a/tests/ui/test-attrs/test-panic-abort.rs b/tests/ui/test-attrs/test-panic-abort.rs index 84740161a708..3d203e059a46 100644 --- a/tests/ui/test-attrs/test-panic-abort.rs +++ b/tests/ui/test-attrs/test-panic-abort.rs @@ -4,7 +4,7 @@ //@ run-fail //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-android #120567 //@ ignore-wasm no panic or subprocess support diff --git a/tests/ui/test-attrs/test-passed.rs b/tests/ui/test-attrs/test-passed.rs index 2a3fca7f002e..959470adcc42 100644 --- a/tests/ui/test-attrs/test-passed.rs +++ b/tests/ui/test-attrs/test-passed.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 //@ run-pass //@ check-run-results -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" // Tests the output of the test harness with only passed tests. diff --git a/tests/ui/test-attrs/test-thread-capture.rs b/tests/ui/test-attrs/test-thread-capture.rs index 75ff4e0ece64..c56f87f2ddac 100644 --- a/tests/ui/test-attrs/test-thread-capture.rs +++ b/tests/ui/test-attrs/test-thread-capture.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-thread-nocapture.rs b/tests/ui/test-attrs/test-thread-nocapture.rs index 6a36ea8d7d19..5b82e9b27207 100644 --- a/tests/ui/test-attrs/test-thread-nocapture.rs +++ b/tests/ui/test-attrs/test-thread-nocapture.rs @@ -3,7 +3,7 @@ //@ run-flags: --test-threads=1 --nocapture //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ ignore-emscripten no threads support //@ needs-unwind diff --git a/tests/ui/test-attrs/test-type.rs b/tests/ui/test-attrs/test-type.rs index 1b71ead55b07..51a6b9245cc7 100644 --- a/tests/ui/test-attrs/test-type.rs +++ b/tests/ui/test-attrs/test-type.rs @@ -1,7 +1,7 @@ //@ compile-flags: --test -Zpanic-abort-tests //@ run-flags: --test-threads=1 //@ check-run-results -//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ needs-threads //@ run-pass diff --git a/tests/ui/test-attrs/tests-listing-format-json.rs b/tests/ui/test-attrs/tests-listing-format-json.rs index b735a82c1662..9d57a6bc3834 100644 --- a/tests/ui/test-attrs/tests-listing-format-json.rs +++ b/tests/ui/test-attrs/tests-listing-format-json.rs @@ -4,8 +4,8 @@ //@ run-pass //@ check-run-results //@ only-nightly -//@ normalize-stdout-test: "fake-test-src-base/test-attrs/" -> "$$DIR/" -//@ normalize-stdout-test: "fake-test-src-base\\test-attrs\\" -> "$$DIR/" +//@ normalize-stdout: "fake-test-src-base/test-attrs/" -> "$$DIR/" +//@ normalize-stdout: "fake-test-src-base\\test-attrs\\" -> "$$DIR/" // Checks the listing of tests with --format json. diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs index 5023f34e4c1b..9e81cb53fc11 100644 --- a/tests/ui/track-diagnostics/track.rs +++ b/tests/ui/track-diagnostics/track.rs @@ -5,13 +5,13 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" -//@ normalize-stderr-test: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" // The test becomes too flaky if we care about exact args. If `-Z ui-testing` // from compiletest and `-Z track-diagnostics` from `// compile-flags` at the // top of this file are present, then assume all args are present. -//@ normalize-stderr-test: "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics" +//@ normalize-stderr: "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics" fn main() { break rust diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs index 7466e9246ce6..5805fd21220d 100644 --- a/tests/ui/track-diagnostics/track2.rs +++ b/tests/ui/track-diagnostics/track2.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _moved @ _from = String::from("foo"); diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs index 43ad1dff8b83..bac1fc7e184b 100644 --- a/tests/ui/track-diagnostics/track3.rs +++ b/tests/ui/track-diagnostics/track3.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { let _unimported = Blah { field: u8 }; diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs index bc76f6f14517..ec9e3efa481c 100644 --- a/tests/ui/track-diagnostics/track4.rs +++ b/tests/ui/track-diagnostics/track4.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" pub onion { Owo(u8), diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs index bb82e9a62c8b..e72e3482ad38 100644 --- a/tests/ui/track-diagnostics/track5.rs +++ b/tests/ui/track-diagnostics/track5.rs @@ -3,6 +3,6 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" } diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index fc8df68e6d92..e4d124a22e49 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -3,7 +3,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -//@ normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" pub trait Foo { diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs index 60c3327902e1..98749b8db7ae 100644 --- a/tests/ui/traits/on_unimplemented_long_types.rs +++ b/tests/ui/traits/on_unimplemented_long_types.rs @@ -1,5 +1,5 @@ //@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +//@ normalize-stderr: "long-type-\d+" -> "long-type-hash" pub fn foo() -> impl std::fmt::Display { //~^ ERROR doesn't implement `std::fmt::Display` diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs index ef0a5a7adcaf..d0418e75fab2 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -2,10 +2,10 @@ //@[next] compile-flags: -Znext-solver //@[next] failure-status: 101 //@[next] known-bug: unknown -//@[next] normalize-stderr-test: "note: .*\n\n" -> "" -//@[next] normalize-stderr-test: "thread 'rustc' panicked.*\n.*\n" -> "" -//@[next] normalize-stderr-test: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@[next] normalize-stderr-test: "delayed at .*" -> "" +//@[next] normalize-stderr: "note: .*\n\n" -> "" +//@[next] normalize-stderr: "thread 'rustc' panicked.*\n.*\n" -> "" +//@[next] normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@[next] normalize-stderr: "delayed at .*" -> "" //@[next] rustc-env:RUST_BACKTRACE=0 //@ check-pass diff --git a/tests/ui/transmute/transmute-different-sizes.rs b/tests/ui/transmute/transmute-different-sizes.rs index b7fca2b32783..40197a6c53f0 100644 --- a/tests/ui/transmute/transmute-different-sizes.rs +++ b/tests/ui/transmute/transmute-different-sizes.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" // Tests that `transmute` cannot be called on types of different size. diff --git a/tests/ui/transmute/transmute-fat-pointers.rs b/tests/ui/transmute/transmute-fat-pointers.rs index d1340c5e8604..f095b80dc2da 100644 --- a/tests/ui/transmute/transmute-fat-pointers.rs +++ b/tests/ui/transmute/transmute-fat-pointers.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" // Tests that are conservative around thin/fat pointer mismatches. diff --git a/tests/ui/transmute/transmute-impl.rs b/tests/ui/transmute/transmute-impl.rs index 15d67483cc8d..84951a0ee603 100644 --- a/tests/ui/transmute/transmute-impl.rs +++ b/tests/ui/transmute/transmute-impl.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "\d+ bits" -> "N bits" +//@ normalize-stderr: "\d+ bits" -> "N bits" // Tests that are conservative around thin/fat pointer mismatches. diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs index 82683cdffef6..9f0e293b4cb1 100644 --- a/tests/ui/treat-err-as-bug/err.rs +++ b/tests/ui/treat-err-as-bug/err.rs @@ -2,8 +2,8 @@ //@ failure-status: 101 //@ error-pattern: aborting due to `-Z treat-err-as-bug=1` //@ error-pattern: [eval_static_initializer] evaluating initializer of static `C` -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![crate_type = "rlib"] diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs index 97b8e4a3ddac..296bdd7a12d9 100644 --- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs @@ -2,8 +2,8 @@ //@ failure-status: 101 //@ error-pattern: aborting due to `-Z treat-err-as-bug=1` //@ error-pattern: [trigger_delayed_bug] triggering a delayed bug for testing incremental -//@ normalize-stderr-test: "note: .*\n\n" -> "" -//@ normalize-stderr-test: "thread 'rustc' panicked.*:\n.*\n" -> "" +//@ normalize-stderr: "note: .*\n\n" -> "" +//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(rustc_attrs)] diff --git a/tests/ui/type/pattern_types/range_patterns.rs b/tests/ui/type/pattern_types/range_patterns.rs index 7c25edb1c3fd..ff87444b49e3 100644 --- a/tests/ui/type/pattern_types/range_patterns.rs +++ b/tests/ui/type/pattern_types/range_patterns.rs @@ -2,7 +2,7 @@ #![feature(pattern_type_macro)] #![allow(incomplete_features)] -//@ normalize-stderr-test: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" +//@ normalize-stderr: "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN" use std::pat::pattern_type; diff --git a/tests/ui/unknown-llvm-arg.rs b/tests/ui/unknown-llvm-arg.rs index 17908d36417c..a8fa55a220a5 100644 --- a/tests/ui/unknown-llvm-arg.rs +++ b/tests/ui/unknown-llvm-arg.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Cllvm-args=-not-a-real-llvm-arg -//@ normalize-stderr-test: "--help" -> "-help" -//@ normalize-stderr-test: "\n(\n|.)*" -> "" +//@ normalize-stderr: "--help" -> "-help" +//@ normalize-stderr: "\n(\n|.)*" -> "" // I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". diff --git a/tests/ui/unpretty/avoid-crash.rs b/tests/ui/unpretty/avoid-crash.rs index e2bde8236220..7fcabfe6a8d4 100644 --- a/tests/ui/unpretty/avoid-crash.rs +++ b/tests/ui/unpretty/avoid-crash.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "error `.*`" -> "$$ERROR_MESSAGE" +//@ normalize-stderr: "error `.*`" -> "$$ERROR_MESSAGE" //@ compile-flags: -o. -Zunpretty=ast-tree fn main() {} diff --git a/tests/ui/unpretty/staged-api-invalid-path-108697.rs b/tests/ui/unpretty/staged-api-invalid-path-108697.rs index 1b6ef2491914..71bad213576c 100644 --- a/tests/ui/unpretty/staged-api-invalid-path-108697.rs +++ b/tests/ui/unpretty/staged-api-invalid-path-108697.rs @@ -2,7 +2,7 @@ // ICE: tcx.resolutions(()) is not supported for local crate -Zunpretty=mir // on invalid module path with staged_api //@ compile-flags: -Zunpretty=mir -//@ normalize-stderr-test: "The system cannot find the file specified." -> "No such file or directory" +//@ normalize-stderr: "The system cannot find the file specified." -> "No such file or directory" #![feature(staged_api)] #[path = "lol"] mod foo; From 0af396f183b815be2b9905faee499c5cddf1c0b9 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 24 Dec 2024 11:04:12 +0000 Subject: [PATCH 038/113] Fix mistake in windows file open --- library/std/src/sys/pal/windows/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index dda4259919b6..553049099fc2 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -323,7 +323,7 @@ impl File { let alloc = c::FILE_ALLOCATION_INFO { AllocationSize: 0 }; let result = c::SetFileInformationByHandle( handle.as_raw_handle(), - c::FileEndOfFileInfo, + c::FileAllocationInfo, (&raw const alloc).cast::(), mem::size_of::() as u32, ); From 54b130afa268f886bddb93e7cf086c75ae0f1529 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 26 Dec 2024 12:03:37 +0000 Subject: [PATCH 039/113] Fix renaming symlinks on Windows Previously we only detected mount points and not other types of links when determining reparse point behaviour. --- library/std/src/fs/tests.rs | 29 +++++++++++++++++++++++++++ library/std/src/sys/pal/windows/fs.rs | 17 +++++++++------- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 0308a5f433a9..28f16da1ed8d 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1953,3 +1953,32 @@ fn test_rename_directory_to_non_empty_directory() { error!(fs::rename(source_path, target_path), 145); // ERROR_DIR_NOT_EMPTY } + +#[test] +fn test_rename_symlink() { + let tmpdir = tmpdir(); + let original = tmpdir.join("original"); + let dest = tmpdir.join("dest"); + let not_exist = Path::new("does not exist"); + + symlink_file(not_exist, &original).unwrap(); + fs::rename(&original, &dest).unwrap(); + // Make sure that renaming `original` to `dest` preserves the symlink. + assert_eq!(fs::read_link(&dest).unwrap().as_path(), not_exist); +} + +#[test] +#[cfg(windows)] +fn test_rename_junction() { + let tmpdir = tmpdir(); + let original = tmpdir.join("original"); + let dest = tmpdir.join("dest"); + let not_exist = Path::new("does not exist"); + + junction_point(¬_exist, &original).unwrap(); + fs::rename(&original, &dest).unwrap(); + + // Make sure that renaming `original` to `dest` preserves the junction point. + // Junction links are always absolute so we just check the file name is correct. + assert_eq!(fs::read_link(&dest).unwrap().file_name(), Some(not_exist.as_os_str())); +} diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index dda4259919b6..2f300e32d7c8 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1295,15 +1295,18 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> { } else { // SAFETY: The struct has been initialized by GetFileInformationByHandleEx let file_attribute_tag_info = unsafe { file_attribute_tag_info.assume_init() }; + let file_type = FileType::new( + file_attribute_tag_info.FileAttributes, + file_attribute_tag_info.ReparseTag, + ); - if file_attribute_tag_info.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 - && file_attribute_tag_info.ReparseTag != c::IO_REPARSE_TAG_MOUNT_POINT - { - // The file is not a mount point: Reopen the file without inhibiting reparse point behavior. - None - } else { - // The file is a mount point: Don't reopen the file so that the mount point gets renamed. + if file_type.is_symlink() { + // The file is a mount point, junction point or symlink so + // don't reopen the file so that the link gets renamed. Some(Ok(handle)) + } else { + // Otherwise reopen the file without inhibiting reparse point behavior. + None } } } From 454c09e355e0122fceaa770a3903c0ec9547bc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 26 Dec 2024 14:09:27 +0100 Subject: [PATCH 040/113] Spruce up the docs of several queries related to the type/trait system and const eval --- .../src/const_eval/fn_queries.rs | 14 +- compiler/rustc_middle/src/query/mod.rs | 313 ++++++++++++------ .../bugs/cycle-iat-inside-of-adt.stderr | 4 +- 3 files changed, 224 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index babf99c4c1fe..8af17d01b0a3 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -15,20 +15,14 @@ fn parent_impl_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness } } -/// Checks whether an item is considered to be `const`. If it is a constructor, it is const. -/// If it is an assoc method or function, -/// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic -/// has a `rustc_const_{un,}stable` attribute. Otherwise, panic. +/// Checks whether a function-like definition is considered to be `const`. fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { let node = tcx.hir_node_by_def_id(def_id); match node { - hir::Node::Ctor(hir::VariantData::Tuple(..)) - | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => { - hir::Constness::Const - } - hir::Node::ForeignItem(_) => { - // Foreign items cannot be evaluated at compile-time. + hir::Node::Ctor(hir::VariantData::Tuple(..)) => hir::Constness::Const, + hir::Node::ForeignItem(item) if let hir::ForeignItemKind::Fn(..) = item.kind => { + // Foreign functions cannot be evaluated at compile-time. hir::Constness::NotConst } hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2c2dffe8b88f..7e7b602c560b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -132,6 +132,7 @@ rustc_queries! { } /// Return the span for a definition. + /// /// Contrary to `def_span` below, this query returns the full absolute span of the definition. /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside /// of rustc_middle::hir::source_map. @@ -142,6 +143,7 @@ rustc_queries! { } /// Represents crate as a whole (as distinct from the top-level crate module). + /// /// If you call `hir_crate` (e.g., indirectly by calling `tcx.hir().krate()`), /// we will have to assume that any change means that you need to be recompiled. /// This is because the `hir_crate` query gives you access to all other items. @@ -202,28 +204,40 @@ rustc_queries! { feedable } - /// Given the def_id of a const-generic parameter, computes the associated default const - /// parameter. e.g. `fn example` called on `N` would return `3`. + /// Returns the *default* of the const pararameter given by `DefId`. + /// + /// E.g., given `struct Ty;` this returns `3` for `N`. query const_param_default(param: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { - desc { |tcx| "computing const default for a given parameter `{}`", tcx.def_path_str(param) } + desc { |tcx| "computing the default for const parameter `{}`", tcx.def_path_str(param) } cache_on_disk_if { param.is_local() } separate_provide_extern } - /// Returns the [`Ty`][rustc_middle::ty::Ty] of the given [`DefId`]. If the [`DefId`] points - /// to an alias, it will "skip" this alias to return the aliased type. + /// Returns the *type* of the definition given by `DefId`. /// - /// [`DefId`]: rustc_hir::def_id::DefId + /// For type aliases (whether eager or lazy) and associated types, this returns + /// the underlying aliased type (not the corresponding [alias type]). + /// + /// For opaque types, this returns and thus reveals the hidden type! If you + /// want to detect cycle errors use `type_of_opaque` instead. + /// + /// To clarify, for type definitions, this does *not* return the "type of a type" + /// (aka *kind* or *sort*) in the type-theoretical sense! It merely returns + /// the type primarily *associated with* it. + /// + /// # Panics + /// + /// This query will panic if the given definition doesn't (and can't + /// conceptually) have an (underlying) type. + /// + /// [alias type]: rustc_middle::ty::AliasTy query type_of(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { desc { |tcx| "{action} `{path}`", - action = { - use rustc_hir::def::DefKind; - match tcx.def_kind(key) { - DefKind::TyAlias => "expanding type alias", - DefKind::TraitAlias => "expanding trait alias", - _ => "computing type of", - } + action = match tcx.def_kind(key) { + DefKind::TyAlias => "expanding type alias", + DefKind::TraitAlias => "expanding trait alias", + _ => "computing type of", }, path = tcx.def_path_str(key), } @@ -232,9 +246,14 @@ rustc_queries! { feedable } - /// Specialized instance of `type_of` that detects cycles that are due to - /// revealing opaque because of an auto trait bound. Unless `CyclePlaceholder` needs - /// to be handled separately, call `type_of` instead. + /// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred. + /// + /// This is a specialized instance of [`Self::type_of`] that detects query cycles. + /// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead. + /// + /// # Panics + /// + /// This query will panic if the given definition is not an opaque type. query type_of_opaque(key: DefId) -> Result>, CyclePlaceholder> { desc { |tcx| "computing type of opaque `{path}`", @@ -243,9 +262,22 @@ rustc_queries! { cycle_stash } + /// Returns whether the type alias given by `DefId` is lazy. + /// + /// I.e., if the type alias expands / ought to expand to a [weak] [alias type] + /// instead of the underyling aliased type. + /// + /// Relevant for features `lazy_type_alias` and `type_alias_impl_trait`. + /// + /// # Panics + /// + /// This query *may* panic if the given definition is not a type alias. + /// + /// [weak]: rustc_middle::ty::Weak + /// [alias type]: rustc_middle::ty::AliasTy query type_alias_is_lazy(key: DefId) -> bool { desc { |tcx| - "computing whether `{path}` is a lazy type alias", + "computing whether the type alias `{path}` is lazy", path = tcx.def_path_str(key), } separate_provide_extern @@ -299,8 +331,7 @@ rustc_queries! { desc { "checking lint expectations (RFC 2383)" } } - /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its - /// associated generics. + /// Returns the *generics* of the definition given by `DefId`. query generics_of(key: DefId) -> &'tcx ty::Generics { desc { |tcx| "computing generics of `{}`", tcx.def_path_str(key) } arena_cache @@ -309,10 +340,13 @@ rustc_queries! { feedable } - /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the - /// predicates (where-clauses) that must be proven true in order - /// to reference it. This is almost always the "predicates query" - /// that you want. + /// Returns the (elaborated) *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). + /// + /// This is almost always *the* "predicates query" that you want. + /// + /// **Tip**: You can use `#[rustc_dump_predicates]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -328,25 +362,24 @@ rustc_queries! { } } - /// Returns the list of bounds that are required to be satisfied - /// by a implementation or definition. For associated types, these - /// must be satisfied for an implementation to be well-formed, - /// and for opaque types, these are required to be satisfied by - /// the hidden-type of the opaque. + /// Returns the explicitly user-written *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). /// - /// Syntactially, these are the bounds written on the trait's type - /// definition, or those after the `impl` keyword for an opaque: + /// For associated types, these must be satisfied for an implementation + /// to be well-formed, and for opaque types, these are required to be + /// satisfied by the hidden type of the opaque. /// - /// ```ignore (incomplete) - /// type X: Bound + 'lt - /// // ^^^^^^^^^^^ - /// impl Debug + Display - /// // ^^^^^^^^^^^^^^^ + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// Syntactially, these are the bounds written on associated types in trait + /// definitions, or those after the `impl` keyword for an opaque: + /// + /// ```ignore (illustrative) + /// trait Trait { type X: Bound + 'lt; } + /// // ^^^^^^^^^^^ + /// fn function() -> impl Debug + Display { /*...*/ } + /// // ^^^^^^^^^^^^^^^ /// ``` - /// - /// `key` is the `DefId` of the associated type or opaque type. - /// - /// Bounds from the parent (e.g. with nested impl trait) are not included. query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -354,10 +387,12 @@ rustc_queries! { feedable } - /// The set of item bounds (see [`TyCtxt::explicit_item_bounds`]) that - /// share the `Self` type of the item. These are a subset of the bounds - /// that may explicitly be used for things like closure signature - /// deduction. + /// Returns the explicitly user-written *bounds* that share the `Self` type of the item. + /// + /// These are a subset of the [explicit item bounds] that may explicitly be used for things + /// like closure signature deduction. + /// + /// [explicit item bounds]: Self::explicit_item_bounds query explicit_item_super_predicates(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } @@ -365,26 +400,29 @@ rustc_queries! { feedable } - /// Elaborated version of the predicates from `explicit_item_bounds`. + /// Returns the (elaborated) *bounds* on the associated or opaque type given by `DefId` + /// that must be proven true at definition site (and which can be assumed at usage sites). /// - /// For example: + /// Bounds from the parent (e.g. with nested `impl Trait`) are not included. + /// + /// **Tip**: You can use `#[rustc_dump_item_bounds]` on an item to basically print + /// the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples /// /// ``` - /// trait MyTrait { - /// type MyAType: Eq + ?Sized; - /// } + /// trait Trait { type Assoc: Eq + ?Sized; } /// ``` /// - /// `explicit_item_bounds` returns `[::MyAType: Eq]`, - /// and `item_bounds` returns + /// While [`Self::explicit_item_bounds`] returns `[::Assoc: Eq]` + /// here, `item_bounds` returns: + /// /// ```text /// [ - /// ::MyAType: Eq, - /// ::MyAType: PartialEq<::MyAType> + /// ::Assoc: Eq, + /// ::Assoc: PartialEq<::Assoc> /// ] /// ``` - /// - /// Bounds from the parent (e.g. with nested impl trait) are not included. query item_bounds(key: DefId) -> ty::EarlyBinder<'tcx, ty::Clauses<'tcx>> { desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } } @@ -615,27 +653,35 @@ rustc_queries! { desc { "getting wasm import module map" } } - /// Returns everything that looks like a predicate written explicitly - /// by the user on a trait item. + /// Returns the explicitly user-written *predicates and bounds* of the trait given by `DefId`. /// /// Traits are unusual, because predicates on associated types are /// converted into bounds on that type for backwards compatibility: /// + /// ``` /// trait X where Self::U: Copy { type U; } + /// ``` /// /// becomes /// + /// ``` /// trait X { type U: Copy; } + /// ``` /// - /// `explicit_predicates_of` and `explicit_item_bounds` will then take - /// the appropriate subsets of the predicates here. + /// [`Self::explicit_predicates_of`] and [`Self::explicit_item_bounds`] will + /// then take the appropriate subsets of the predicates here. + /// + /// # Panics + /// + /// This query will panic if the given definition is not a trait. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } - /// Returns the predicates written explicitly by the user. + /// Returns the explicitly user-written *predicates* of the definition given by `DefId` + /// that must be proven true at usage sites (and which can be assumed at definition site). /// - /// You should probably use `predicates_of` unless you're looking for + /// You should probably use [`Self::predicates_of`] unless you're looking for /// predicates with explicit spans for diagnostics purposes. query explicit_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> { desc { |tcx| "computing explicit predicates of `{}`", tcx.def_path_str(key) } @@ -644,18 +690,24 @@ rustc_queries! { feedable } - /// Returns the inferred outlives predicates (e.g., for `struct - /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). + /// Returns the *inferred outlives-predicates* of the item given by `DefId`. + /// + /// E.g., for `struct Foo<'a, T> { x: &'a T }`, this would return `[T: 'a]`. + /// + /// **Tip**: You can use `#[rustc_outlives]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { - desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } + desc { |tcx| "computing inferred outlives-predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern feedable } - /// Maps from the `DefId` of a trait to the list of super-predicates of the trait, - /// *before* elaboration (so it doesn't contain transitive super-predicates). This - /// is a subset of the full list of predicates. We store these in a separate map + /// Returns the explicitly user-written *super-predicates* of the trait given by `DefId`. + /// + /// These predicates are unelaborated and consequently don't contain transitive super-predicates. + /// + /// This is a subset of the full list of predicates. We store these in a separate map /// because we must evaluate them even during type conversion, often before the full /// predicates are available (note that super-predicates must not be cyclic). query explicit_super_predicates_of(key: DefId) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { @@ -664,8 +716,9 @@ rustc_queries! { separate_provide_extern } - /// The predicates of the trait that are implied during elaboration. This is a - /// superset of the super-predicates of the trait, but a subset of the predicates + /// The predicates of the trait that are implied during elaboration. + /// + /// This is a superset of the super-predicates of the trait, but a subset of the predicates /// of the trait. For regular traits, this includes all super-predicates and their /// associated type bounds. For trait aliases, currently, this includes all of the /// predicates of the trait alias. @@ -745,14 +798,27 @@ rustc_queries! { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } - /// Returns the constness of function-like things (tuple struct/variant constructors, functions, - /// methods) + /// Returns the constness of the function-like[^1] definition given by `DefId`. /// - /// Will ICE if used on things that are always const or never const. + /// Tuple struct/variant constructors are *always* const, foreign functions are + /// *never* const. The rest is const iff marked with keyword `const` (or rather + /// its parent in the case of associated functions). /// - /// **Do not call this function manually.** It is only meant to cache the base data for the + ///
+ /// + /// **Do not call this query** directly. It is only meant to cache the base data for the /// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead. - /// Also note that neither of them takes into account feature gates and stability. + /// + /// Also note that neither of them takes into account feature gates, stability and + /// const predicates/conditions! + /// + ///
+ /// + /// # Panics + /// + /// This query will panic if the given definition is not function-like[^1]. + /// + /// [^1]: Tuple struct/variant constructors, closures and free, associated and foreign functions. query constness(key: DefId) -> hir::Constness { desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) } separate_provide_extern @@ -798,13 +864,25 @@ rustc_queries! { separate_provide_extern } - /// Gets a map with the variance of every item; use `variances_of` instead. + /// Gets a map with the variances of every item in the local crate. + /// + ///
+ /// + /// **Do not call this query** directly, use [`Self::variances_of`] instead. + /// + ///
query crate_variances(_: ()) -> &'tcx ty::CrateVariancesMap<'tcx> { arena_cache desc { "computing the variances for items in this crate" } } - /// Maps from the `DefId` of a type or region parameter to its (inferred) variance. + /// Returns the (inferred) variances of the item given by `DefId`. + /// + /// The list of variances corresponds to the list of (early-bound) generic + /// parameters of the item (including its parents). + /// + /// **Tip**: You can use `#[rustc_variance]` on an item to basically print the + /// result of this query for use in UI tests or for debugging purposes. query variances_of(def_id: DefId) -> &'tcx [ty::Variance] { desc { |tcx| "computing the variances of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } @@ -812,10 +890,16 @@ rustc_queries! { cycle_delay_bug } - /// Maps from thee `DefId` of a type to its (inferred) outlives. + /// Gets a map with the inferred outlives-predicates of every item in the local crate. + /// + ///
+ /// + /// **Do not call this query** directly, use [`Self::inferred_outlives_of`] instead. + /// + ///
query inferred_outlives_crate(_: ()) -> &'tcx ty::CratePredicatesMap<'tcx> { arena_cache - desc { "computing the inferred outlives predicates for items in this crate" } + desc { "computing the inferred outlives-predicates for items in this crate" } } /// Maps from an impl/trait or struct/variant `DefId` @@ -1038,20 +1122,35 @@ rustc_queries! { } /// Gets a complete map from all types to their inherent impls. - /// Not meant to be used directly outside of coherence. + /// + ///
+ /// + /// **Not meant to be used** directly outside of coherence. + /// + ///
query crate_inherent_impls(k: ()) -> (&'tcx CrateInherentImpls, Result<(), ErrorGuaranteed>) { desc { "finding all inherent impls defined in crate" } } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// Not meant to be used directly outside of coherence. + /// + ///
+ /// + /// **Not meant to be used** directly outside of coherence. + /// + ///
query crate_inherent_impls_validity_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for inherent impls that should not be defined in crate" } ensure_forwards_result_if_red } /// Checks all types in the crate for overlap in their inherent impls. Reports errors. - /// Not meant to be used directly outside of coherence. + /// + ///
+ /// + /// **Not meant to be used** directly outside of coherence. + /// + ///
query crate_inherent_impls_overlap_check(_: ()) -> Result<(), ErrorGuaranteed> { desc { "check for overlap between inherent impls defined in this crate" } ensure_forwards_result_if_red @@ -1089,8 +1188,12 @@ rustc_queries! { } /// Computes the tag (if any) for a given type and variant. + /// /// `None` means that the variant doesn't need a tag (because it is niched). - /// Will panic for uninhabited variants. + /// + /// # Panics + /// + /// This query will panic for uninhabited variants and if the passed type is not an enum. query tag_for_variant( key: (Ty<'tcx>, abi::VariantIdx) ) -> Option { @@ -1099,7 +1202,12 @@ rustc_queries! { /// Evaluates a constant and returns the computed allocation. /// - /// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead. + ///
+ /// + /// **Do not call this query** directly, use [`Self::eval_to_const_value_raw`] or + /// [`Self::eval_to_valtree`] instead. + /// + ///
query eval_to_allocation_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToAllocationRawResult<'tcx> { desc { |tcx| @@ -1120,12 +1228,18 @@ rustc_queries! { feedable } - /// Evaluates const items or anonymous constants - /// (such as enum variant explicit discriminants or array lengths) - /// into a representation suitable for the type system and const generics. + /// Evaluates const items or anonymous constants[^1] into a representation + /// suitable for the type system and const generics. /// - /// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`, - /// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_global_id`. + ///
+ /// + /// **Do not call this** directly, use one of the following wrappers: + /// [`TyCtxt::const_eval_poly`], [`TyCtxt::const_eval_resolve`], + /// [`TyCtxt::const_eval_instance`], or [`TyCtxt::const_eval_global_id`]. + /// + ///
+ /// + /// [^1]: Such as enum variant explicit discriminants or array lengths. query eval_to_const_value_raw(key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>) -> EvalToConstValueResult<'tcx> { desc { |tcx| @@ -1252,13 +1366,13 @@ rustc_queries! { separate_provide_extern } - /// Determines whether an item is annotated with `doc(hidden)`. + /// Determines whether an item is annotated with `#[doc(hidden)]`. query is_doc_hidden(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } separate_provide_extern } - /// Determines whether an item is annotated with `doc(notable_trait)`. + /// Determines whether an item is annotated with `#[doc(notable_trait)]`. query is_doc_notable_trait(def_id: DefId) -> bool { desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } } @@ -1796,13 +1910,22 @@ rustc_queries! { query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet> { desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) } } - /// For a given item's generic parameter, gets the default lifetimes to be used - /// for each parameter if a trait object were to be passed for that parameter. - /// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`. - /// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`. - /// This query will panic if passed something that is not a type parameter. + /// Returns the *default lifetime* to be used if a trait object type were to be passed for + /// the type parameter given by `DefId`. + /// + /// **Tip**: You can use `#[rustc_object_lifetime_default]` on an item to basically + /// print the result of this query for use in UI tests or for debugging purposes. + /// + /// # Examples + /// + /// - For `T` in `struct Foo<'a, T: 'a>(&'a T);`, this would be `Param('a)` + /// - For `T` in `struct Bar<'a, T>(&'a T);`, this would be `Empty` + /// + /// # Panics + /// + /// This query will panic if the given definition is not a type parameter. query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault { - desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(def_id) } + desc { "looking up lifetime defaults for type parameter `{}`", tcx.def_path_str(def_id) } separate_provide_extern } query late_bound_vars_map(owner_id: hir::OwnerId) diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr index cf5d8f614dda..7f8ed8985252 100644 --- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr @@ -4,12 +4,12 @@ error[E0391]: cycle detected when computing predicates of `Foo` LL | struct Foo { | ^^^^^^^^^^ | -note: ...which requires computing inferred outlives predicates of `Foo`... +note: ...which requires computing inferred outlives-predicates of `Foo`... --> $DIR/cycle-iat-inside-of-adt.rs:7:1 | LL | struct Foo { | ^^^^^^^^^^ - = note: ...which requires computing the inferred outlives predicates for items in this crate... + = note: ...which requires computing the inferred outlives-predicates for items in this crate... note: ...which requires computing type of `Foo::bar`... --> $DIR/cycle-iat-inside-of-adt.rs:8:5 | From 9e57593fdb4159521e7542d768e6956d9cf614c6 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 23 Dec 2024 14:53:09 +0000 Subject: [PATCH 041/113] Add LTO support to clang in CI --- src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile | 1 + src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 6 ++++++ src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh | 1 + src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh | 5 +++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index 414bcc52484c..7e946df61631 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile @@ -50,6 +50,7 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ # Need at least GCC 5.1 to compile LLVM nowadays COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ +ENV GCC_VERSION=9.5.0 RUN ./build-gcc.sh && yum remove -y gcc gcc-c++ COPY scripts/cmake.sh /tmp/ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index e857f38e68a8..81aead701711 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -44,12 +44,14 @@ RUN mkdir -p /rustroot/bin ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig +# Clang needs to access GCC headers to enable linker plugin LTO WORKDIR /tmp RUN mkdir /home/user COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ # Need at least GCC 5.1 to compile LLVM nowadays COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ +ENV GCC_VERSION=9.5.0 RUN ./build-gcc.sh && yum remove -y gcc gcc-c++ # LLVM 17 needs cmake 3.20 or higher. @@ -104,3 +106,7 @@ ENV DIST_SRC 1 ENV LIBCURL_NO_PKG_CONFIG 1 ENV DIST_REQUIRE_ALL_TOOLS 1 + +# FIXME: Without this, LLVMgold.so incorrectly resolves to the system +# libstdc++, instead of the one we build. +ENV LD_PRELOAD=/rustroot/lib64/libstdc++.so.6 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index 2e08c87f278c..3c8123d90de0 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -39,6 +39,7 @@ hide_output \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \ + -DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC_VERSION/plugin/include/" \ -DC_INCLUDE_DIRS="$INC" hide_output make -j$(nproc) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index e939a5d7eac4..57d4d338a506 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -1,10 +1,11 @@ #!/usr/bin/env bash -set -ex +set -eux source shared.sh # Note: in the future when bumping to version 10.1.0, also take care of the sed block below. -GCC=9.5.0 +# This version is specified in the Dockerfile +GCC=$GCC_VERSION curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC From 4fd3baaf70fb5b0fe3afc85588b71cf8bee40e91 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 26 Dec 2024 23:41:46 +0000 Subject: [PATCH 042/113] Add `--no-capture` as a bootstrap argument --- src/bootstrap/src/core/build_steps/test.rs | 4 ++++ src/bootstrap/src/core/builder/tests.rs | 2 ++ src/bootstrap/src/core/config/flags.rs | 10 ++++++++++ src/etc/completions/x.fish | 1 + src/etc/completions/x.ps1 | 1 + src/etc/completions/x.py.fish | 1 + src/etc/completions/x.py.ps1 | 1 + src/etc/completions/x.py.sh | 2 +- src/etc/completions/x.py.zsh | 1 + src/etc/completions/x.sh | 2 +- src/etc/completions/x.zsh | 1 + 11 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 636c88b099b4..47b81d2669d0 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1829,6 +1829,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--force-rerun"); } + if builder.config.cmd.no_capture() { + cmd.arg("--nocapture"); + } + let compare_mode = builder.config.cmd.compare_mode().or_else(|| { if builder.config.test_compare_mode { self.compare_mode } else { None } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 819a552093be..a0acd8393744 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -637,6 +637,7 @@ mod dist { run: None, only_modified: false, extra_checks: None, + no_capture: false, }; let build = Build::new(config); @@ -702,6 +703,7 @@ mod dist { run: None, only_modified: false, extra_checks: None, + no_capture: false, }; // Make sure rustfmt binary not being found isn't an error. config.channel = "beta".to_string(); diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 00bcbe9f86d4..f17103f97dc4 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -388,6 +388,9 @@ pub enum Subcommand { /// enable this to generate a Rustfix coverage file, which is saved in /// `//rustfix_missing_coverage.txt` rustfix_coverage: bool, + #[arg(long)] + /// don't capture stdout/stderr of tests + no_capture: bool, }, /// Build and run some test suites *in Miri* Miri { @@ -563,6 +566,13 @@ impl Subcommand { } } + pub fn no_capture(&self) -> bool { + match *self { + Subcommand::Test { no_capture, .. } => no_capture, + _ => false, + } + } + pub fn rustfix_coverage(&self) -> bool { match *self { Subcommand::Test { rustfix_coverage, .. } => rustfix_coverage, diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index f0927183c071..49fe10a4ea22 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -319,6 +319,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l bless -d 'whether to automa complete -c x -n "__fish_x_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x -n "__fish_x_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x -n "__fish_x_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`' +complete -c x -n "__fish_x_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x -n "__fish_x_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index 7cbf0f0d13ce..fa833b6876ac 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -366,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`') + [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index df31b0d644e7..07144ad22d1a 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -319,6 +319,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l bless -d 'whether to complete -c x.py -n "__fish_x.py_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x.py -n "__fish_x.py_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x.py -n "__fish_x.py_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x.py -n "__fish_x.py_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index afbfb055abdb..7d5bd3c9632b 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -366,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`') + [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index ba7f2c9fb5d6..5c5e4ef0c158 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -3119,7 +3119,7 @@ _x.py() { return 0 ;; x.py__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 415fe09718c2..dd71ec00edfa 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -365,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`//rustfix_missing_coverage.txt\`]' \ +'--no-capture[don'\''t capture stdout/stderr of tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh index a4cf80acc30f..057af1ffc6d5 100644 --- a/src/etc/completions/x.sh +++ b/src/etc/completions/x.sh @@ -3119,7 +3119,7 @@ _x() { return 0 ;; x__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index ee6f504f93e2..6215f9af8330 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -365,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`//rustfix_missing_coverage.txt\`]' \ +'--no-capture[don'\''t capture stdout/stderr of tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ From bccc11e230e247c413ecf0922bde9e3c4b67faeb Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 27 Dec 2024 12:10:55 +0000 Subject: [PATCH 043/113] compiletest: Replace `--nocapture` with `--no-capture` --- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/tools/compiletest/src/lib.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 47b81d2669d0..4efc29737763 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1830,7 +1830,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } if builder.config.cmd.no_capture() { - cmd.arg("--nocapture"); + cmd.arg("--no-capture"); } let compare_mode = diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 250ef0794add..74d1f5637a8f 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -159,7 +159,9 @@ pub fn parse_config(args: Vec) -> Config { ) .optflag("", "force-rerun", "rerun tests even if the inputs are unchanged") .optflag("", "only-modified", "only run tests that result been modified") + // FIXME: Temporarily retained so we can point users to `--no-capture` .optflag("", "nocapture", "") + .optflag("", "no-capture", "don't capture stdout/stderr of tests") .optflag("", "profiler-runtime", "is the profiler runtime enabled for this target") .optflag("h", "help", "show this message") .reqopt("", "channel", "current Rust channel", "CHANNEL") @@ -288,6 +290,10 @@ pub fn parse_config(args: Vec) -> Config { ); }) }); + if matches.opt_present("nocapture") { + panic!("`--nocapture` is deprecated; please use `--no-capture`"); + } + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -385,7 +391,7 @@ pub fn parse_config(args: Vec) -> Config { target_cfgs: OnceLock::new(), builtin_cfg_names: OnceLock::new(), - nocapture: matches.opt_present("nocapture"), + nocapture: matches.opt_present("no-capture"), git_repository: matches.opt_str("git-repository").unwrap(), nightly_branch: matches.opt_str("nightly-branch").unwrap(), From 5bb727a66a293fc77062a118e139affbd137c744 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 26 Dec 2024 23:00:13 +0000 Subject: [PATCH 044/113] compiletest: Remove/don't write empty 'expected' files --- src/tools/compiletest/src/runtest.rs | 99 +++++++++++++------ src/tools/compiletest/src/runtest/coverage.rs | 12 +-- src/tools/compiletest/src/runtest/ui.rs | 7 +- 3 files changed, 81 insertions(+), 37 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 108fde1c8995..7084c407a642 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -213,7 +213,7 @@ fn remove_and_create_dir_all(path: &Path) { fs::create_dir_all(path).unwrap(); } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] struct TestCx<'test> { config: &'test Config, props: &'test TestProps, @@ -2318,32 +2318,47 @@ impl<'test> TestCx<'test> { match output_kind { TestOutput::Compile => { if !self.props.dont_check_compiler_stdout { - errors += self.compare_output( + if self + .compare_output( + stdout_kind, + &normalized_stdout, + &proc_res.stdout, + &expected_stdout, + ) + .should_error() + { + errors += 1; + } + } + if !self.props.dont_check_compiler_stderr { + if self + .compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr) + .should_error() + { + errors += 1; + } + } + } + TestOutput::Run => { + if self + .compare_output( stdout_kind, &normalized_stdout, &proc_res.stdout, &expected_stdout, - ); + ) + .should_error() + { + errors += 1; } - if !self.props.dont_check_compiler_stderr { - errors += self.compare_output( - stderr_kind, - &normalized_stderr, - &stderr, - &expected_stderr, - ); + + if self + .compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr) + .should_error() + { + errors += 1; } } - TestOutput::Run => { - errors += self.compare_output( - stdout_kind, - &normalized_stdout, - &proc_res.stdout, - &expected_stdout, - ); - errors += - self.compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr); - } } errors } @@ -2576,7 +2591,14 @@ impl<'test> TestCx<'test> { actual: &str, actual_unnormalized: &str, expected: &str, - ) -> usize { + ) -> CompareOutcome { + let expected_path = + expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); + + if self.config.bless && actual.is_empty() && expected_path.exists() { + self.delete_file(&expected_path); + } + let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) { // FIXME: We ignore the first line of SVG files // because the width parameter is non-deterministic. @@ -2584,7 +2606,7 @@ impl<'test> TestCx<'test> { _ => expected != actual, }; if !are_different { - return 0; + return CompareOutcome::Same; } // Wrapper tools set by `runner` might provide extra output on failure, @@ -2600,7 +2622,7 @@ impl<'test> TestCx<'test> { used.retain(|line| actual_lines.contains(line)); // check if `expected` contains a subset of the lines of `actual` if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) { - return 0; + return CompareOutcome::Same; } if expected_lines.is_empty() { // if we have no lines to check, force a full overwite @@ -2626,9 +2648,6 @@ impl<'test> TestCx<'test> { } println!("Saved the actual {stream} to {actual_path:?}"); - let expected_path = - expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); - if !self.config.bless { if expected.is_empty() { println!("normalized {}:\n{}\n", stream, actual); @@ -2651,15 +2670,17 @@ impl<'test> TestCx<'test> { self.delete_file(&old); } - if let Err(err) = fs::write(&expected_path, &actual) { - self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); + if !actual.is_empty() { + if let Err(err) = fs::write(&expected_path, &actual) { + self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); + } + println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } - println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } println!("\nThe actual {0} differed from the expected {0}.", stream); - if self.config.bless { 0 } else { 1 } + if self.config.bless { CompareOutcome::Blessed } else { CompareOutcome::Differed } } /// Returns whether to show the full stderr/stdout. @@ -2885,3 +2906,21 @@ enum AuxType { Dylib, ProcMacro, } + +/// Outcome of comparing a stream to a blessed file, +/// e.g. `.stderr` and `.fixed`. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum CompareOutcome { + /// Expected and actual outputs are the same + Same, + /// Outputs differed but were blessed + Blessed, + /// Outputs differed and an error should be emitted + Differed, +} + +impl CompareOutcome { + fn should_error(&self) -> bool { + matches!(self, CompareOutcome::Differed) + } +} diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index 030ca5ebb247..56fc5baf5f24 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -39,16 +39,16 @@ impl<'test> TestCx<'test> { let expected_coverage_dump = self.load_expected_output(kind); let actual_coverage_dump = self.normalize_output(&proc_res.stdout, &[]); - let coverage_dump_errors = self.compare_output( + let coverage_dump_compare_outcome = self.compare_output( kind, &actual_coverage_dump, &proc_res.stdout, &expected_coverage_dump, ); - if coverage_dump_errors > 0 { + if coverage_dump_compare_outcome.should_error() { self.fatal_proc_rec( - &format!("{coverage_dump_errors} errors occurred comparing coverage output."), + &format!("an error occurred comparing coverage output."), &proc_res, ); } @@ -139,16 +139,16 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec(&err, &proc_res); }); - let coverage_errors = self.compare_output( + let coverage_dump_compare_outcome = self.compare_output( kind, &normalized_actual_coverage, &proc_res.stdout, &expected_coverage, ); - if coverage_errors > 0 { + if coverage_dump_compare_outcome.should_error() { self.fatal_proc_rec( - &format!("{} errors occurred comparing coverage output.", coverage_errors), + &format!("an error occurred comparing coverage output."), &proc_res, ); } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index 10528de427d0..0c6d46188e6f 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -100,7 +100,12 @@ impl TestCx<'_> { ) }); - errors += self.compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed); + if self + .compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed) + .should_error() + { + errors += 1; + } } else if !expected_fixed.is_empty() { panic!( "the `//@ run-rustfix` directive wasn't found but a `*.fixed` \ From 35bbb01ea97f8bf0a604fdcfbb5c73c755efb938 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 27 Dec 2024 12:24:03 +0000 Subject: [PATCH 045/113] Add change tracker entry --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index f4f189c718a3..139ea357877b 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -315,4 +315,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`build.vendor` is now enabled by default for dist/tarball sources when 'vendor' directory and '.cargo/config.toml' file are present.", }, + ChangeInfo { + change_id: 134809, + severity: ChangeSeverity::Warning, + summary: "compiletest now takes `--no-capture` instead of `--nocapture`; bootstrap now accepts `--no-capture` as an argument to test commands directly", + }, ]; From e1b65be4177486979bab4a05f520e0c013b831b4 Mon Sep 17 00:00:00 2001 From: chloefeal <188809157+chloefeal@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:35:57 +0800 Subject: [PATCH 046/113] Fix typos Signed-off-by: chloefeal <188809157+chloefeal@users.noreply.github.com> --- compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs | 2 +- compiler/rustc_llvm/build.rs | 2 +- compiler/rustc_mir_build/src/check_tail_calls.rs | 2 +- compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 +- library/alloc/tests/sort/tests.rs | 2 +- library/core/benches/num/int_pow/mod.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs index d77c53a39844..876b8f214b01 100644 --- a/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs +++ b/compiler/rustc_borrowck/src/diagnostics/opaque_suggestions.rs @@ -31,7 +31,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { diag: &mut Diag<'_>, ) { // We look at all the locals. Why locals? Because it's the best thing - // I could think of that's correlated with the *instantiated* higer-ranked + // I could think of that's correlated with the *instantiated* higher-ranked // binder for calls, since we don't really store those anywhere else. for ty in self.body.local_decls.iter().map(|local| local.ty) { if !ty.has_opaque_types() { diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index f092110a324e..d9d28299413b 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -220,7 +220,7 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg(llvm_link_arg).arg("--libs"); - // Don't link system libs if cross-compiling unless targetting Windows. + // Don't link system libs if cross-compiling unless targeting Windows. // On Windows system DLLs aren't linked directly, instead import libraries are used. // These import libraries are independent of the host. if !is_crossed || target.contains("windows") { diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b1f46d37d506..0659e3ea314b 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -117,7 +117,7 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { self.report_arguments_mismatch(expr.span, caller_sig, callee_sig); } - // FIXME(explicit_tail_calls): this currenly fails for cases where opaques are used. + // FIXME(explicit_tail_calls): this currently fails for cases where opaques are used. // e.g. // ``` // fn a() -> impl Sized { become b() } // ICE diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7857ed95cc71..9e7da5eb3689 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1843,7 +1843,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // a global and a non-global where-clause. // // Our handling of where-bounds is generally fairly messy but necessary for backwards - // compatability, see #50825 for why we need to handle global where-bounds like this. + // compatibility, see #50825 for why we need to handle global where-bounds like this. let is_global = |c: ty::PolyTraitPredicate<'tcx>| c.is_global() && !c.has_bound_vars(); let param_candidates = candidates .iter() diff --git a/library/alloc/tests/sort/tests.rs b/library/alloc/tests/sort/tests.rs index 14e6013f965d..206624e59ea5 100644 --- a/library/alloc/tests/sort/tests.rs +++ b/library/alloc/tests/sort/tests.rs @@ -33,7 +33,7 @@ fn check_is_sorted(v: &mut [T]) { known_good_stable_sort::sort(known_good_sorted_vec.as_mut_slice()); if is_small_test { - eprintln!("Orginal: {:?}", v_orig); + eprintln!("Original: {:?}", v_orig); eprintln!("Expected: {:?}", known_good_sorted_vec); eprintln!("Got: {:?}", v); } else { diff --git a/library/core/benches/num/int_pow/mod.rs b/library/core/benches/num/int_pow/mod.rs index 6cf902135828..46f47028d56e 100644 --- a/library/core/benches/num/int_pow/mod.rs +++ b/library/core/benches/num/int_pow/mod.rs @@ -25,7 +25,7 @@ macro_rules! pow_bench_template { let mut exp_iter = black_box(&exp_array).into_iter(); (0..ITERATIONS).fold((0 as IntType, false), |acc, _| { - // Sometimes constants don't propogate all the way to the + // Sometimes constants don't propagate all the way to the // inside of the loop, so we call a custom expression every cycle // rather than iter::repeat(CONST) let base: IntType = $base_macro!(base_iter); From 2c0c9123fc45343eeda185c2b95e48bc4580c8c2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 29 Nov 2024 21:32:03 -0800 Subject: [PATCH 047/113] Move `{widening, carrying}_mul` to an intrinsic with fallback MIR Including implementing it for `u128`, so it can be defined in `uint_impl!`. This way it works for all backends, including CTFE. --- .../rustc_hir_analysis/src/check/intrinsic.rs | 5 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics/fallback.rs | 111 ++++++++++++++ library/core/src/intrinsics/mod.rs | 29 ++++ library/core/src/lib.rs | 1 + library/core/src/num/mod.rs | 135 ------------------ library/core/src/num/uint_macros.rs | 116 +++++++++++++++ library/core/tests/intrinsics.rs | 58 ++++++++ library/core/tests/lib.rs | 1 + 9 files changed, 322 insertions(+), 135 deletions(-) create mode 100644 library/core/src/intrinsics/fallback.rs diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 394794019109..427ef141c72a 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -94,6 +94,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow + | sym::carrying_mul_add | sym::wrapping_add | sym::wrapping_sub | sym::wrapping_mul @@ -436,6 +437,10 @@ pub fn check_intrinsic_type( (1, 0, vec![param(0), param(0)], Ty::new_tup(tcx, &[param(0), tcx.types.bool])) } + sym::carrying_mul_add => { + (2, 0, vec![param(0); 4], Ty::new_tup(tcx, &[param(1), param(0)])) + } + sym::ptr_guaranteed_cmp => ( 1, 0, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3d202f11722e..c8825d031f59 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -555,6 +555,7 @@ symbols! { call_ref_future, caller_location, capture_disjoint_fields, + carrying_mul_add, catch_unwind, cause, cdylib, diff --git a/library/core/src/intrinsics/fallback.rs b/library/core/src/intrinsics/fallback.rs new file mode 100644 index 000000000000..d87331f72620 --- /dev/null +++ b/library/core/src/intrinsics/fallback.rs @@ -0,0 +1,111 @@ +#![unstable( + feature = "core_intrinsics_fallbacks", + reason = "The fallbacks will never be stable, as they exist only to be called \ + by the fallback MIR, but they're exported so they can be tested on \ + platforms where the fallback MIR isn't actually used", + issue = "none" +)] +#![allow(missing_docs)] + +#[const_trait] +pub trait CarryingMulAdd: Copy + 'static { + type Unsigned: Copy + 'static; + fn carrying_mul_add( + self, + multiplicand: Self, + addend: Self, + carry: Self, + ) -> (Self::Unsigned, Self); +} + +macro_rules! impl_carrying_mul_add_by_widening { + ($($t:ident $u:ident $w:ident,)+) => {$( + #[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] + impl const CarryingMulAdd for $t { + type Unsigned = $u; + #[inline] + fn carrying_mul_add(self, a: Self, b: Self, c: Self) -> ($u, $t) { + let wide = (self as $w) * (a as $w) + (b as $w) + (c as $w); + (wide as _, (wide >> Self::BITS) as _) + } + } + )+}; +} +impl_carrying_mul_add_by_widening! { + u8 u8 u16, + u16 u16 u32, + u32 u32 u64, + u64 u64 u128, + usize usize UDoubleSize, + i8 u8 i16, + i16 u16 i32, + i32 u32 i64, + i64 u64 i128, + isize usize UDoubleSize, +} + +#[cfg(target_pointer_width = "16")] +type UDoubleSize = u32; +#[cfg(target_pointer_width = "32")] +type UDoubleSize = u64; +#[cfg(target_pointer_width = "64")] +type UDoubleSize = u128; + +#[inline] +const fn wide_mul_u128(a: u128, b: u128) -> (u128, u128) { + #[inline] + const fn to_low_high(x: u128) -> [u128; 2] { + const MASK: u128 = u64::MAX as _; + [x & MASK, x >> 64] + } + #[inline] + const fn from_low_high(x: [u128; 2]) -> u128 { + x[0] | (x[1] << 64) + } + #[inline] + const fn scalar_mul(low_high: [u128; 2], k: u128) -> [u128; 3] { + let [x, c] = to_low_high(k * low_high[0]); + let [y, z] = to_low_high(k * low_high[1] + c); + [x, y, z] + } + let a = to_low_high(a); + let b = to_low_high(b); + let low = scalar_mul(a, b[0]); + let high = scalar_mul(a, b[1]); + let r0 = low[0]; + let [r1, c] = to_low_high(low[1] + high[0]); + let [r2, c] = to_low_high(low[2] + high[1] + c); + let r3 = high[2] + c; + (from_low_high([r0, r1]), from_low_high([r2, r3])) +} + +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +impl const CarryingMulAdd for u128 { + type Unsigned = u128; + #[inline] + fn carrying_mul_add(self, b: u128, c: u128, d: u128) -> (u128, u128) { + let (low, mut high) = wide_mul_u128(self, b); + let (low, carry) = u128::overflowing_add(low, c); + high += carry as u128; + let (low, carry) = u128::overflowing_add(low, d); + high += carry as u128; + (low, high) + } +} + +#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")] +impl const CarryingMulAdd for i128 { + type Unsigned = u128; + #[inline] + fn carrying_mul_add(self, b: i128, c: i128, d: i128) -> (u128, i128) { + let (low, high) = wide_mul_u128(self as u128, b as u128); + let mut high = high as i128; + high = high.wrapping_add((self >> 127) * b); + high = high.wrapping_add(self * (b >> 127)); + let (low, carry) = u128::overflowing_add(low, c as u128); + high = high.wrapping_add((carry as i128) + (c >> 127)); + let (low, carry) = u128::overflowing_add(low, d as u128); + high = high.wrapping_add((carry as i128) + (d >> 127)); + (low, high) + } +} diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 42b8eb33a1a9..1ee3b83ed22f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -68,6 +68,7 @@ use crate::marker::{DiscriminantKind, Tuple}; use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; +pub mod fallback; pub mod mir; pub mod simd; @@ -3305,6 +3306,34 @@ pub const fn mul_with_overflow(_x: T, _y: T) -> (T, bool) { unimplemented!() } +/// Performs full-width multiplication and addition with a carry: +/// `multiplier * multiplicand + addend + carry`. +/// +/// This is possible without any overflow. For `uN`: +/// MAX * MAX + MAX + MAX +/// => (2ⁿ-1) × (2ⁿ-1) + (2ⁿ-1) + (2ⁿ-1) +/// => (2²ⁿ - 2ⁿ⁺¹ + 1) + (2ⁿ⁺¹ - 2) +/// => 2²ⁿ - 1 +/// +/// For `iN`, the upper bound is MIN * MIN + MAX + MAX => 2²ⁿ⁻² + 2ⁿ - 2, +/// and the lower bound is MAX * MIN + MIN + MIN => -2²ⁿ⁻² - 2ⁿ + 2ⁿ⁺¹. +/// +/// This currently supports unsigned integers *only*, no signed ones. +/// The stabilized versions of this intrinsic are available on integers. +#[unstable(feature = "core_intrinsics", issue = "none")] +#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "85532")] +#[rustc_nounwind] +#[cfg_attr(not(bootstrap), rustc_intrinsic)] +#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +pub const fn carrying_mul_add, U>( + multiplier: T, + multiplicand: T, + addend: T, + carry: T, +) -> (U, T) { + multiplier.carrying_mul_add(multiplicand, addend, carry) +} + /// Performs an exact division, resulting in undefined behavior where /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1` /// diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index a7f741a94089..82d7d045bf57 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -110,6 +110,7 @@ #![cfg_attr(bootstrap, feature(do_not_recommend))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] +#![feature(const_carrying_mul_add)] #![feature(const_eval_select)] #![feature(const_typed_swap)] #![feature(core_intrinsics)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 357a85ae843c..1f5b8ce6c6e2 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -228,134 +228,6 @@ macro_rules! midpoint_impl { }; } -macro_rules! widening_impl { - ($SelfT:ty, $WideT:ty, $BITS:literal, unsigned) => { - /// Calculates the complete product `self * rhs` without the possibility to overflow. - /// - /// This returns the low-order (wrapping) bits and the high-order (overflow) bits - /// of the result as two separate values, in that order. - /// - /// If you also need to add a carry to the wide result, then you want - /// [`Self::carrying_mul`] instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!(5u32.widening_mul(2), (10, 0)); - /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2)); - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn widening_mul(self, rhs: Self) -> (Self, Self) { - // note: longer-term this should be done via an intrinsic, - // but for now we can deal without an impl for u128/i128 - // SAFETY: overflow will be contained within the wider types - let wide = unsafe { (self as $WideT).unchecked_mul(rhs as $WideT) }; - (wide as $SelfT, (wide >> $BITS) as $SelfT) - } - - /// Calculates the "full multiplication" `self * rhs + carry` - /// without the possibility to overflow. - /// - /// This returns the low-order (wrapping) bits and the high-order (overflow) bits - /// of the result as two separate values, in that order. - /// - /// Performs "long multiplication" which takes in an extra amount to add, and may return an - /// additional amount of overflow. This allows for chaining together multiple - /// multiplications to create "big integers" which represent larger values. - /// - /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. - /// - /// # Examples - /// - /// Basic usage: - /// - /// Please note that this example is shared between integer types. - /// Which explains why `u32` is used here. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0)); - /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); - /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); - /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); - #[doc = concat!("assert_eq!(", - stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", - "(0, ", stringify!($SelfT), "::MAX));" - )] - /// ``` - /// - /// This is the core operation needed for scalar multiplication when - /// implementing it for wider-than-native types. - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { - /// let mut carry = 0; - /// for d in little_endian_digits.iter_mut() { - /// (*d, carry) = d.carrying_mul(multiplicand, carry); - /// } - /// if carry != 0 { - /// little_endian_digits.push(carry); - /// } - /// } - /// - /// let mut v = vec![10, 20]; - /// scalar_mul_eq(&mut v, 3); - /// assert_eq!(v, [30, 60]); - /// - /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D); - /// let mut v = vec![0x4321, 0x8765]; - /// scalar_mul_eq(&mut v, 0xFEED); - /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]); - /// ``` - /// - /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), - /// except that it gives the value of the overflow instead of just whether one happened: - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// let r = u8::carrying_mul(7, 13, 0); - /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); - /// let r = u8::carrying_mul(13, 42, 0); - /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42)); - /// ``` - /// - /// The value of the first field in the returned tuple matches what you'd get - /// by combining the [`wrapping_mul`](Self::wrapping_mul) and - /// [`wrapping_add`](Self::wrapping_add) methods: - /// - /// ``` - /// #![feature(bigint_helper_methods)] - /// assert_eq!( - /// 789_u16.carrying_mul(456, 123).0, - /// 789_u16.wrapping_mul(456).wrapping_add(123), - /// ); - /// ``` - #[unstable(feature = "bigint_helper_methods", issue = "85532")] - #[must_use = "this returns the result of the operation, \ - without modifying the original"] - #[inline] - pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) { - // note: longer-term this should be done via an intrinsic, - // but for now we can deal without an impl for u128/i128 - // SAFETY: overflow will be contained within the wider types - let wide = unsafe { - (self as $WideT).unchecked_mul(rhs as $WideT).unchecked_add(carry as $WideT) - }; - (wide as $SelfT, (wide >> $BITS) as $SelfT) - } - }; -} - impl i8 { int_impl! { Self = i8, @@ -576,7 +448,6 @@ impl u8 { from_xe_bytes_doc = u8_xe_bytes_doc!(), bound_condition = "", } - widening_impl! { u8, u16, 8, unsigned } midpoint_impl! { u8, u16, unsigned } /// Checks if the value is within the ASCII range. @@ -1192,7 +1063,6 @@ impl u16 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u16, u32, 16, unsigned } midpoint_impl! { u16, u32, unsigned } /// Checks if the value is a Unicode surrogate code point, which are disallowed values for [`char`]. @@ -1240,7 +1110,6 @@ impl u32 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u32, u64, 32, unsigned } midpoint_impl! { u32, u64, unsigned } } @@ -1264,7 +1133,6 @@ impl u64 { from_xe_bytes_doc = "", bound_condition = "", } - widening_impl! { u64, u128, 64, unsigned } midpoint_impl! { u64, u128, unsigned } } @@ -1314,7 +1182,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 16-bit targets", } - widening_impl! { usize, u32, 16, unsigned } midpoint_impl! { usize, u32, unsigned } } @@ -1339,7 +1206,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 32-bit targets", } - widening_impl! { usize, u64, 32, unsigned } midpoint_impl! { usize, u64, unsigned } } @@ -1364,7 +1230,6 @@ impl usize { from_xe_bytes_doc = usize_isize_from_xe_bytes_doc!(), bound_condition = " on 64-bit targets", } - widening_impl! { usize, u128, 64, unsigned } midpoint_impl! { usize, u128, unsigned } } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 151d879fabee..4a5fdbfb0ea2 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3347,6 +3347,122 @@ macro_rules! uint_impl { unsafe { mem::transmute(bytes) } } + /// Calculates the complete product `self * rhs` without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// If you also need to add a carry to the wide result, then you want + /// [`Self::carrying_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.widening_mul(2), (10, 0)); + /// assert_eq!(1_000_000_000u32.widening_mul(10), (1410065408, 2)); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn widening_mul(self, rhs: Self) -> (Self, Self) { + Self::carrying_mul(self, rhs, 0) + } + + /// Calculates the "full multiplication" `self * rhs + carry` + /// without the possibility to overflow. + /// + /// This returns the low-order (wrapping) bits and the high-order (overflow) bits + /// of the result as two separate values, in that order. + /// + /// Performs "long multiplication" which takes in an extra amount to add, and may return an + /// additional amount of overflow. This allows for chaining together multiple + /// multiplications to create "big integers" which represent larger values. + /// + /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead. + /// + /// # Examples + /// + /// Basic usage: + /// + /// Please note that this example is shared between integer types. + /// Which explains why `u32` is used here. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!(5u32.carrying_mul(2, 0), (10, 0)); + /// assert_eq!(5u32.carrying_mul(2, 10), (20, 0)); + /// assert_eq!(1_000_000_000u32.carrying_mul(10, 0), (1410065408, 2)); + /// assert_eq!(1_000_000_000u32.carrying_mul(10, 10), (1410065418, 2)); + #[doc = concat!("assert_eq!(", + stringify!($SelfT), "::MAX.carrying_mul(", stringify!($SelfT), "::MAX, ", stringify!($SelfT), "::MAX), ", + "(0, ", stringify!($SelfT), "::MAX));" + )] + /// ``` + /// + /// This is the core operation needed for scalar multiplication when + /// implementing it for wider-than-native types. + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { + /// let mut carry = 0; + /// for d in little_endian_digits.iter_mut() { + /// (*d, carry) = d.carrying_mul(multiplicand, carry); + /// } + /// if carry != 0 { + /// little_endian_digits.push(carry); + /// } + /// } + /// + /// let mut v = vec![10, 20]; + /// scalar_mul_eq(&mut v, 3); + /// assert_eq!(v, [30, 60]); + /// + /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D); + /// let mut v = vec![0x4321, 0x8765]; + /// scalar_mul_eq(&mut v, 0xFEED); + /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]); + /// ``` + /// + /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul), + /// except that it gives the value of the overflow instead of just whether one happened: + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// let r = u8::carrying_mul(7, 13, 0); + /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); + /// let r = u8::carrying_mul(13, 42, 0); + /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(13, 42)); + /// ``` + /// + /// The value of the first field in the returned tuple matches what you'd get + /// by combining the [`wrapping_mul`](Self::wrapping_mul) and + /// [`wrapping_add`](Self::wrapping_add) methods: + /// + /// ``` + /// #![feature(bigint_helper_methods)] + /// assert_eq!( + /// 789_u16.carrying_mul(456, 123).0, + /// 789_u16.wrapping_mul(456).wrapping_add(123), + /// ); + /// ``` + #[unstable(feature = "bigint_helper_methods", issue = "85532")] + #[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) { + intrinsics::carrying_mul_add(self, rhs, 0, carry) + } + /// New code should prefer to use #[doc = concat!("[`", stringify!($SelfT), "::MIN", "`] instead.")] /// diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs index 8b731cf5b25d..76f425940912 100644 --- a/library/core/tests/intrinsics.rs +++ b/library/core/tests/intrinsics.rs @@ -125,3 +125,61 @@ fn test_three_way_compare_in_const_contexts() { assert_eq!(SIGNED_EQUAL, Equal); assert_eq!(SIGNED_GREATER, Greater); } + +fn fallback_cma( + a: T, + b: T, + c: T, + d: T, +) -> (T::Unsigned, T) { + a.carrying_mul_add(b, c, d) +} + +#[test] +fn carrying_mul_add_fallback_u32() { + let r = fallback_cma::(0x9e37_79b9, 0x7f4a_7c15, 0xf39c_c060, 0x5ced_c834); + assert_eq!(r, (0x2087_20c1, 0x4eab_8e1d)); + let r = fallback_cma::(0x1082_276b, 0xf3a2_7251, 0xf86c_6a11, 0xd0c1_8e95); + assert_eq!(r, (0x7aa0_1781, 0x0fb6_0528)); +} + +#[test] +fn carrying_mul_add_fallback_i32() { + let r = fallback_cma::(-1, -1, -1, -1); + assert_eq!(r, (u32::MAX, -1)); + let r = fallback_cma::(1, -1, 1, 1); + assert_eq!(r, (1, 0)); +} + +#[test] +fn carrying_mul_add_fallback_u128() { + assert_eq!(fallback_cma::(1, 1, 1, 1), (3, 0)); + assert_eq!(fallback_cma::(0, 0, u128::MAX, u128::MAX), (u128::MAX - 1, 1)); + assert_eq!( + fallback_cma::(u128::MAX, u128::MAX, u128::MAX, u128::MAX), + (u128::MAX, u128::MAX), + ); + + let r = fallback_cma::( + 0x243f6a8885a308d313198a2e03707344, + 0xa4093822299f31d0082efa98ec4e6c89, + 0x452821e638d01377be5466cf34e90c6c, + 0xc0ac29b7c97c50dd3f84d5b5b5470917, + ); + assert_eq!(r, (0x8050ec20ed554e40338d277e00b674e7, 0x1739ee6cea07da409182d003859b59d8)); + let r = fallback_cma::( + 0x9216d5d98979fb1bd1310ba698dfb5ac, + 0x2ffd72dbd01adfb7b8e1afed6a267e96, + 0xba7c9045f12c7f9924a19947b3916cf7, + 0x0801f2e2858efc16636920d871574e69, + ); + assert_eq!(r, (0x185525545fdb2fefb502a3a602efd628, 0x1b62d35fe3bff6b566f99667ef7ebfd6)); +} + +#[test] +fn carrying_mul_add_fallback_i128() { + let r = fallback_cma::(-1, -1, -1, -1); + assert_eq!(r, (u128::MAX, -1)); + let r = fallback_cma::(1, -1, 1, 1); + assert_eq!(r, (1, 0)); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 9f0ab7b3f297..8716c0949283 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -19,6 +19,7 @@ #![feature(const_swap_nonoverlapping)] #![feature(const_trait_impl)] #![feature(core_intrinsics)] +#![feature(core_intrinsics_fallbacks)] #![feature(core_io_borrowed_buf)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] From 4669c0d756ddfbd3df0ee1d5c7a4b1cdaabf5945 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 29 Nov 2024 22:51:46 -0800 Subject: [PATCH 048/113] Override `carrying_mul_add` in cg_llvm --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 31 +++++ compiler/rustc_codegen_llvm/src/lib.rs | 1 + library/core/src/intrinsics/fallback.rs | 4 +- library/core/tests/intrinsics.rs | 10 ++ tests/codegen/intrinsics/carrying_mul_add.rs | 137 +++++++++++++++++++ 5 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 tests/codegen/intrinsics/carrying_mul_add.rs diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index c38c5d4c6442..cabcfc9b42b4 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -340,6 +340,37 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { self.const_i32(cache_type), ]) } + sym::carrying_mul_add => { + let (size, signed) = fn_args.type_at(0).int_size_and_signed(self.tcx); + + let wide_llty = self.type_ix(size.bits() * 2); + let args = args.as_array().unwrap(); + let [a, b, c, d] = args.map(|a| self.intcast(a.immediate(), wide_llty, signed)); + + let wide = if signed { + let prod = self.unchecked_smul(a, b); + let acc = self.unchecked_sadd(prod, c); + self.unchecked_sadd(acc, d) + } else { + let prod = self.unchecked_umul(a, b); + let acc = self.unchecked_uadd(prod, c); + self.unchecked_uadd(acc, d) + }; + + let narrow_llty = self.type_ix(size.bits()); + let low = self.trunc(wide, narrow_llty); + let bits_const = self.const_uint(wide_llty, size.bits()); + // No need for ashr when signed; LLVM changes it to lshr anyway. + let high = self.lshr(wide, bits_const); + // FIXME: could be `trunc nuw`, even for signed. + let high = self.trunc(high, narrow_llty); + + let pair_llty = self.type_struct(&[narrow_llty, narrow_llty], false); + let pair = self.const_poison(pair_llty); + let pair = self.insert_value(pair, low, 0); + let pair = self.insert_value(pair, high, 1); + pair + } sym::ctlz | sym::ctlz_nonzero | sym::cttz diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0de0c6a7a89e..dca7738daf77 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -17,6 +17,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(rustdoc_internals)] +#![feature(slice_as_array)] #![feature(try_blocks)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/library/core/src/intrinsics/fallback.rs b/library/core/src/intrinsics/fallback.rs index d87331f72620..1779126b180e 100644 --- a/library/core/src/intrinsics/fallback.rs +++ b/library/core/src/intrinsics/fallback.rs @@ -100,8 +100,8 @@ impl const CarryingMulAdd for i128 { fn carrying_mul_add(self, b: i128, c: i128, d: i128) -> (u128, i128) { let (low, high) = wide_mul_u128(self as u128, b as u128); let mut high = high as i128; - high = high.wrapping_add((self >> 127) * b); - high = high.wrapping_add(self * (b >> 127)); + high = high.wrapping_add(i128::wrapping_mul(self >> 127, b)); + high = high.wrapping_add(i128::wrapping_mul(self, b >> 127)); let (low, carry) = u128::overflowing_add(low, c as u128); high = high.wrapping_add((carry as i128) + (c >> 127)); let (low, carry) = u128::overflowing_add(low, d as u128); diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs index 76f425940912..744a6a0d2dd8 100644 --- a/library/core/tests/intrinsics.rs +++ b/library/core/tests/intrinsics.rs @@ -153,6 +153,7 @@ fn carrying_mul_add_fallback_i32() { #[test] fn carrying_mul_add_fallback_u128() { + assert_eq!(fallback_cma::(u128::MAX, u128::MAX, 0, 0), (1, u128::MAX - 1)); assert_eq!(fallback_cma::(1, 1, 1, 1), (3, 0)); assert_eq!(fallback_cma::(0, 0, u128::MAX, u128::MAX), (u128::MAX - 1, 1)); assert_eq!( @@ -178,8 +179,17 @@ fn carrying_mul_add_fallback_u128() { #[test] fn carrying_mul_add_fallback_i128() { + assert_eq!(fallback_cma::(-1, -1, 0, 0), (1, 0)); let r = fallback_cma::(-1, -1, -1, -1); assert_eq!(r, (u128::MAX, -1)); let r = fallback_cma::(1, -1, 1, 1); assert_eq!(r, (1, 0)); + assert_eq!( + fallback_cma::(i128::MAX, i128::MAX, i128::MAX, i128::MAX), + (u128::MAX, i128::MAX / 2), + ); + assert_eq!( + fallback_cma::(i128::MIN, i128::MIN, i128::MAX, i128::MAX), + (u128::MAX - 1, -(i128::MIN / 2)), + ); } diff --git a/tests/codegen/intrinsics/carrying_mul_add.rs b/tests/codegen/intrinsics/carrying_mul_add.rs new file mode 100644 index 000000000000..174c4077f09e --- /dev/null +++ b/tests/codegen/intrinsics/carrying_mul_add.rs @@ -0,0 +1,137 @@ +//@ revisions: RAW OPT +//@ compile-flags: -C opt-level=1 +//@[RAW] compile-flags: -C no-prepopulate-passes +//@[OPT] min-llvm-version: 19 + +#![crate_type = "lib"] +#![feature(core_intrinsics)] +#![feature(core_intrinsics_fallbacks)] + +// Note that LLVM seems to sometimes permute the order of arguments to mul and add, +// so these tests don't check the arguments in the optimized revision. + +use std::intrinsics::{carrying_mul_add, fallback}; + +// The fallbacks are emitted even when they're never used, but optimize out. + +// RAW: wide_mul_u128 +// OPT-NOT: wide_mul_u128 + +// CHECK-LABEL: @cma_u8 +#[no_mangle] +pub unsafe fn cma_u8(a: u8, b: u8, c: u8, d: u8) -> (u8, u8) { + // CHECK: [[A:%.+]] = zext i8 %a to i16 + // CHECK: [[B:%.+]] = zext i8 %b to i16 + // CHECK: [[C:%.+]] = zext i8 %c to i16 + // CHECK: [[D:%.+]] = zext i8 %d to i16 + // CHECK: [[AB:%.+]] = mul nuw i16 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nuw i16 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nuw i16 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i16 [[ABCD]] to i8 + // CHECK: [[HIGHW:%.+]] = lshr i16 [[ABCD]], 8 + // RAW: [[HIGH:%.+]] = trunc i16 [[HIGHW]] to i8 + // OPT: [[HIGH:%.+]] = trunc nuw i16 [[HIGHW]] to i8 + // CHECK: [[PAIR0:%.+]] = insertvalue { i8, i8 } poison, i8 [[LOW]], 0 + // CHECK: [[PAIR1:%.+]] = insertvalue { i8, i8 } [[PAIR0]], i8 [[HIGH]], 1 + // OPT: ret { i8, i8 } [[PAIR1]] + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @cma_u32 +#[no_mangle] +pub unsafe fn cma_u32(a: u32, b: u32, c: u32, d: u32) -> (u32, u32) { + // CHECK: [[A:%.+]] = zext i32 %a to i64 + // CHECK: [[B:%.+]] = zext i32 %b to i64 + // CHECK: [[C:%.+]] = zext i32 %c to i64 + // CHECK: [[D:%.+]] = zext i32 %d to i64 + // CHECK: [[AB:%.+]] = mul nuw i64 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nuw i64 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nuw i64 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i64 [[ABCD]] to i32 + // CHECK: [[HIGHW:%.+]] = lshr i64 [[ABCD]], 32 + // RAW: [[HIGH:%.+]] = trunc i64 [[HIGHW]] to i32 + // OPT: [[HIGH:%.+]] = trunc nuw i64 [[HIGHW]] to i32 + // CHECK: [[PAIR0:%.+]] = insertvalue { i32, i32 } poison, i32 [[LOW]], 0 + // CHECK: [[PAIR1:%.+]] = insertvalue { i32, i32 } [[PAIR0]], i32 [[HIGH]], 1 + // OPT: ret { i32, i32 } [[PAIR1]] + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @cma_u128 +// CHECK-SAME: sret{{.+}}dereferenceable(32){{.+}}%_0,{{.+}}%a,{{.+}}%b,{{.+}}%c,{{.+}}%d +#[no_mangle] +pub unsafe fn cma_u128(a: u128, b: u128, c: u128, d: u128) -> (u128, u128) { + // CHECK: [[A:%.+]] = zext i128 %a to i256 + // CHECK: [[B:%.+]] = zext i128 %b to i256 + // CHECK: [[C:%.+]] = zext i128 %c to i256 + // CHECK: [[D:%.+]] = zext i128 %d to i256 + // CHECK: [[AB:%.+]] = mul nuw i256 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nuw i256 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nuw i256 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i256 [[ABCD]] to i128 + // CHECK: [[HIGHW:%.+]] = lshr i256 [[ABCD]], 128 + // RAW: [[HIGH:%.+]] = trunc i256 [[HIGHW]] to i128 + // OPT: [[HIGH:%.+]] = trunc nuw i256 [[HIGHW]] to i128 + // RAW: [[PAIR0:%.+]] = insertvalue { i128, i128 } poison, i128 [[LOW]], 0 + // RAW: [[PAIR1:%.+]] = insertvalue { i128, i128 } [[PAIR0]], i128 [[HIGH]], 1 + // OPT: store i128 [[LOW]], ptr %_0 + // OPT: [[P1:%.+]] = getelementptr inbounds i8, ptr %_0, {{i32|i64}} 16 + // OPT: store i128 [[HIGH]], ptr [[P1]] + // CHECK: ret void + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @cma_i128 +// CHECK-SAME: sret{{.+}}dereferenceable(32){{.+}}%_0,{{.+}}%a,{{.+}}%b,{{.+}}%c,{{.+}}%d +#[no_mangle] +pub unsafe fn cma_i128(a: i128, b: i128, c: i128, d: i128) -> (u128, i128) { + // CHECK: [[A:%.+]] = sext i128 %a to i256 + // CHECK: [[B:%.+]] = sext i128 %b to i256 + // CHECK: [[C:%.+]] = sext i128 %c to i256 + // CHECK: [[D:%.+]] = sext i128 %d to i256 + // CHECK: [[AB:%.+]] = mul nsw i256 + // RAW-SAME: [[A]], [[B]] + // CHECK: [[ABC:%.+]] = add nsw i256 + // RAW-SAME: [[AB]], [[C]] + // CHECK: [[ABCD:%.+]] = add nsw i256 + // RAW-SAME: [[ABC]], [[D]] + // CHECK: [[LOW:%.+]] = trunc i256 [[ABCD]] to i128 + // CHECK: [[HIGHW:%.+]] = lshr i256 [[ABCD]], 128 + // RAW: [[HIGH:%.+]] = trunc i256 [[HIGHW]] to i128 + // OPT: [[HIGH:%.+]] = trunc nuw i256 [[HIGHW]] to i128 + // RAW: [[PAIR0:%.+]] = insertvalue { i128, i128 } poison, i128 [[LOW]], 0 + // RAW: [[PAIR1:%.+]] = insertvalue { i128, i128 } [[PAIR0]], i128 [[HIGH]], 1 + // OPT: store i128 [[LOW]], ptr %_0 + // OPT: [[P1:%.+]] = getelementptr inbounds i8, ptr %_0, {{i32|i64}} 16 + // OPT: store i128 [[HIGH]], ptr [[P1]] + // CHECK: ret void + carrying_mul_add(a, b, c, d) +} + +// CHECK-LABEL: @fallback_cma_u32 +#[no_mangle] +pub unsafe fn fallback_cma_u32(a: u32, b: u32, c: u32, d: u32) -> (u32, u32) { + // OPT-DAG: [[A:%.+]] = zext i32 %a to i64 + // OPT-DAG: [[B:%.+]] = zext i32 %b to i64 + // OPT-DAG: [[AB:%.+]] = mul nuw i64 + // OPT-DAG: [[C:%.+]] = zext i32 %c to i64 + // OPT-DAG: [[ABC:%.+]] = add nuw i64{{.+}}[[C]] + // OPT-DAG: [[D:%.+]] = zext i32 %d to i64 + // OPT-DAG: [[ABCD:%.+]] = add nuw i64{{.+}}[[D]] + // OPT-DAG: [[LOW:%.+]] = trunc i64 [[ABCD]] to i32 + // OPT-DAG: [[HIGHW:%.+]] = lshr i64 [[ABCD]], 32 + // OPT-DAG: [[HIGH:%.+]] = trunc nuw i64 [[HIGHW]] to i32 + // OPT-DAG: [[PAIR0:%.+]] = insertvalue { i32, i32 } poison, i32 [[LOW]], 0 + // OPT-DAG: [[PAIR1:%.+]] = insertvalue { i32, i32 } [[PAIR0]], i32 [[HIGH]], 1 + // OPT-DAG: ret { i32, i32 } [[PAIR1]] + fallback::CarryingMulAdd::carrying_mul_add(a, b, c, d) +} From 6039eab641b842e4aa05367e1f3bc378b1fe0879 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 27 Dec 2024 14:43:24 -0300 Subject: [PATCH 049/113] Add spastorino to users_on_vacation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index da652ef70420..3b441db73552 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -997,6 +997,7 @@ users_on_vacation = [ "jyn514", "celinval", "nnethercote", + "spastorino", "workingjubilee", ] From 85aad52ce8b2de4d6b7119812d1daa8717f4b23d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 27 Dec 2024 17:58:16 +0000 Subject: [PATCH 050/113] Make sure there are no registered constraints from creating universal region vids --- compiler/rustc_borrowck/src/type_check/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c29f3033dd06..f918f005a9b5 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -140,6 +140,12 @@ pub(crate) fn type_check<'a, 'tcx>( &mut constraints, ); + let pre_obligations = infcx.take_registered_region_obligations(); + assert!( + pre_obligations.is_empty(), + "there should be no incoming region obligations = {pre_obligations:#?}", + ); + debug!(?normalized_inputs_and_output); let mut typeck = TypeChecker { From df189f6b36e362d15a6fb5e1d1957ee8954bfd61 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 27 Dec 2024 18:23:49 +0000 Subject: [PATCH 051/113] Add clubby789 to bootstrap review rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index da652ef70420..d531d888f99e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1046,6 +1046,7 @@ bootstrap = [ "@onur-ozkan", "@kobzol", "@jieyouxu", + "@clubby789", ] infra-ci = [ "@Mark-Simulacrum", From fef8ec5ad9ccd3249d616520e22e43602fa47883 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 13:41:46 -0800 Subject: [PATCH 052/113] Add test of dot after eager statement boundary expr --- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 94c7964392d1..8cef9fa13f90 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -108,6 +108,10 @@ static EXPRS: &[&str] = &[ "{ (match 2 {})() - 1 }", "{ (match 2 {})[0] - 1 }", "{ (loop {}) - 1 }", + "match 2 { _ => (loop {}) - 1 }", + // No eager statement boundary if followed by `.` or `?`. + "{ (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. + "match 2 { _ => (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. // Angle bracket is eagerly parsed as a path's generic argument list. "(2 as T) < U", "(2 as T) < V", // FIXME: no parentheses needed. From e67fe3698bfd0f3957abb84c2b396c50822a5b67 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 13:42:25 -0800 Subject: [PATCH 053/113] Skip parenthesis if `.` makes statement boundary unambiguous --- .../rustc_ast_pretty/src/pprust/state/expr.rs | 28 +++++++++++-------- .../src/pprust/state/fixup.rs | 14 ++++++++++ .../pprust-parenthesis-insertion.rs | 4 +-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index dce76fb1e770..ab1dd46fe338 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -245,19 +245,21 @@ impl<'a> State<'a> { base_args: &[P], fixup: FixupContext, ) { - // Unlike in `print_expr_call`, no change to fixup here because + // The fixup here is different than in `print_expr_call` because // statement boundaries never occur in front of a `.` (or `?`) token. // - // match () { _ => f }.method(); + // Needs parens: + // + // (loop { break x; })(); + // + // Does not need parens: + // + // loop { break x; }.method(); // - // Parenthesizing only for precedence and not with regard to statement - // boundaries, `$receiver.method()` can be parsed back as a statement - // containing an expression if and only if `$receiver` can be parsed as - // a statement containing an expression. self.print_expr_cond_paren( receiver, receiver.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word("."); @@ -503,7 +505,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word_nbsp(".match"); } @@ -567,7 +569,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word(".await"); } @@ -606,7 +608,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren( expr, expr.precedence() < ExprPrecedence::Unambiguous, - fixup, + fixup.leftmost_subexpression_with_dot(), ); self.word("."); self.print_ident(*ident); @@ -763,7 +765,11 @@ impl<'a> State<'a> { } } ast::ExprKind::Try(e) => { - self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup); + self.print_expr_cond_paren( + e, + e.precedence() < ExprPrecedence::Unambiguous, + fixup.leftmost_subexpression_with_dot(), + ); self.word("?") } ast::ExprKind::TryBlock(blk) => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index ff466703f737..3ef21f5cb29e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -138,6 +138,20 @@ impl FixupContext { } } + /// Transform this fixup into the one that should apply when printing a + /// leftmost subexpression followed by a `.` or `?` token, which confer + /// different statement boundary rules compared to other leftmost + /// subexpressions. + pub(crate) fn leftmost_subexpression_with_dot(self) -> Self { + FixupContext { + stmt: self.stmt || self.leftmost_subexpression_in_stmt, + leftmost_subexpression_in_stmt: false, + match_arm: self.match_arm || self.leftmost_subexpression_in_match_arm, + leftmost_subexpression_in_match_arm: false, + ..self + } + } + /// Transform this fixup into the one that should apply when printing any /// subexpression that is neither a leftmost subexpression nor surrounded in /// delimiters. diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 8cef9fa13f90..dc45731dce76 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -110,8 +110,8 @@ static EXPRS: &[&str] = &[ "{ (loop {}) - 1 }", "match 2 { _ => (loop {}) - 1 }", // No eager statement boundary if followed by `.` or `?`. - "{ (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. - "match 2 { _ => (loop {}).to_string() - 1 }", // FIXME: no parenthesis needed. + "{ loop {}.to_string() - 1 }", + "match 2 { _ => loop {}.to_string() - 1 }", // Angle bracket is eagerly parsed as a path's generic argument list. "(2 as T) < U", "(2 as T) < V", // FIXME: no parentheses needed. From c95f9f50de555454cbd931c026814e46793a820a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 14:18:39 -0800 Subject: [PATCH 054/113] Add pretty-printer test of tuple field function call --- tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 94c7964392d1..fa9b0300743f 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -77,6 +77,9 @@ static EXPRS: &[&str] = &[ // These mean different things. "if let _ = true && false {}", "if let _ = (true && false) {}", + // Parentheses to call a named field, but not an unnamed field. + "(self.fun)()", + "(self.0)()", // FIXME: no parenthesis needed. // Conditions end at the first curly brace, so struct expressions need to be // parenthesized. Except in a match guard, where conditions end at arrow. "if let _ = (Struct {}) {}", From 68bd853bb6b391135565e42577baa2be09dee762 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 27 Dec 2024 21:57:09 +0000 Subject: [PATCH 055/113] Update `compiler-builtins` to 0.1.140 Nothing significant here, just syncing the following small changes: - https://github.com/rust-lang/compiler-builtins/pull/727 - https://github.com/rust-lang/compiler-builtins/pull/730 - https://github.com/rust-lang/compiler-builtins/pull/736 - https://github.com/rust-lang/compiler-builtins/pull/737 --- ...029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch | 4 ++-- library/Cargo.lock | 4 ++-- library/alloc/Cargo.toml | 2 +- library/std/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index 6012af6a8dd2..bf07e455a75f 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core" } --compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/Cargo.lock b/library/Cargo.lock index 15ca4cbff7b7..40edd2c211cd 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.138" +version = "0.1.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f0ea7fff95b51f84371588f06062557e96bbe363d2b36218ddb806f3ca8611" +checksum = "df14d41c5d172a886df3753d54238eefb0f61c96cbd8b363c33ccc92c457bee3" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 3464047d4ee9..07596fa16f98 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] core = { path = "../core" } -compiler_builtins = { version = "=0.1.138", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.140", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f43dcc1630c6..6380c941e6ab 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.138" } +compiler_builtins = { version = "=0.1.140" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', From 26bb4e64645d3f3e0ed0b2921738e56888f96fd1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 27 Dec 2024 14:25:08 -0800 Subject: [PATCH 056/113] Skip parenthesis around tuple struct field calls --- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 4 +++- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_span/src/symbol.rs | 6 ++++++ tests/ui-fulldeps/pprust-parenthesis-insertion.rs | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index dce76fb1e770..f7d8edc4743a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -213,7 +213,9 @@ impl<'a> State<'a> { fn print_expr_call(&mut self, func: &ast::Expr, args: &[P], fixup: FixupContext) { let needs_paren = match func.kind { - ast::ExprKind::Field(..) => true, + // In order to call a named field, needs parens: `(self.fun)()` + // But not for an unnamed field: `self.0()` + ast::ExprKind::Field(_, name) => !name.is_numeric(), _ => func.precedence() < ExprPrecedence::Unambiguous, }; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index aab4e1b1afc1..7df7e7329252 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1336,7 +1336,7 @@ impl<'a> Parser<'a> { ) -> bool { if let ExprKind::Binary(op, l1, r1) = &inner_op.kind { if let ExprKind::Field(_, ident) = l1.kind - && ident.as_str().parse::().is_err() + && !ident.is_numeric() && !matches!(r1.kind, ExprKind::Lit(_)) { // The parser has encountered `foo.bar bool { self.name.can_be_raw() && self.is_reserved() } + + /// Whether this would be the identifier for a tuple field like `self.0`, as + /// opposed to a named field like `self.thing`. + pub fn is_numeric(self) -> bool { + !self.name.is_empty() && self.as_str().bytes().all(|b| b.is_ascii_digit()) + } } /// Collect all the keywords in a given edition into a vector. diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index fa9b0300743f..2697c5f66ce7 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -79,7 +79,7 @@ static EXPRS: &[&str] = &[ "if let _ = (true && false) {}", // Parentheses to call a named field, but not an unnamed field. "(self.fun)()", - "(self.0)()", // FIXME: no parenthesis needed. + "self.0()", // Conditions end at the first curly brace, so struct expressions need to be // parenthesized. Except in a match guard, where conditions end at arrow. "if let _ = (Struct {}) {}", From bc054245283069d3b273f22773a3c3425aff07bd Mon Sep 17 00:00:00 2001 From: chloefeal <188809157+chloefeal@users.noreply.github.com> Date: Sat, 28 Dec 2024 10:37:02 +0800 Subject: [PATCH 057/113] Update library/alloc/tests/sort/tests.rs Co-authored-by: David Tolnay --- library/alloc/tests/sort/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/tests/sort/tests.rs b/library/alloc/tests/sort/tests.rs index 206624e59ea5..4cc79010e8fe 100644 --- a/library/alloc/tests/sort/tests.rs +++ b/library/alloc/tests/sort/tests.rs @@ -33,7 +33,7 @@ fn check_is_sorted(v: &mut [T]) { known_good_stable_sort::sort(known_good_sorted_vec.as_mut_slice()); if is_small_test { - eprintln!("Original: {:?}", v_orig); + eprintln!("Original: {:?}", v_orig); eprintln!("Expected: {:?}", known_good_sorted_vec); eprintln!("Got: {:?}", v); } else { From ef19017f7ca29450efff332db297851933f21844 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 28 Dec 2024 13:12:36 +1100 Subject: [PATCH 058/113] compiletest: Self-test for `normalize-*` with revisions --- .../normalize-with-revision.a.run.stderr | 2 ++ .../normalize-with-revision.b.run.stderr | 2 ++ .../normalize-with-revision.rs | 20 +++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr create mode 100644 tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr create mode 100644 tests/ui/compiletest-self-test/normalize-with-revision.rs diff --git a/tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr b/tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr new file mode 100644 index 000000000000..3eb3f6b4e571 --- /dev/null +++ b/tests/ui/compiletest-self-test/normalize-with-revision.a.run.stderr @@ -0,0 +1,2 @@ +1st emitted line +second emitted line diff --git a/tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr b/tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr new file mode 100644 index 000000000000..8d9156480abf --- /dev/null +++ b/tests/ui/compiletest-self-test/normalize-with-revision.b.run.stderr @@ -0,0 +1,2 @@ +first emitted line +2nd emitted line diff --git a/tests/ui/compiletest-self-test/normalize-with-revision.rs b/tests/ui/compiletest-self-test/normalize-with-revision.rs new file mode 100644 index 000000000000..e1bbbb3eabb7 --- /dev/null +++ b/tests/ui/compiletest-self-test/normalize-with-revision.rs @@ -0,0 +1,20 @@ +//! Checks that `[rev] normalize-*` directives affect the specified revision, +//! and don't affect other revisions. +//! +//! This currently relies on the fact that `normalize-*` directives are +//! applied to run output, not just compiler output. If that ever changes, +//! this test might need to be adjusted. + +//@ edition: 2021 +//@ revisions: a b +//@ run-pass +//@ check-run-results + +//@ normalize-stderr: "output" -> "emitted" +//@[a] normalize-stderr: "first" -> "1st" +//@[b] normalize-stderr: "second" -> "2nd" + +fn main() { + eprintln!("first output line"); + eprintln!("second output line"); +} From 3a4e82195e08a77d542078cadcc881105e9d0838 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 28 Dec 2024 13:21:21 +1100 Subject: [PATCH 059/113] compiletest: Only pass the post-colon value to `parse_normalize_rule` --- src/tools/compiletest/src/header.rs | 18 ++++++++-------- src/tools/compiletest/src/header/tests.rs | 25 +++++++++++++---------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 67ecdaf9e5e1..73d00fbf7b85 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -978,10 +978,10 @@ impl Config { } } - fn parse_custom_normalization(&self, line: &str) -> Option { + fn parse_custom_normalization(&self, raw_directive: &str) -> Option { // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine` // instead of doing it here. - let (directive_name, _value) = line.split_once(':')?; + let (directive_name, raw_value) = raw_directive.split_once(':')?; let kind = match directive_name { "normalize-stdout" => NormalizeKind::Stdout, @@ -991,11 +991,9 @@ impl Config { _ => return None, }; - // FIXME(Zalathar): The normalize rule parser should only care about - // the value part, not the "line" (which isn't even the whole line). - let Some((regex, replacement)) = parse_normalize_rule(line) else { + let Some((regex, replacement)) = parse_normalize_rule(raw_value) else { panic!( - "couldn't parse custom normalization rule: `{line}`\n\ + "couldn't parse custom normalization rule: `{raw_directive}`\n\ help: expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`" ); }; @@ -1141,21 +1139,21 @@ enum NormalizeKind { /// Parses the regex and replacement values of a `//@ normalize-*` header, /// in the format: /// ```text -/// normalize-*: "REGEX" -> "REPLACEMENT" +/// "REGEX" -> "REPLACEMENT" /// ``` -fn parse_normalize_rule(header: &str) -> Option<(String, String)> { +fn parse_normalize_rule(raw_value: &str) -> Option<(String, String)> { // FIXME: Support escaped double-quotes in strings. let captures = static_regex!( r#"(?x) # (verbose mode regex) ^ - [^:\s]+:\s* # (header name followed by colon) + \s* # (leading whitespace) "(?[^"]*)" # "REGEX" \s+->\s+ # -> "(?[^"]*)" # "REPLACEMENT" $ "# ) - .captures(header)?; + .captures(raw_value)?; let regex = captures["regex"].to_owned(); let replacement = captures["replacement"].to_owned(); // FIXME: Support escaped new-line in strings. diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index cd7c6f8361ed..618b66dfd4cb 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -35,11 +35,14 @@ fn make_test_description( #[test] fn test_parse_normalize_rule() { - let good_data = &[( - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)""#, - "something (32 bits)", - "something ($WORD bits)", - )]; + let good_data = &[ + ( + r#""something (32 bits)" -> "something ($WORD bits)""#, + "something (32 bits)", + "something ($WORD bits)", + ), + (r#" " with whitespace" -> " replacement""#, " with whitespace", " replacement"), + ]; for &(input, expected_regex, expected_replacement) in good_data { let parsed = parse_normalize_rule(input); @@ -49,15 +52,15 @@ fn test_parse_normalize_rule() { } let bad_data = &[ - r#"normalize-stderr-32bit "something (32 bits)" -> "something ($WORD bits)""#, - r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)"."#, + r#"something (11 bits) -> something ($WORD bits)"#, + r#"something (12 bits) -> something ($WORD bits)"#, + r#""something (13 bits) -> something ($WORD bits)"#, + r#""something (14 bits)" -> "something ($WORD bits)"#, + r#""something (15 bits)" -> "something ($WORD bits)"."#, ]; for &input in bad_data { + println!("- {input:?}"); let parsed = parse_normalize_rule(input); assert_eq!(parsed, None); } From 378dc0357dd9aba1527c54faf983c44b121a85b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 28 Dec 2024 11:19:16 +0800 Subject: [PATCH 060/113] Disable `backtrace-debuginfo.rs` on windows-gnu --- tests/ui/runtime/backtrace-debuginfo.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs index 9c4b15e64f51..da747ded44ff 100644 --- a/tests/ui/runtime/backtrace-debuginfo.rs +++ b/tests/ui/runtime/backtrace-debuginfo.rs @@ -13,6 +13,10 @@ //@ ignore-sgx no processes //@ ignore-fuchsia Backtrace not symbolized, trace different line alignment +// FIXME(#117097): backtrace (possibly unwinding mechanism) seems to be different on at least +// `i686-mingw` (32-bit windows-gnu)? cc #128911. +//@ ignore-windows-gnu + use std::env; #[path = "backtrace-debuginfo-aux.rs"] mod aux; From f55736365a886d6fbb90cf97e3941c76d77536f2 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 28 Dec 2024 14:23:12 +1100 Subject: [PATCH 061/113] compiletest: Make a FIXME for escaped newlines less confusing The old FIXME implies that we don't support escaped newlines, but in fact it was added in the same patch that added support for escaped newlines. The new FIXME makes it clear that we do currently support this, and that the FIXME is for doing so in a less ad-hoc way. --- src/tools/compiletest/src/header.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 73d00fbf7b85..48149e3b897e 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1156,7 +1156,9 @@ fn parse_normalize_rule(raw_value: &str) -> Option<(String, String)> { .captures(raw_value)?; let regex = captures["regex"].to_owned(); let replacement = captures["replacement"].to_owned(); - // FIXME: Support escaped new-line in strings. + // A `\n` sequence in the replacement becomes an actual newline. + // FIXME: Do unescaping in a less ad-hoc way, and perhaps support escaped + // backslashes and double-quotes. let replacement = replacement.replace("\\n", "\n"); Some((regex, replacement)) } From b77ab2dd90b8636a38cb34a3e6fe73dbb1e7b0f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 28 Dec 2024 02:20:26 +0800 Subject: [PATCH 062/113] tests: migrate `libs-through-symlink` to rmake.rs - Document test intent, backlink to #13890 and fix PR #13903. - Fix the test logic: the `Makefile` version seems to not actually be exercising the "library search traverses symlink" logic, because the actual symlinked-to-library is present under the directory tree when `bar.rs` is compiled, because the `$(RUSTC)` invocation has an implicit `-L $(TMPDIR)`. The symlink itself was actually broken, i.e. it should've been `ln -nsf $(TMPDIR)/outdir/$(NAME) $(TMPDIR)` but it used `ln -nsf outdir/$(NAME) $(TMPDIR)`. Co-authored-by: Oneirical --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/libs-through-symlinks/Makefile | 22 --------- tests/run-make/libs-through-symlinks/rmake.rs | 48 +++++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) delete mode 100644 tests/run-make/libs-through-symlinks/Makefile create mode 100644 tests/run-make/libs-through-symlinks/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f7ecb4851529..7ab27667e28f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -2,7 +2,6 @@ run-make/branch-protection-check-IBT/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/extern-fn-reachable/Makefile run-make/jobserver-error/Makefile -run-make/libs-through-symlinks/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile run-make/translation/Makefile diff --git a/tests/run-make/libs-through-symlinks/Makefile b/tests/run-make/libs-through-symlinks/Makefile deleted file mode 100644 index c6ff566a0e86..000000000000 --- a/tests/run-make/libs-through-symlinks/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# ignore-windows - -# The option -n for the AIX ln command has a different purpose than it does -# on Linux. On Linux, the -n option is used to treat the destination path as -# normal file if it is a symbolic link to a directory, which is the default -# behavior of the AIX ln command. -ifeq ($(UNAME),AIX) -LN_FLAGS := -sf -else -LN_FLAGS := -nsf -endif - -NAME := $(shell $(RUSTC) --print file-names foo.rs) - -all: - mkdir -p $(TMPDIR)/outdir - $(RUSTC) foo.rs -o $(TMPDIR)/outdir/$(NAME) - ln $(LN_FLAGS) outdir/$(NAME) $(TMPDIR) - RUSTC_LOG=rustc_metadata::loader $(RUSTC) bar.rs diff --git a/tests/run-make/libs-through-symlinks/rmake.rs b/tests/run-make/libs-through-symlinks/rmake.rs new file mode 100644 index 000000000000..4bb3d05abb7a --- /dev/null +++ b/tests/run-make/libs-through-symlinks/rmake.rs @@ -0,0 +1,48 @@ +//! Regression test for [rustc doesn't handle relative symlinks to libraries +//! #13890](https://github.com/rust-lang/rust/issues/13890). +//! +//! This smoke test checks that for a given library search path `P`: +//! +//! - `rustc` is able to locate a library available via a symlink, where: +//! - the symlink is under the directory subtree of `P`, +//! - but the actual library is not (it's in a different directory subtree). +//! +//! For example: +//! +//! ```text +//! actual_dir/ +//! libfoo.rlib +//! symlink_dir/ # $CWD set; rustc -L . bar.rs that depends on foo +//! libfoo.rlib --> ../actual_dir/libfoo.rlib +//! ``` +//! +//! Previously, if `rustc` was invoked with CWD set to `symlink_dir/`, it would fail to traverse the +//! symlink to locate `actual_dir/libfoo.rlib`. This was originally fixed in +//! . + +//@ ignore-cross-compile + +use run_make_support::{bare_rustc, cwd, path, rfs, rust_lib_name}; + +fn main() { + let actual_lib_dir = path("actual_lib_dir"); + let symlink_lib_dir = path("symlink_lib_dir"); + rfs::create_dir_all(&actual_lib_dir); + rfs::create_dir_all(&symlink_lib_dir); + + // NOTE: `bare_rustc` is used because it does not introduce an implicit `-L .` library search + // flag. + bare_rustc().input("foo.rs").output(actual_lib_dir.join(rust_lib_name("foo"))).run(); + + rfs::symlink_file( + actual_lib_dir.join(rust_lib_name("foo")), + symlink_lib_dir.join(rust_lib_name("foo")), + ); + + // Make rustc's $CWD be in the directory containing the symlink-to-lib. + bare_rustc() + .current_dir(&symlink_lib_dir) + .library_search_path(".") + .input(cwd().join("bar.rs")) + .run(); +} From b32591e5808ce7c59b58bd807dc1d26670cedb68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 25 Dec 2024 20:15:49 +0800 Subject: [PATCH 063/113] tests: migrate `branch-protection-check-IBT` to rmake.rs - The Makefile version *never* ran because of Makefile syntax confusion. - The test would've always failed because precompiled std is not built with `-Z cf-protection=branch`, but linkers require all input object files to indicate IBT support in order to enable IBT for the executable, which is not the case for std. - Thus, the test input file is instead changed to a `no_std` + `no_core` program. Co-authored-by: Jerry Wang Co-authored-by: Oneirical --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../branch-protection-check-IBT/Makefile | 21 -------- .../branch-protection-check-IBT/_rmake.rs | 29 ---------- .../branch-protection-check-IBT/main.rs | 8 +-- .../branch-protection-check-IBT/rmake.rs | 53 +++++++++++++++++++ 5 files changed, 58 insertions(+), 54 deletions(-) delete mode 100644 tests/run-make/branch-protection-check-IBT/Makefile delete mode 100644 tests/run-make/branch-protection-check-IBT/_rmake.rs create mode 100644 tests/run-make/branch-protection-check-IBT/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f7ecb4851529..2f8981870229 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,4 +1,3 @@ -run-make/branch-protection-check-IBT/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/extern-fn-reachable/Makefile run-make/jobserver-error/Makefile diff --git a/tests/run-make/branch-protection-check-IBT/Makefile b/tests/run-make/branch-protection-check-IBT/Makefile deleted file mode 100644 index ee0e034627f6..000000000000 --- a/tests/run-make/branch-protection-check-IBT/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Check for GNU Property Note - -include ../tools.mk - -# How to run this -# python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/ - -# only-x86_64 - -# ignore-test -# FIXME(jieyouxu): This test never runs because the `ifeq` check on line 17 -# compares `x86` to `x86_64`, which always evaluates to false. -# When the test does run, the compilation does not include `.note.gnu.property`. -# See https://github.com/rust-lang/rust/pull/126720 for more information. - -all: -ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64) - $(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles' -C save-temps ./main.rs -o $(TMPDIR)/rsmain - readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property" -endif - diff --git a/tests/run-make/branch-protection-check-IBT/_rmake.rs b/tests/run-make/branch-protection-check-IBT/_rmake.rs deleted file mode 100644 index 911514087856..000000000000 --- a/tests/run-make/branch-protection-check-IBT/_rmake.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Check for GNU Property Note - -// How to run this -// python3 x.py test --target x86_64-unknown-linux-gnu tests/run-make/branch-protection-check-IBT/ - -//@ only-x86_64 - -//@ ignore-test -// FIXME(jieyouxu): see the FIXME in the Makefile - -use run_make_support::{cwd, env_var, llvm_readobj, rustc}; - -fn main() { - let llvm_components = env_var("LLVM_COMPONENTS"); - if !format!(" {llvm_components} ").contains(" x86 ") { - return; - } - - rustc() - .input("main.rs") - .target("x86_64-unknown-linux-gnu") - .arg("-Zcf-protection=branch") - .arg(format!("-L{}", cwd().display())) - .arg("-Clink-args=-nostartfiles") - .arg("-Csave-temps") - .run(); - - llvm_readobj().arg("-nW").input("main").run().assert_stdout_contains(".note.gnu.property"); -} diff --git a/tests/run-make/branch-protection-check-IBT/main.rs b/tests/run-make/branch-protection-check-IBT/main.rs index ad379d6ea437..445b8795134c 100644 --- a/tests/run-make/branch-protection-check-IBT/main.rs +++ b/tests/run-make/branch-protection-check-IBT/main.rs @@ -1,3 +1,5 @@ -fn main() { - println!("hello world"); -} +#![feature(no_core)] +#![allow(internal_features)] +#![no_core] +#![no_std] +#![no_main] diff --git a/tests/run-make/branch-protection-check-IBT/rmake.rs b/tests/run-make/branch-protection-check-IBT/rmake.rs new file mode 100644 index 000000000000..73109df12ae9 --- /dev/null +++ b/tests/run-make/branch-protection-check-IBT/rmake.rs @@ -0,0 +1,53 @@ +// ignore-tidy-linelength +//! A basic smoke test to check for GNU Property Note to see that for `x86_64` targets when [`-Z +//! cf-protection=branch`][intel-cet-tracking-issue] is requested, that the +//! +//! ```text +//! NT_GNU_PROPERTY_TYPE_0 Properties: x86 feature: IBT +//! ``` +//! +//! Intel Indirect Branch Tracking (IBT) property is emitted. This was generated in +//! in order to address +//! . +//! +//! Note that the precompiled std currently is not compiled with `-Z cf-protection=branch`! +//! +//! In particular, it is expected that: +//! +//! > IBT to only be enabled for the process if `.note.gnu.property` indicates that the executable +//! > was compiled with IBT support and the linker to only tell that IBT is supported if all input +//! > object files indicate that they support IBT, which in turn requires the standard library to be +//! > compiled with IBT enabled. +//! +//! Note that Intel IBT (Indirect Branch Tracking) is not to be confused with Arm's BTI (Branch +//! Target Identification). See below for link to Intel IBT docs. +//! +//! ## Related links +//! +//! - [Tracking Issue for Intel Control Enforcement Technology (CET)][intel-cet-tracking-issue] +//! - Zulip question about this test: +//! +//! - Intel IBT docs: +//! +//! +//! [intel-cet-tracking-issue]: https://github.com/rust-lang/rust/issues/93754 + +//@ needs-llvm-components: x86 + +// FIXME(#93754): increase the test coverage of this test. +//@ only-x86_64-unknown-linux-gnu +//@ ignore-cross-compile + +use run_make_support::{bare_rustc, llvm_readobj}; + +fn main() { + // `main.rs` is `#![no_std]` to not pull in the currently not-compiled-with-IBT precompiled std. + bare_rustc() + .input("main.rs") + .target("x86_64-unknown-linux-gnu") + .arg("-Zcf-protection=branch") + .arg("-Clink-args=-nostartfiles") + .run(); + + llvm_readobj().arg("-nW").input("main").run().assert_stdout_contains(".note.gnu.property"); +} From ec9502d803a33f60bfe063000f1bdf873308822d Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 22 Dec 2024 09:21:48 +0300 Subject: [PATCH 064/113] remove an invalid FIXME note Signed-off-by: onur-ozkan --- src/bootstrap/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 0ecf61ffcd90..eff259212c58 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -635,11 +635,12 @@ impl Build { if self.config.backtrace { features.insert("backtrace"); } + if self.config.profiler_enabled(target) { features.insert("profiler"); } - // Generate memcpy, etc. FIXME: Remove this once compiler-builtins - // automatically detects this target. + + // If zkvm target, generate memcpy, etc. if target.contains("zkvm") { features.insert("compiler-builtins-mem"); } From 47cd3e7c6183853ddac9b9995ec1eec197394a10 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 22 Dec 2024 09:22:12 +0300 Subject: [PATCH 065/113] read to `String` directly without extra conversion Signed-off-by: onur-ozkan --- src/bootstrap/src/core/download.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index db35e6907e66..8b513093db90 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -197,8 +197,7 @@ impl Config { if !path_is_dylib(fname) { // Finally, set the correct .interp for binaries let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker"); - // FIXME: can we support utf8 here? `args` doesn't accept Vec, only OsString ... - let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path)))); + let dynamic_linker = t!(fs::read_to_string(dynamic_linker_path)); patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]); } From eedafbc92fff51e7f7d47ee1875f8b52e0744660 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 22 Dec 2024 09:39:04 +0300 Subject: [PATCH 066/113] remove deprecated option `parallel-compiler` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/config/config.rs | 10 ---------- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 435216ef534c..17fc037a0594 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1154,7 +1154,6 @@ define_config! { debuginfo_level_tests: Option = "debuginfo-level-tests", backtrace: Option = "backtrace", incremental: Option = "incremental", - parallel_compiler: Option = "parallel-compiler", default_linker: Option = "default-linker", channel: Option = "channel", description: Option = "description", @@ -1764,7 +1763,6 @@ impl Config { debuginfo_level_tests: debuginfo_level_tests_toml, backtrace, incremental, - parallel_compiler, randomize_layout, default_linker, channel: _, // already handled above @@ -1874,13 +1872,6 @@ impl Config { config.rust_randomize_layout = randomize_layout.unwrap_or_default(); config.llvm_tools_enabled = llvm_tools.unwrap_or(true); - // FIXME: Remove this option at the end of 2024. - if parallel_compiler.is_some() { - println!( - "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" - ); - } - config.llvm_enzyme = llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly"); config.rustc_default_linker = default_linker; @@ -3222,7 +3213,6 @@ fn check_incompatible_options_for_ci_rustc( debuginfo_level_tools: _, debuginfo_level_tests: _, backtrace: _, - parallel_compiler: _, musl_root: _, verbose_tests: _, optimize_tests: _, diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 139ea357877b..8fd6c8aa23ae 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -320,4 +320,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "compiletest now takes `--no-capture` instead of `--nocapture`; bootstrap now accepts `--no-capture` as an argument to test commands directly", }, + ChangeInfo { + change_id: 134650, + severity: ChangeSeverity::Warning, + summary: "Removed `rust.parallel-compiler` as it was deprecated in #132282 long time ago.", + }, ]; From c393811a48932a13b44ef2546a6c0f7ce9225857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Sat, 28 Dec 2024 17:54:59 +0800 Subject: [PATCH 067/113] bootstrap: drop warning for top-level test suite path check This doesn't quite handle the more exotic path suffix matches that test filters seem to accept (e.g. `library/test` can be matched with `--exclude test`), so avoid warning on non-existent top-level test suites for now. A proper fix will need to possibly query test `Step`s for their exclude logic. --- src/bootstrap/src/core/config/config.rs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 435216ef534c..a3bf1021f9a2 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1325,23 +1325,14 @@ impl Config { .into_iter() .chain(flags.exclude) .map(|p| { - let p = if cfg!(windows) { - PathBuf::from(p.to_str().unwrap().replace('/', "\\")) - } else { - p - }; - - // Jump to top-level project path to support passing paths - // from sub directories. - let top_level_path = config.src.join(&p); - if !config.src.join(&top_level_path).exists() { - eprintln!("WARNING: '{}' does not exist.", top_level_path.display()); - } - // Never return top-level path here as it would break `--skip` // logic on rustc's internal test framework which is utilized // by compiletest. - p + if cfg!(windows) { + PathBuf::from(p.to_str().unwrap().replace('/', "\\")) + } else { + p + } }) .collect(); From c1c2d85cc9cf314d8a9248c8910229b99d914975 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 28 Dec 2024 23:23:41 +1100 Subject: [PATCH 068/113] bootstrap: Allow `./x check compiletest` --- src/bootstrap/src/core/build_steps/check.rs | 3 +++ src/bootstrap/src/core/builder/mod.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f32d95fe8367..b4d37b25a6c7 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -501,6 +501,9 @@ tool_check_step!( ); tool_check_step!(Bootstrap, "bootstrap", "src/bootstrap", SourceType::InTree, false); +// Compiletest is implicitly "checked" when it gets built in order to run tests, +// so this is mainly for people working on compiletest to run locally. +tool_check_step!(Compiletest, "compiletest", "src/tools/compiletest", SourceType::InTree, false); /// Cargo's output path for the standard library in a given stage, compiled /// by a particular compiler for the specified target. diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 98f765dbd0f5..18beaf3676d5 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -905,6 +905,7 @@ impl<'a> Builder<'a> { check::RustAnalyzer, check::TestFloatParse, check::Bootstrap, + check::Compiletest, ), Kind::Test => describe!( crate::core::build_steps::toolstate::ToolStateCheck, From a625ddd1ed250a32690ce739997706b3bfd7e2ec Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 28 Dec 2024 23:37:48 +1100 Subject: [PATCH 069/113] Remove the unused `cdbg-*` debugger directive prefix There are no tests in `tests/debuginfo` that use this prefix. --- src/tools/compiletest/src/runtest/debuginfo.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index c621c22ac993..7f1f85ba730d 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -59,14 +59,8 @@ impl TestCx<'_> { return; } - let prefixes = { - static PREFIXES: &[&str] = &["cdb", "cdbg"]; - // No "native rust support" variation for CDB yet. - PREFIXES - }; - // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["cdb"]) .unwrap_or_else(|e| self.fatal(&e)); // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands From 2f8824a477f8b4ec51a3365c2d68f525032b8241 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sat, 28 Dec 2024 23:43:41 +1100 Subject: [PATCH 070/113] Simplify `DebuggerCommands::parse_from` to only take one prefix --- src/tools/compiletest/src/runtest/debugger.rs | 25 ++++++------------- .../compiletest/src/runtest/debuginfo.rs | 6 ++--- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index c15422fb6f68..d9e5c3fa0d8f 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -19,15 +19,9 @@ pub(super) struct DebuggerCommands { } impl DebuggerCommands { - pub fn parse_from( - file: &Path, - config: &Config, - debugger_prefixes: &[&str], - ) -> Result { - let directives = debugger_prefixes - .iter() - .map(|prefix| (format!("{prefix}-command"), format!("{prefix}-check"))) - .collect::>(); + pub fn parse_from(file: &Path, config: &Config, debugger_prefix: &str) -> Result { + let command_directive = format!("{debugger_prefix}-command"); + let check_directive = format!("{debugger_prefix}-check"); let mut breakpoint_lines = vec![]; let mut commands = vec![]; @@ -48,14 +42,11 @@ impl DebuggerCommands { continue; }; - for &(ref command_directive, ref check_directive) in &directives { - config - .parse_name_value_directive(&line, command_directive) - .map(|cmd| commands.push(cmd)); - - config - .parse_name_value_directive(&line, check_directive) - .map(|cmd| check_lines.push((line_no, cmd))); + if let Some(command) = config.parse_name_value_directive(&line, &command_directive) { + commands.push(command); + } + if let Some(pattern) = config.parse_name_value_directive(&line, &check_directive) { + check_lines.push((line_no, pattern)); } } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 7f1f85ba730d..b236b0675690 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -60,7 +60,7 @@ impl TestCx<'_> { } // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["cdb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "cdb") .unwrap_or_else(|e| self.fatal(&e)); // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands @@ -131,7 +131,7 @@ impl TestCx<'_> { } fn run_debuginfo_gdb_test_no_opt(&self) { - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["gdb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "gdb") .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); @@ -397,7 +397,7 @@ impl TestCx<'_> { } // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["lldb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "lldb") .unwrap_or_else(|e| self.fatal(&e)); // Write debugger script: From 11ad6ff3cb3cb3da0040541877c716ddc38ec388 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sat, 28 Dec 2024 15:42:39 +0100 Subject: [PATCH 071/113] docs: inline `alloc::ffi::c_str` types to `alloc::ffi` --- library/alloc/src/ffi/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/ffi/mod.rs b/library/alloc/src/ffi/mod.rs index 4f9dc40a3cfc..695d7ad07cf7 100644 --- a/library/alloc/src/ffi/mod.rs +++ b/library/alloc/src/ffi/mod.rs @@ -83,7 +83,7 @@ #[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::CString; -#[doc(no_inline)] +#[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] pub use self::c_str::{FromVecWithNulError, IntoStringError, NulError}; From 35e5c7d43808c0dfaffa67abeb16ce58f1ae4695 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 28 Dec 2024 08:44:25 -0500 Subject: [PATCH 072/113] Document virality of `feature(rustc_private)` Since 9cb1998ea15e179482504e07cad8fa121e169a32 this feature is viral. --- .../unstable-book/src/language-features/rustc-private.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/rustc-private.md b/src/doc/unstable-book/src/language-features/rustc-private.md index 97fce5980e40..3b83a3cf4df8 100644 --- a/src/doc/unstable-book/src/language-features/rustc-private.md +++ b/src/doc/unstable-book/src/language-features/rustc-private.md @@ -6,6 +6,9 @@ The tracking issue for this feature is: [#27812] ------------------------ -This feature allows access to unstable internal compiler crates. +This feature allows access to unstable internal compiler crates such as `rustc_driver`. -Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`. +The presence of this feature changes the way the linkage format for dylibs is calculated in a way +that is necessary for linking against dylibs that statically link `std` (such as `rustc_driver`). +This makes this feature "viral" in linkage; its use in a given crate makes its use required in +dependent crates which link to it (including integration tests, which are built as separate crates). From d6c73ebbf3df1331eb60a6fba1f4b0bd03274f49 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 28 Dec 2024 10:14:46 -0500 Subject: [PATCH 073/113] Added a codegen test for optimization with const arrays Closes #107208 --- tests/codegen/const-array.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/codegen/const-array.rs diff --git a/tests/codegen/const-array.rs b/tests/codegen/const-array.rs new file mode 100644 index 000000000000..f2b331c315dc --- /dev/null +++ b/tests/codegen/const-array.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] + +const LUT: [u8; 2] = [1, 1]; + +// CHECK-LABEL: @decode +#[no_mangle] +pub fn decode(i: u8) -> u8 { + // CHECK: start: + // CHECK-NEXT: icmp + // CHECK-NEXT: select + // CHECK-NEXT: ret + if i < 2 { LUT[i as usize] } else { 2 } +} From f5c497529c5d06cf3171bae1c60d44a494fa0a3d Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Mon, 23 Dec 2024 23:44:45 +0100 Subject: [PATCH 074/113] nits: librustdoc::clean - librustdoc::clean::clean_lifetime doesn't need a mut doc context - librustdoc::clean::normalize doesn't need a mut doc context - move Some() wrapping up into `clean_predicate()` - simplify nested if in librustdoc::clean::record_extern_fqn() --- src/librustdoc/clean/mod.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 27b7d55f4d08..3c9e0914b59d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -268,7 +268,7 @@ fn clean_poly_trait_ref_with_constraints<'tcx>( ) } -fn clean_lifetime(lifetime: &hir::Lifetime, cx: &mut DocContext<'_>) -> Lifetime { +fn clean_lifetime(lifetime: &hir::Lifetime, cx: &DocContext<'_>) -> Lifetime { if let Some( rbv::ResolvedArg::EarlyBound(did) | rbv::ResolvedArg::LateBound(_, _, did) @@ -362,9 +362,9 @@ pub(crate) fn clean_predicate<'tcx>( let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_predicate.rebind(pred), cx), - ty::ClauseKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred), + ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred)), ty::ClauseKind::TypeOutlives(pred) => { - clean_type_outlives_predicate(bound_predicate.rebind(pred), cx) + Some(clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)) } ty::ClauseKind::Projection(pred) => { Some(clean_projection_predicate(bound_predicate.rebind(pred), cx)) @@ -396,32 +396,30 @@ fn clean_poly_trait_predicate<'tcx>( }) } -fn clean_region_outlives_predicate( - pred: ty::RegionOutlivesPredicate<'_>, -) -> Option { +fn clean_region_outlives_predicate(pred: ty::RegionOutlivesPredicate<'_>) -> WherePredicate { let ty::OutlivesPredicate(a, b) = pred; - Some(WherePredicate::RegionPredicate { + WherePredicate::RegionPredicate { lifetime: clean_middle_region(a).expect("failed to clean lifetime"), bounds: vec![GenericBound::Outlives( clean_middle_region(b).expect("failed to clean bounds"), )], - }) + } } fn clean_type_outlives_predicate<'tcx>( pred: ty::Binder<'tcx, ty::TypeOutlivesPredicate<'tcx>>, cx: &mut DocContext<'tcx>, -) -> Option { +) -> WherePredicate { let ty::OutlivesPredicate(ty, lt) = pred.skip_binder(); - Some(WherePredicate::BoundPredicate { + WherePredicate::BoundPredicate { ty: clean_middle_ty(pred.rebind(ty), cx, None, None), bounds: vec![GenericBound::Outlives( clean_middle_region(lt).expect("failed to clean lifetimes"), )], bound_params: Vec::new(), - }) + } } fn clean_middle_term<'tcx>( @@ -1860,7 +1858,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T /// Returns `None` if the type could not be normalized fn normalize<'tcx>( - cx: &mut DocContext<'tcx>, + cx: &DocContext<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, ) -> Option>> { // HACK: low-churn fix for #79459 while we wait for a trait normalization fix From 563920ce1410dd27104dcfe861398a43da0e319c Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Sun, 29 Dec 2024 01:17:18 +0100 Subject: [PATCH 075/113] rustc_codegen_ssa: Buffer file writes in link_rlib This makes this step take ~25ms on my machine (M3 Max 64GB) for Zed repo instead of ~150ms. Additionally it takes down the time needed for a clean cargo build of ripgrep from ~6.1s to 5.9s. This change is mostly relevant for crates with multiple large CGUs. --- compiler/rustc_codegen_ssa/src/back/archive.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index d9eece1d8dc9..dc8774ff477d 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -2,7 +2,7 @@ use std::env; use std::error::Error; use std::ffi::OsString; use std::fs::{self, File}; -use std::io::{self, Write}; +use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; use ar_archive_writer::{ @@ -493,7 +493,6 @@ impl<'a> ArArchiveBuilder<'a> { perms: 0o644, }) } - // Write to a temporary file first before atomically renaming to the final name. // This prevents programs (including rustc) from attempting to read a partial archive. // It also enables writing an archive with the same filename as a dependency on Windows as @@ -509,9 +508,9 @@ impl<'a> ArArchiveBuilder<'a> { io_error_context("couldn't create a directory for the temp file", err) })?; let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a"); - let mut archive_tmpfile = File::create_new(&archive_tmpfile_path) + let archive_tmpfile = File::create_new(&archive_tmpfile_path) .map_err(|err| io_error_context("couldn't create the temp file", err))?; - + let mut archive_tmpfile = BufWriter::new(archive_tmpfile); write_archive_to_stream( &mut archive_tmpfile, &entries, @@ -519,7 +518,8 @@ impl<'a> ArArchiveBuilder<'a> { false, /* is_ec = */ self.sess.target.arch == "arm64ec", )?; - + archive_tmpfile.flush()?; + drop(archive_tmpfile); let any_entries = !entries.is_empty(); drop(entries); // Drop src_archives to unmap all input archives, which is necessary if we want to write the From 519c233cbbfafcb3c3c7c069de28e96f60e64466 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 29 Dec 2024 00:22:58 +0000 Subject: [PATCH 076/113] cargo update compiler & tools dependencies: Locking 8 packages to latest compatible versions Updating anyhow v1.0.94 -> v1.0.95 Updating glob v0.3.1 -> v0.3.2 Updating quote v1.0.37 -> v1.0.38 Updating rustversion v1.0.18 -> v1.0.19 Updating serde v1.0.216 -> v1.0.217 Updating serde_derive v1.0.216 -> v1.0.217 Updating syn v2.0.90 -> v2.0.93 Updating unicase v2.8.0 -> v2.8.1 note: pass `--verbose` to see 36 unchanged dependencies behind latest library dependencies: Locking 0 packages to latest compatible versions note: pass `--verbose` to see 5 unchanged dependencies behind latest rustbook dependencies: Locking 7 packages to latest compatible versions Updating anyhow v1.0.94 -> v1.0.95 Updating cc v1.2.5 -> v1.2.6 Updating quote v1.0.37 -> v1.0.38 Updating serde v1.0.216 -> v1.0.217 Updating serde_derive v1.0.216 -> v1.0.217 Updating syn v2.0.90 -> v2.0.93 Updating unicase v2.8.0 -> v2.8.1 --- Cargo.lock | 102 +++++++++++++++++----------------- src/tools/rustbook/Cargo.lock | 28 +++++----- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eeb3c99a294a..266a93605bde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,9 +182,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" dependencies = [ "backtrace", ] @@ -519,7 +519,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -550,7 +550,7 @@ dependencies = [ "rustc_tools_util", "serde", "serde_json", - "syn 2.0.90", + "syn 2.0.93", "tempfile", "termize", "tokio", @@ -660,7 +660,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -885,7 +885,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -896,7 +896,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -933,7 +933,7 @@ checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -954,7 +954,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -964,7 +964,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -976,7 +976,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1054,7 +1054,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1351,7 +1351,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1463,9 +1463,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" @@ -1585,7 +1585,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -1774,7 +1774,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -2730,7 +2730,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -2952,9 +2952,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -3140,7 +3140,7 @@ dependencies = [ "rinja_parser", "rustc-hash 2.1.0", "serde", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -3780,7 +3780,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "unic-langid", ] @@ -3915,7 +3915,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -4063,7 +4063,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -4651,7 +4651,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -4740,7 +4740,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -4787,9 +4787,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ruzstd" @@ -4862,22 +4862,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5135,9 +5135,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -5152,7 +5152,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5294,7 +5294,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5305,7 +5305,7 @@ checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5506,7 +5506,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -5677,15 +5677,15 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.90", + "syn 2.0.93", "unic-langid-impl", ] [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" @@ -5883,7 +5883,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "wasm-bindgen-shared", ] @@ -5905,7 +5905,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6087,7 +6087,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.90", + "syn 2.0.93", "windows-metadata", ] @@ -6120,7 +6120,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -6131,7 +6131,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -6410,7 +6410,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -6432,7 +6432,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] [[package]] @@ -6452,7 +6452,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", "synstructure", ] @@ -6475,5 +6475,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.93", ] diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 68fb9895ecd4..1f98e820840f 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "autocfg" @@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] @@ -1209,9 +1209,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1338,18 +1338,18 @@ checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -1446,9 +1446,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -1639,9 +1639,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" From 8c8fed7ea92a4048d1424f41ddf9b288ffed4df0 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sun, 29 Dec 2024 00:30:32 +0000 Subject: [PATCH 077/113] Bump compiler cc --- Cargo.lock | 4 ++-- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_llvm/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eeb3c99a294a..fc196c67cf39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -405,9 +405,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 3a9b4d368078..f0456e62442a 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -10,7 +10,7 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" # Pinned so `cargo update` bumps don't cause breakage. Please also update the # `cc` in `rustc_llvm` if you update the `cc` here. -cc = "=1.2.5" +cc = "=1.2.6" either = "1.5.0" itertools = "0.12" pathdiff = "0.2.0" diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 79a6454dbb94..b2a14a0022e8 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -12,5 +12,5 @@ libc = "0.2.73" # tidy-alphabetical-start # Pinned so `cargo update` bumps don't cause breakage. Please also update the # pinned `cc` in `rustc_codegen_ssa` if you update `cc` here. -cc = "=1.2.5" +cc = "=1.2.6" # tidy-alphabetical-end From 0c2f4359fdb8c556af298e835d3828d7c0b4e658 Mon Sep 17 00:00:00 2001 From: Geoffrey Thomas Date: Sat, 28 Dec 2024 22:21:04 -0500 Subject: [PATCH 078/113] Fix sentence fragment in `pin` module docs Looks like this was inadvertently dropped in 8241ca60. Restore the words from before that commit. --- library/core/src/pin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index f18a45083ff7..83730285636f 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -595,7 +595,7 @@ //! [drop-impl]: self#implementing-drop-for-types-with-address-sensitive-states //! //! The [`drop`] function takes [`&mut self`], but this is called *even if that `self` has been -//! pinned*! Implementing [`Drop`] for a type with address-sensitive states, because if `self` was +//! pinned*! Implementing [`Drop`] for a type with address-sensitive states requires some care, because if `self` was //! indeed in an address-sensitive state before [`drop`] was called, it is as if the compiler //! automatically called [`Pin::get_unchecked_mut`]. //! From 71e3ea35b175fa50e5fcd033980666548b718081 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sun, 29 Dec 2024 03:31:37 +0000 Subject: [PATCH 079/113] Add codegen test for issue 63646 --- tests/codegen/range_to_inclusive.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/codegen/range_to_inclusive.rs diff --git a/tests/codegen/range_to_inclusive.rs b/tests/codegen/range_to_inclusive.rs new file mode 100644 index 000000000000..f3001897f88d --- /dev/null +++ b/tests/codegen/range_to_inclusive.rs @@ -0,0 +1,28 @@ +//! Test that `RangeTo` and `RangeToInclusive` generate identical +//! (and optimal) code; #63646 +//@ compile-flags: -O -Zmerge-functions=disabled +#![crate_type = "lib"] + +#[no_mangle] +// CHECK-LABEL: range_to( +pub fn range_to(a: i32, mut b: i32) -> i32 { + // CHECK: %1 = and i32 %0, %a + // CHECK-NEXT: ret i32 %1 + for _ in 0..65 { + b &= a; + } + + b +} + +#[no_mangle] +// CHECK-LABEL: range_to_inclusive( +pub fn range_to_inclusive(a: i32, mut b: i32) -> i32 { + // CHECK: %1 = and i32 %0, %a + // CHECK-NEXT: ret i32 %1 + for _ in 0..=64 { + b &= a; + } + + b +} From 7b7f634cac2fb0a235e3123c457f51a9f579d0d4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 29 Dec 2024 14:59:34 +1100 Subject: [PATCH 080/113] Consolidate the macros for declaring compiletest suites --- src/bootstrap/src/core/build_steps/test.rs | 163 ++++++++++----------- 1 file changed, 81 insertions(+), 82 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 95192efda988..2ff76323c77c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1133,69 +1133,19 @@ fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { builder.out.join(host).join("test") } -macro_rules! default_test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { - test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false }); - }; -} - -macro_rules! default_test_with_compare_mode { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, - compare_mode: $compare_mode:expr }) => { - test_with_compare_mode!($name { - path: $path, - mode: $mode, - suite: $suite, - default: true, - host: false, - compare_mode: $compare_mode - }); - }; -} - -macro_rules! host_test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { - test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true }); - }; -} - +/// Declares a test step that invokes compiletest on a particular test suite. macro_rules! test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, - host: $host:expr }) => { - test_definitions!($name { - path: $path, - mode: $mode, - suite: $suite, - default: $default, - host: $host, - compare_mode: None - }); - }; -} - -macro_rules! test_with_compare_mode { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, - host: $host:expr, compare_mode: $compare_mode:expr }) => { - test_definitions!($name { - path: $path, - mode: $mode, - suite: $suite, - default: $default, - host: $host, - compare_mode: Some($compare_mode) - }); - }; -} - -macro_rules! test_definitions { - ($name:ident { - path: $path:expr, - mode: $mode:expr, - suite: $suite:expr, - default: $default:expr, - host: $host:expr, - compare_mode: $compare_mode:expr - }) => { + ( + $name:ident { + path: $path:expr, + mode: $mode:expr, + suite: $suite:expr, + default: $default:expr + $( , only_hosts: $only_hosts:expr )? // default: false + $( , compare_mode: $compare_mode:expr )? // default: None + $( , )? // optional trailing comma + } + ) => { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1205,7 +1155,12 @@ macro_rules! test_definitions { impl Step for $name { type Output = (); const DEFAULT: bool = $default; - const ONLY_HOSTS: bool = $host; + const ONLY_HOSTS: bool = (const { + #[allow(unused_assignments, unused_mut)] + let mut value = false; + $( value = $only_hosts; )? + value + }); fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.suite_path($path) @@ -1224,7 +1179,12 @@ macro_rules! test_definitions { mode: $mode, suite: $suite, path: $path, - compare_mode: $compare_mode, + compare_mode: (const { + #[allow(unused_assignments, unused_mut)] + let mut value = None; + $( value = $compare_mode; )? + value + }), }) } } @@ -1232,7 +1192,7 @@ macro_rules! test_definitions { } /// Declares an alias for running the [`Coverage`] tests in only one mode. -/// Adapted from [`test_definitions`]. +/// Adapted from [`test`]. macro_rules! coverage_test_alias { ($name:ident { alias_and_mode: $alias_and_mode:expr, // &'static str @@ -1410,37 +1370,74 @@ impl Step for CrateBuildHelper { } } -default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" }); +test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true }); -default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" }); +test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true }); -default_test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen" }); +test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen", default: true }); -default_test!(CodegenUnits { +test!(CodegenUnits { path: "tests/codegen-units", mode: "codegen-units", - suite: "codegen-units" + suite: "codegen-units", + default: true, }); -default_test!(Incremental { path: "tests/incremental", mode: "incremental", suite: "incremental" }); +test!(Incremental { + path: "tests/incremental", + mode: "incremental", + suite: "incremental", + default: true, +}); -default_test_with_compare_mode!(Debuginfo { +test!(Debuginfo { path: "tests/debuginfo", mode: "debuginfo", suite: "debuginfo", - compare_mode: "split-dwarf" + default: true, + compare_mode: Some("split-dwarf"), }); -host_test!(UiFullDeps { path: "tests/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" }); +test!(UiFullDeps { + path: "tests/ui-fulldeps", + mode: "ui", + suite: "ui-fulldeps", + default: true, + only_hosts: true, +}); -host_test!(Rustdoc { path: "tests/rustdoc", mode: "rustdoc", suite: "rustdoc" }); -host_test!(RustdocUi { path: "tests/rustdoc-ui", mode: "ui", suite: "rustdoc-ui" }); +test!(Rustdoc { + path: "tests/rustdoc", + mode: "rustdoc", + suite: "rustdoc", + default: true, + only_hosts: true, +}); +test!(RustdocUi { + path: "tests/rustdoc-ui", + mode: "ui", + suite: "rustdoc-ui", + default: true, + only_hosts: true, +}); -host_test!(RustdocJson { path: "tests/rustdoc-json", mode: "rustdoc-json", suite: "rustdoc-json" }); +test!(RustdocJson { + path: "tests/rustdoc-json", + mode: "rustdoc-json", + suite: "rustdoc-json", + default: true, + only_hosts: true, +}); -host_test!(Pretty { path: "tests/pretty", mode: "pretty", suite: "pretty" }); +test!(Pretty { + path: "tests/pretty", + mode: "pretty", + suite: "pretty", + default: true, + only_hosts: true, +}); -/// Special-handling is needed for `run-make`, so don't use `default_test` for defining `RunMake` +/// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake` /// tests. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct RunMake { @@ -1475,7 +1472,7 @@ impl Step for RunMake { } } -default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" }); +test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true }); /// Coverage tests are a bit more complicated than other test suites, because /// we want to run the same set of test files in multiple different modes, @@ -1569,10 +1566,12 @@ coverage_test_alias!(CoverageRun { only_hosts: true, }); -host_test!(CoverageRunRustdoc { +test!(CoverageRunRustdoc { path: "tests/coverage-run-rustdoc", mode: "coverage-run", - suite: "coverage-run-rustdoc" + suite: "coverage-run-rustdoc", + default: true, + only_hosts: true, }); // For the mir-opt suite we do not use macros, as we need custom behavior when blessing. From 1e37bbe2de0129e1e747a013e2dbd6f8ceee7cf5 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 29 Dec 2024 15:29:52 +1100 Subject: [PATCH 081/113] Allow macro-declared test steps to have docstrings and attributes --- src/bootstrap/src/core/build_steps/test.rs | 53 +++++++++++++--------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 2ff76323c77c..fe2dd9cc5f3e 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1136,6 +1136,7 @@ fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { /// Declares a test step that invokes compiletest on a particular test suite. macro_rules! test { ( + $( #[$attr:meta] )* // allow docstrings and attributes $name:ident { path: $path:expr, mode: $mode:expr, @@ -1146,6 +1147,7 @@ macro_rules! test { $( , )? // optional trailing comma } ) => { + $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1194,11 +1196,16 @@ macro_rules! test { /// Declares an alias for running the [`Coverage`] tests in only one mode. /// Adapted from [`test`]. macro_rules! coverage_test_alias { - ($name:ident { - alias_and_mode: $alias_and_mode:expr, // &'static str - default: $default:expr, // bool - only_hosts: $only_hosts:expr $(,)? // bool - }) => { + ( + $( #[$attr:meta] )* // allow docstrings and attributes + $name:ident { + alias_and_mode: $alias_and_mode:expr, // &'static str + default: $default:expr, // bool + only_hosts: $only_hosts:expr // bool + $( , )? // optional trailing comma + } + ) => { + $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1549,22 +1556,26 @@ impl Step for Coverage { } } -// Runs `tests/coverage` in "coverage-map" mode only. -// Used by `x test` and `x test coverage-map`. -coverage_test_alias!(CoverageMap { - alias_and_mode: "coverage-map", - default: true, - only_hosts: false, -}); -// Runs `tests/coverage` in "coverage-run" mode only. -// Used by `x test` and `x test coverage-run`. -coverage_test_alias!(CoverageRun { - alias_and_mode: "coverage-run", - default: true, - // Compiletest knows how to automatically skip these tests when cross-compiling, - // but skipping the whole step here makes it clearer that they haven't run at all. - only_hosts: true, -}); +coverage_test_alias! { + /// Runs the `tests/coverage` test suite in "coverage-map" mode only. + /// Used by `x test` and `x test coverage-map`. + CoverageMap { + alias_and_mode: "coverage-map", + default: true, + only_hosts: false, + } +} +coverage_test_alias! { + /// Runs the `tests/coverage` test suite in "coverage-run" mode only. + /// Used by `x test` and `x test coverage-run`. + CoverageRun { + alias_and_mode: "coverage-run", + default: true, + // Compiletest knows how to automatically skip these tests when cross-compiling, + // but skipping the whole step here makes it clearer that they haven't run at all. + only_hosts: true, + } +} test!(CoverageRunRustdoc { path: "tests/coverage-run-rustdoc", From 4192293b4d546a20dcd25ad344ef9fbc84e8f2a9 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 29 Dec 2024 20:29:49 +1100 Subject: [PATCH 082/113] Fix `./x check bootstrap` by moving `shared_helpers::tests` --- src/bootstrap/src/utils/mod.rs | 2 ++ src/bootstrap/src/utils/shared_helpers.rs | 5 +++-- src/bootstrap/src/utils/tests/mod.rs | 1 + .../tests.rs => tests/shared_helpers_tests.rs} | 9 ++++++++- 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 src/bootstrap/src/utils/tests/mod.rs rename src/bootstrap/src/utils/{shared_helpers/tests.rs => tests/shared_helpers_tests.rs} (69%) diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index 53b41f157806..b5f5e2ba6dc8 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -14,3 +14,5 @@ pub(crate) mod metrics; pub(crate) mod render_tests; pub(crate) mod shared_helpers; pub(crate) mod tarball; +#[cfg(test)] +mod tests; diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 6d3c276cc056..7b206c3ffe82 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -13,8 +13,9 @@ use std::io::Write; use std::process::Command; use std::str::FromStr; -#[cfg(test)] -mod tests; +// If we were to declare a tests submodule here, the shim binaries that include this +// module via `#[path]` would fail to find it, which breaks `./x check bootstrap`. +// So instead the unit tests for this module are in `super::tests::shared_helpers_tests`. /// Returns the environment variable which the dynamic library lookup path /// resides in for this platform. diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs new file mode 100644 index 000000000000..0791f7a6e207 --- /dev/null +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -0,0 +1 @@ +mod shared_helpers_tests; diff --git a/src/bootstrap/src/utils/shared_helpers/tests.rs b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs similarity index 69% rename from src/bootstrap/src/utils/shared_helpers/tests.rs rename to src/bootstrap/src/utils/tests/shared_helpers_tests.rs index da7924276f7c..6c47e7f24387 100644 --- a/src/bootstrap/src/utils/shared_helpers/tests.rs +++ b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs @@ -1,4 +1,11 @@ -use super::parse_value_from_args; +//! The `shared_helpers` module can't have its own tests submodule, because +//! that would cause problems for the shim binaries that include it via +//! `#[path]`, so instead those unit tests live here. +//! +//! To prevent tidy from complaining about this file not being named `tests.rs`, +//! it lives inside a submodule directory named `tests`. + +use crate::utils::shared_helpers::parse_value_from_args; #[test] fn test_parse_value_from_args() { From 62bb35ab5d99dc0b7d6cc77687b09e94ccd228c6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 29 Dec 2024 11:10:36 +0100 Subject: [PATCH 083/113] make -Csoft-float have an effect on all ARM targets --- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_session/src/session.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 45294ea35b16..ae5e818d86f1 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -189,7 +189,7 @@ pub(crate) fn target_machine_factory( let reloc_model = to_llvm_relocation_model(sess.relocation_model()); let (opt_level, _) = to_llvm_opt_settings(optlvl); - let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" { + let use_softfp = if sess.target.arch == "arm" { sess.opts.cg.soft_float } else { // `validate_commandline_args_with_session_available` has already warned about this being diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 54bb46229635..60f1154dc6d0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1320,7 +1320,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } if sess.opts.cg.soft_float { - if sess.target.arch == "arm" && sess.target.abi == "eabihf" { + if sess.target.arch == "arm" { sess.dcx().emit_warn(errors::SoftFloatDeprecated); } else { // All `use_softfp` does is the equivalent of `-mfloat-abi` in GCC/clang, which only exists on ARM targets. From 4f8bebd6b55e0a2986be81e50e3851a3ba973edf Mon Sep 17 00:00:00 2001 From: calciumbe <192480234+calciumbe@users.noreply.github.com> Date: Sun, 29 Dec 2024 18:03:37 +0800 Subject: [PATCH 084/113] fix: typos Signed-off-by: calciumbe <192480234+calciumbe@users.noreply.github.com> --- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- library/alloc/src/raw_vec.rs | 2 +- library/std/src/thread/current.rs | 2 +- src/doc/rustc/src/platform-support/android.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index aab4e1b1afc1..278cde5d560f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -755,7 +755,7 @@ impl<'a> Parser<'a> { // When there are a few keywords in the last ten elements of `self.expected_token_types` // and the current token is an identifier, it's probably a misspelled keyword. This handles // code like `async Move {}`, misspelled `if` in match guard, misspelled `else` in - // `if`-`else` and mispelled `where` in a where clause. + // `if`-`else` and misspelled `where` in a where clause. if !expected_keywords.is_empty() && !curr_ident.is_used_keyword() && let Some(misspelled_kw) = find_similar_kw(curr_ident, &expected_keywords) diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 2c7cdcf0cfb4..e93ff2f90237 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -420,7 +420,7 @@ impl RawVecInner { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { unsafe { - // Make it more obvious that a subsquent Vec::reserve(capacity) will not allocate. + // Make it more obvious that a subsequent Vec::reserve(capacity) will not allocate. hint::assert_unchecked(!this.needs_to_grow(0, capacity, elem_layout)); } this diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs index 1048ef973560..3d2c288b3608 100644 --- a/library/std/src/thread/current.rs +++ b/library/std/src/thread/current.rs @@ -136,7 +136,7 @@ pub(crate) fn set_current(thread: Thread) -> Result<(), Thread> { /// one thread and is guaranteed not to call the global allocator. #[inline] pub(crate) fn current_id() -> ThreadId { - // If accessing the persistant thread ID takes multiple TLS accesses, try + // If accessing the persistent thread ID takes multiple TLS accesses, try // to retrieve it from the current thread handle, which will only take one // TLS access. if !id::CHEAP { diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index 96499b0d8014..54e7ddca32aa 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -65,4 +65,4 @@ Currently the `riscv64-linux-android` target requires the following architecture ### aarch64-linux-android on Nightly compilers As soon as `-Zfixed-x18` compiler flag is supplied, the [`ShadowCallStack` sanitizer](https://releases.llvm.org/7.0.1/tools/clang/docs/ShadowCallStack.html) -instrumentation is also made avaiable by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`. +instrumentation is also made available by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`. From 0ebdc0c431789f10844fe548e111e48f643bc0be Mon Sep 17 00:00:00 2001 From: dxsullivan <193140725+dxsullivan@users.noreply.github.com> Date: Sun, 29 Dec 2024 21:51:30 +0800 Subject: [PATCH 085/113] docs: fix typos --- .../rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md | 2 +- src/doc/rustc/src/targets/custom.md | 4 ++-- .../rustdoc/src/write-documentation/documentation-tests.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index 1acc0584be91..b57083980d27 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -122,7 +122,7 @@ limactl shell riscv Using [Docker (with BuildKit)](https://docs.docker.com/build/buildkit/) the [`riscv64/ubuntu`](https://hub.docker.com/r/riscv64/ubuntu) image can be used -to buiild or run `riscv64gc-unknown-linux-gnu` binaries. +to build or run `riscv64gc-unknown-linux-gnu` binaries. ```bash docker run --platform linux/riscv64 -ti --rm --mount "type=bind,src=$(pwd),dst=/checkout" riscv64/ubuntu bash diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md index a332d24c9f1f..6c1494186a4e 100644 --- a/src/doc/rustc/src/targets/custom.md +++ b/src/doc/rustc/src/targets/custom.md @@ -21,10 +21,10 @@ To use a custom target, see the (unstable) [`build-std` feature](../../cargo/ref When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic: 1. if `TARGET` is the name of a built-in target, use that 2. if `TARGET` is a path to a file, read that file as a json target -3. otherwise, search the colon-seperated list of directories found +3. otherwise, search the colon-separated list of directories found in the `RUST_TARGET_PATH` environment variable from left to right for a file named `TARGET.json`. -These steps are tried in order, so if there are multple potentially valid +These steps are tried in order, so if there are multiple potentially valid interpretations for a target, whichever is found first will take priority. If none of these methods find a target, an error is thrown. diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md index e02c26bd42bd..b921f6778575 100644 --- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md +++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md @@ -412,7 +412,7 @@ In some cases, doctests cannot be merged. For example, if you have: ``` The problem with this code is that, if you change any other doctests, it'll likely break when -runing `rustdoc --test`, making it tricky to maintain. +running `rustdoc --test`, making it tricky to maintain. This is where the `standalone_crate` attribute comes in: it tells `rustdoc` that a doctest should not be merged with the others. So the previous code should use it: From dab1c57723d4ab53b9279801f6a27db94bdec98a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 29 Dec 2024 08:02:40 -0600 Subject: [PATCH 086/113] Added codegen test for elidings bounds check when indexes are manually checked Closes #55147 --- tests/codegen/slice-indexing.rs | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/codegen/slice-indexing.rs b/tests/codegen/slice-indexing.rs index 3d284148db22..75112bb0c24e 100644 --- a/tests/codegen/slice-indexing.rs +++ b/tests/codegen/slice-indexing.rs @@ -60,3 +60,40 @@ pub unsafe fn str_get_unchecked_mut_by_range(x: &mut str, r: Range) -> &m // CHECK: sub nuw i64 x.get_unchecked_mut(r) } + +// CHECK-LABEL: @slice_repeated_indexing( +#[no_mangle] +pub fn slice_repeated_indexing(dst: &mut [u8], offset: usize) { + let mut i = offset; + // CHECK: panic_bounds_check + dst[i] = 1; + i += 1; + // CHECK: panic_bounds_check + dst[i] = 2; + i += 1; + // CHECK: panic_bounds_check + dst[i] = 3; + i += 1; + // CHECK: panic_bounds_check + dst[i] = 4; +} + +// CHECK-LABEL: @slice_repeated_indexing_coalesced( +#[no_mangle] +pub fn slice_repeated_indexing_coalesced(dst: &mut [u8], offset: usize) { + let mut i = offset; + if i.checked_add(4).unwrap() <= dst.len() { + // CHECK-NOT: panic_bounds_check + dst[i] = 1; + i += 1; + // CHECK-NOT: panic_bounds_check + dst[i] = 2; + i += 1; + // CHECK-NOT: panic_bounds_check + dst[i] = 3; + i += 1; + // CHECK-NOT: panic_bounds_check + dst[i] = 4; + } + // CHECK: ret +} From 9007cb15e4cd5abece667f42ea89bc9ed45bc3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sun, 29 Dec 2024 18:02:14 +0100 Subject: [PATCH 087/113] Document how to run the split Docker pipelines --- src/ci/docker/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 2f35e6050262..508b7b40c01e 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -26,6 +26,12 @@ DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu while locally, to the `obj/$image_name` directory. This is primarily to prevent strange linker errors when using multiple Docker images. +For some Linux workflows (for example `x86_64-gnu-llvm-18-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-18-3` workflow, you can run the following script: + +``` +DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-18 +``` + ## Local Development Refer to the [dev guide](https://rustc-dev-guide.rust-lang.org/tests/docker.html) for more information on testing locally. From b235cc9e703c323a3ae01951980c776e916ea34e Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Wed, 25 Dec 2024 16:59:55 +0100 Subject: [PATCH 088/113] Document x86_64-unknown-linux-none is PIE by default --- .../rustc/src/platform-support/x86_64-unknown-linux-none.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md index 5608b5cb7781..965d6aea9318 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -14,6 +14,11 @@ This target is cross compiled and can be built from any host. This target has no support for host tools, std, or alloc. +One of the primary motivations of the target is to write a dynamic linker and libc in Rust. +For that, the target defaults to position-independent code and position-independent executables (PIE) by default. +PIE binaries need relocation at runtime. This is usually done by the dynamic linker or libc. +You can use `-Crelocation-model=static` to create a position-dependent binary that does not need relocation at runtime. + ## Building the target The target can be built by enabling it for a `rustc` build: From 42f28cbae675d890d50da86b7e1735f3e596c350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 22:09:44 +0000 Subject: [PATCH 089/113] introduce polonius context This context struct will hold data to help creating localized constraints: - the live regions, with the shape matching a CFG walk, indexed per point - the variance of these live regions, represented as the direction we'll add the appropriate We also add this structure to the mir typeck to record liveness data, and make it responsible for localized constraint creation. --- compiler/rustc_borrowck/src/nll.rs | 39 ++++---- compiler/rustc_borrowck/src/polonius/mod.rs | 89 +++++++++++++------ compiler/rustc_borrowck/src/type_check/mod.rs | 19 +++- 3 files changed, 102 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index abe27555b186..4428e6958447 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -100,19 +100,23 @@ pub(crate) fn compute_regions<'a, 'tcx>( let elements = Rc::new(DenseLocationMap::new(body)); // Run the MIR type-checker. - let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } = - type_check::type_check( - infcx, - body, - promoted, - universal_regions, - location_table, - borrow_set, - &mut all_facts, - flow_inits, - move_data, - Rc::clone(&elements), - ); + let MirTypeckResults { + constraints, + universal_region_relations, + opaque_type_values, + mut polonius_context, + } = type_check::type_check( + infcx, + body, + promoted, + universal_regions, + location_table, + borrow_set, + &mut all_facts, + flow_inits, + move_data, + Rc::clone(&elements), + ); // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the @@ -141,12 +145,9 @@ pub(crate) fn compute_regions<'a, 'tcx>( // If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives // constraints. - let localized_outlives_constraints = - if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { - Some(polonius::create_localized_constraints(&mut regioncx, body)) - } else { - None - }; + let localized_outlives_constraints = polonius_context + .as_mut() + .map(|polonius_context| polonius_context.create_localized_constraints(&mut regioncx, body)); // If requested: dump NLL facts, and run legacy polonius analysis. let polonius_output = all_facts.as_ref().and_then(|all_facts| { diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index eee5e70efe34..16487de09e2f 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -34,45 +34,84 @@ //! mod constraints; -pub(crate) use constraints::*; mod dump; -pub(crate) use dump::dump_polonius_mir; pub(crate) mod legacy; +use std::collections::BTreeMap; + +use rustc_index::bit_set::SparseBitMatrix; use rustc_middle::mir::{Body, Location}; +use rustc_middle::ty::RegionVid; use rustc_mir_dataflow::points::PointIndex; +pub(crate) use self::constraints::*; +pub(crate) use self::dump::dump_polonius_mir; use crate::RegionInferenceContext; use crate::constraints::OutlivesConstraint; use crate::region_infer::values::LivenessValues; use crate::type_check::Locations; use crate::universal_regions::UniversalRegions; -/// Creates a constraint set for `-Zpolonius=next` by: -/// - converting NLL typeck constraints to be localized -/// - encoding liveness constraints -pub(crate) fn create_localized_constraints<'tcx>( - regioncx: &mut RegionInferenceContext<'tcx>, - body: &Body<'tcx>, -) -> LocalizedOutlivesConstraintSet { - let mut localized_outlives_constraints = LocalizedOutlivesConstraintSet::default(); - convert_typeck_constraints( - body, - regioncx.liveness_constraints(), - regioncx.outlives_constraints(), - &mut localized_outlives_constraints, - ); - create_liveness_constraints( - body, - regioncx.liveness_constraints(), - regioncx.universal_regions(), - &mut localized_outlives_constraints, - ); +/// This struct holds the data needed to create the Polonius localized constraints. +pub(crate) struct PoloniusContext { + /// The set of regions that are live at a given point in the CFG, used to create localized + /// outlives constraints between regions that are live at connected points in the CFG. + live_regions: SparseBitMatrix, - // FIXME: here, we can trace loan reachability in the constraint graph and record this as loan - // liveness for the next step in the chain, the NLL loan scope and active loans computations. + /// The expected edge direction per live region: the kind of directed edge we'll create as + /// liveness constraints depends on the variance of types with respect to each contained region. + live_region_variances: BTreeMap, +} - localized_outlives_constraints +/// The direction a constraint can flow into. Used to create liveness constraints according to +/// variance. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum ConstraintDirection { + /// For covariant cases, we add a forward edge `O at P1 -> O at P2`. + Forward, + + /// For contravariant cases, we add a backward edge `O at P2 -> O at P1` + Backward, + + /// For invariant cases, we add both the forward and backward edges `O at P1 <-> O at P2`. + Bidirectional, +} + +impl PoloniusContext { + pub(crate) fn new(num_regions: usize) -> PoloniusContext { + Self { + live_region_variances: BTreeMap::new(), + live_regions: SparseBitMatrix::new(num_regions), + } + } + + /// Creates a constraint set for `-Zpolonius=next` by: + /// - converting NLL typeck constraints to be localized + /// - encoding liveness constraints + pub(crate) fn create_localized_constraints<'tcx>( + &self, + regioncx: &RegionInferenceContext<'tcx>, + body: &Body<'tcx>, + ) -> LocalizedOutlivesConstraintSet { + let mut localized_outlives_constraints = LocalizedOutlivesConstraintSet::default(); + convert_typeck_constraints( + body, + regioncx.liveness_constraints(), + regioncx.outlives_constraints(), + &mut localized_outlives_constraints, + ); + create_liveness_constraints( + body, + regioncx.liveness_constraints(), + regioncx.universal_regions(), + &mut localized_outlives_constraints, + ); + + // FIXME: here, we can trace loan reachability in the constraint graph and record this as loan + // liveness for the next step in the chain, the NLL loan scope and active loans computations. + + localized_outlives_constraints + } } /// Propagate loans throughout the subset graph at a given point (with some subtleties around the diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index f918f005a9b5..ea13e9b0fcfc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -50,6 +50,7 @@ use crate::diagnostics::UniverseInfo; use crate::facts::AllFacts; use crate::location::LocationTable; use crate::member_constraints::MemberConstraintSet; +use crate::polonius::PoloniusContext; use crate::region_infer::TypeTest; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; use crate::renumber::RegionCtxt; @@ -148,6 +149,13 @@ pub(crate) fn type_check<'a, 'tcx>( debug!(?normalized_inputs_and_output); + let mut polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { + let num_regions = infcx.num_region_vars(); + Some(PoloniusContext::new(num_regions)) + } else { + None + }; + let mut typeck = TypeChecker { infcx, last_span: body.span, @@ -162,6 +170,7 @@ pub(crate) fn type_check<'a, 'tcx>( all_facts, borrow_set, constraints: &mut constraints, + polonius_context: &mut polonius_context, }; typeck.check_user_type_annotations(); @@ -178,7 +187,12 @@ pub(crate) fn type_check<'a, 'tcx>( let opaque_type_values = opaque_types::take_opaques_and_register_member_constraints(&mut typeck); - MirTypeckResults { constraints, universal_region_relations, opaque_type_values } + MirTypeckResults { + constraints, + universal_region_relations, + opaque_type_values, + polonius_context, + } } #[track_caller] @@ -546,6 +560,8 @@ struct TypeChecker<'a, 'tcx> { all_facts: &'a mut Option, borrow_set: &'a BorrowSet<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + /// When using `-Zpolonius=next`, the helper data used to create polonius constraints. + polonius_context: &'a mut Option, } /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions @@ -554,6 +570,7 @@ pub(crate) struct MirTypeckResults<'tcx> { pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, pub(crate) universal_region_relations: Frozen>, pub(crate) opaque_type_values: FxIndexMap, OpaqueHiddenType<'tcx>>, + pub(crate) polonius_context: Option, } /// A collection of region constraints that must be satisfied for the From de049e6622b36d24a26e4c4cb6ad29ae97d3d631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 22:18:02 +0000 Subject: [PATCH 090/113] add variance recording Following the Generalizer's structure, relating e.g. a type with itself will allow tracking the variance wrt the contained regions. --- .../src/polonius/liveness_constraints.rs | 125 ++++++++++++++++++ compiler/rustc_borrowck/src/polonius/mod.rs | 1 + 2 files changed, 126 insertions(+) create mode 100644 compiler/rustc_borrowck/src/polonius/liveness_constraints.rs diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs new file mode 100644 index 000000000000..6ed133134631 --- /dev/null +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -0,0 +1,125 @@ +use std::collections::BTreeMap; + +use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable}; + +use super::{ConstraintDirection, PoloniusContext}; +use crate::universal_regions::UniversalRegions; + +impl PoloniusContext { + /// Record the variance of each region contained within the given value. + pub(crate) fn record_live_region_variance<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + universal_regions: &UniversalRegions<'tcx>, + value: impl TypeVisitable> + Relate>, + ) { + let mut extractor = VarianceExtractor { + tcx, + ambient_variance: ty::Variance::Covariant, + directions: &mut self.live_region_variances, + universal_regions, + }; + extractor.relate(value, value).expect("Can't have a type error relating to itself"); + } +} + +/// Extracts variances for regions contained within types. Follows the same structure as +/// `rustc_infer`'s `Generalizer`: we try to relate a type with itself to track and extract the +/// variances of regions. +struct VarianceExtractor<'a, 'tcx> { + tcx: TyCtxt<'tcx>, + ambient_variance: ty::Variance, + directions: &'a mut BTreeMap, + universal_regions: &'a UniversalRegions<'tcx>, +} + +impl<'tcx> VarianceExtractor<'_, 'tcx> { + fn record_variance(&mut self, region: ty::Region<'tcx>, variance: ty::Variance) { + // We're only interested in the variance of vars and free regions. + + if region.is_bound() || region.is_erased() { + // ignore these + return; + } + + let direction = match variance { + ty::Variance::Covariant => ConstraintDirection::Forward, + ty::Variance::Contravariant => ConstraintDirection::Backward, + ty::Variance::Invariant => ConstraintDirection::Bidirectional, + ty::Variance::Bivariant => { + // We don't add edges for bivariant cases. + return; + } + }; + + let region = self.universal_regions.to_region_vid(region); + self.directions + .entry(region) + .and_modify(|entry| { + // If there's already a recorded direction for this region, we combine the two: + // - combining the same direction is idempotent + // - combining different directions is trivially bidirectional + if entry != &direction { + *entry = ConstraintDirection::Bidirectional; + } + }) + .or_insert(direction); + } +} + +impl<'tcx> TypeRelation> for VarianceExtractor<'_, 'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn relate_with_variance>>( + &mut self, + variance: ty::Variance, + _info: ty::VarianceDiagInfo>, + a: T, + b: T, + ) -> RelateResult<'tcx, T> { + let old_ambient_variance = self.ambient_variance; + self.ambient_variance = self.ambient_variance.xform(variance); + let r = self.relate(a, b)?; + self.ambient_variance = old_ambient_variance; + Ok(r) + } + + fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { + assert_eq!(a, b); // we are misusing TypeRelation here; both LHS and RHS ought to be == + relate::structurally_relate_tys(self, a, b) + } + + fn regions( + &mut self, + a: ty::Region<'tcx>, + b: ty::Region<'tcx>, + ) -> RelateResult<'tcx, ty::Region<'tcx>> { + assert_eq!(a, b); // we are misusing TypeRelation here; both LHS and RHS ought to be == + self.record_variance(a, self.ambient_variance); + Ok(a) + } + + fn consts( + &mut self, + a: ty::Const<'tcx>, + b: ty::Const<'tcx>, + ) -> RelateResult<'tcx, ty::Const<'tcx>> { + assert_eq!(a, b); // we are misusing TypeRelation here; both LHS and RHS ought to be == + relate::structurally_relate_consts(self, a, b) + } + + fn binders( + &mut self, + a: ty::Binder<'tcx, T>, + _: ty::Binder<'tcx, T>, + ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> + where + T: Relate>, + { + self.relate(a.skip_binder(), a.skip_binder())?; + Ok(a) + } +} diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index 16487de09e2f..d86edd007253 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -36,6 +36,7 @@ mod constraints; mod dump; pub(crate) mod legacy; +mod liveness_constraints; use std::collections::BTreeMap; From d1cadf6292196dbe6840c3321b9073cf47269682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 22:19:44 +0000 Subject: [PATCH 091/113] record variance of use/drop live regions records the variance of: - use live types - drop live generic args --- .../src/type_check/liveness/trace.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index f510d193dd9f..2c658edc41cc 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::for_liveness; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; use rustc_middle::traits::query::DropckOutlivesResult; +use rustc_middle::ty::relate::Relate; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; @@ -532,11 +533,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { /// Stores the result that all regions in `value` are live for the /// points `live_at`. - fn add_use_live_facts_for( - &mut self, - value: impl TypeVisitable>, - live_at: &IntervalSet, - ) { + fn add_use_live_facts_for(&mut self, value: Ty<'tcx>, live_at: &IntervalSet) { debug!("add_use_live_facts_for(value={:?})", value); Self::make_all_regions_live(self.elements, self.typeck, value, live_at); } @@ -603,7 +600,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { fn make_all_regions_live( elements: &DenseLocationMap, typeck: &mut TypeChecker<'_, 'tcx>, - value: impl TypeVisitable>, + value: impl TypeVisitable> + Relate>, live_at: &IntervalSet, ) { debug!("make_all_regions_live(value={:?})", value); @@ -621,6 +618,15 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { typeck.constraints.liveness_constraints.add_points(live_region_vid, live_at); }, }); + + // When using `-Zpolonius=next`, we record the variance of each live region. + if let Some(polonius_context) = typeck.polonius_context { + polonius_context.record_live_region_variance( + typeck.infcx.tcx, + typeck.universal_regions, + value, + ); + } } fn compute_drop_data(typeck: &TypeChecker<'_, 'tcx>, dropped_ty: Ty<'tcx>) -> DropData<'tcx> { From 1bea7f9a446cf6a274e6b5f528ae20dd0b911b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 22:27:14 +0000 Subject: [PATCH 092/113] record variance of regular live regions --- .../src/type_check/liveness/mod.rs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 683293bf8286..3e9900cce5f5 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -3,6 +3,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::visit::{TyContext, Visitor}; use rustc_middle::mir::{Body, Local, Location, SourceInfo}; use rustc_middle::span_bug; +use rustc_middle::ty::relate::Relate; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{GenericArgsRef, Region, RegionVid, Ty, TyCtxt}; use rustc_mir_dataflow::ResultsCursor; @@ -13,6 +14,7 @@ use tracing::debug; use super::TypeChecker; use crate::constraints::OutlivesConstraintSet; +use crate::polonius::PoloniusContext; use crate::region_infer::values::LivenessValues; use crate::universal_regions::UniversalRegions; @@ -56,7 +58,13 @@ pub(super) fn generate<'a, 'tcx>( // Mark regions that should be live where they appear within rvalues or within a call: like // args, regions, and types. - record_regular_live_regions(typeck.tcx(), &mut typeck.constraints.liveness_constraints, body); + record_regular_live_regions( + typeck.tcx(), + &mut typeck.constraints.liveness_constraints, + &typeck.universal_regions, + &mut typeck.polonius_context, + body, + ); } // The purpose of `compute_relevant_live_locals` is to define the subset of `Local` @@ -130,9 +138,12 @@ fn regions_that_outlive_free_regions<'tcx>( fn record_regular_live_regions<'tcx>( tcx: TyCtxt<'tcx>, liveness_constraints: &mut LivenessValues, + universal_regions: &UniversalRegions<'tcx>, + polonius_context: &mut Option, body: &Body<'tcx>, ) { - let mut visitor = LiveVariablesVisitor { tcx, liveness_constraints }; + let mut visitor = + LiveVariablesVisitor { tcx, liveness_constraints, universal_regions, polonius_context }; for (bb, data) in body.basic_blocks.iter_enumerated() { visitor.visit_basic_block_data(bb, data); } @@ -142,6 +153,8 @@ fn record_regular_live_regions<'tcx>( struct LiveVariablesVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, liveness_constraints: &'a mut LivenessValues, + universal_regions: &'a UniversalRegions<'tcx>, + polonius_context: &'a mut Option, } impl<'a, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'a, 'tcx> { @@ -184,12 +197,17 @@ impl<'a, 'tcx> LiveVariablesVisitor<'a, 'tcx> { /// all regions appearing in the type of `value` must be live at `location`. fn record_regions_live_at(&mut self, value: T, location: Location) where - T: TypeVisitable>, + T: TypeVisitable> + Relate>, { debug!("record_regions_live_at(value={:?}, location={:?})", value, location); self.tcx.for_each_free_region(&value, |live_region| { let live_region_vid = live_region.as_var(); self.liveness_constraints.add_location(live_region_vid, location); }); + + // When using `-Zpolonius=next`, we record the variance of each live region. + if let Some(polonius_context) = self.polonius_context { + polonius_context.record_live_region_variance(self.tcx, self.universal_regions, value); + } } } From cbdac2f0e9da7c1b379bed6da49bde43feb3eed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 23:18:40 +0000 Subject: [PATCH 093/113] improve `bit_set` assertion it missed the index and bounds info --- compiler/rustc_index/src/bit_set.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 664b77fd49eb..38e2dbbde7d0 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -179,7 +179,12 @@ impl BitSet { /// Insert `elem`. Returns whether the set has changed. #[inline] pub fn insert(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); + assert!( + elem.index() < self.domain_size, + "inserting element at index {} but domain size is {}", + elem.index(), + self.domain_size, + ); let (word_index, mask) = word_index_and_mask(elem); let word_ref = &mut self.words[word_index]; let word = *word_ref; From 6e88db90c2a73d6d63dae15886f59bc613b23d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 23:25:19 +0000 Subject: [PATCH 094/113] finish filling polonius context transpose liveness matrix and record live regions at the end of MIR typeck --- .../src/polonius/liveness_constraints.rs | 22 +++++++++++++++++++ compiler/rustc_borrowck/src/polonius/mod.rs | 9 +++----- .../rustc_borrowck/src/region_infer/values.rs | 8 +++++++ compiler/rustc_borrowck/src/type_check/mod.rs | 9 ++++++-- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs index 6ed133134631..804a166014f0 100644 --- a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -1,7 +1,10 @@ use std::collections::BTreeMap; +use rustc_index::bit_set::SparseBitMatrix; +use rustc_index::interval::SparseIntervalMatrix; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable}; +use rustc_mir_dataflow::points::PointIndex; use super::{ConstraintDirection, PoloniusContext}; use crate::universal_regions::UniversalRegions; @@ -22,6 +25,25 @@ impl PoloniusContext { }; extractor.relate(value, value).expect("Can't have a type error relating to itself"); } + + /// Unlike NLLs, in polonius we traverse the cfg to look for regions live across an edge, so we + /// need to transpose the "points where each region is live" matrix to a "live regions per point" + /// matrix. + // FIXME: avoid this conversion by always storing liveness data in this shape in the rest of + // borrowck. + pub(crate) fn record_live_regions_per_point( + &mut self, + num_regions: usize, + points_per_live_region: &SparseIntervalMatrix, + ) { + let mut live_regions_per_point = SparseBitMatrix::new(num_regions); + for region in points_per_live_region.rows() { + for point in points_per_live_region.row(region).unwrap().iter() { + live_regions_per_point.insert(point, region); + } + } + self.live_regions = Some(live_regions_per_point); + } } /// Extracts variances for regions contained within types. Follows the same structure as diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index d86edd007253..5a95ac758fd9 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -57,7 +57,7 @@ use crate::universal_regions::UniversalRegions; pub(crate) struct PoloniusContext { /// The set of regions that are live at a given point in the CFG, used to create localized /// outlives constraints between regions that are live at connected points in the CFG. - live_regions: SparseBitMatrix, + live_regions: Option>, /// The expected edge direction per live region: the kind of directed edge we'll create as /// liveness constraints depends on the variance of types with respect to each contained region. @@ -79,11 +79,8 @@ enum ConstraintDirection { } impl PoloniusContext { - pub(crate) fn new(num_regions: usize) -> PoloniusContext { - Self { - live_region_variances: BTreeMap::new(), - live_regions: SparseBitMatrix::new(num_regions), - } + pub(crate) fn new() -> PoloniusContext { + Self { live_region_variances: BTreeMap::new(), live_regions: None } } /// Creates a constraint set for `-Zpolonius=next` by: diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 0b0757f16ab2..e567f3a8b0de 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -99,6 +99,14 @@ impl LivenessValues { } } + /// Returns the liveness matrix of points where each region is live. Panics if the liveness + /// values have been created without any per-point data (that is, for promoteds). + pub(crate) fn points(&self) -> &SparseIntervalMatrix { + self.points + .as_ref() + .expect("this `LivenessValues` wasn't created using `with_specific_points`") + } + /// Iterate through each region that has a value in this set. pub(crate) fn regions(&self) -> impl Iterator + '_ { self.points.as_ref().expect("use with_specific_points").rows() diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index ea13e9b0fcfc..3968900d0471 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -150,8 +150,7 @@ pub(crate) fn type_check<'a, 'tcx>( debug!(?normalized_inputs_and_output); let mut polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { - let num_regions = infcx.num_region_vars(); - Some(PoloniusContext::new(num_regions)) + Some(PoloniusContext::new()) } else { None }; @@ -187,6 +186,12 @@ pub(crate) fn type_check<'a, 'tcx>( let opaque_type_values = opaque_types::take_opaques_and_register_member_constraints(&mut typeck); + if let Some(polonius_context) = typeck.polonius_context.as_mut() { + let num_regions = infcx.num_region_vars(); + let points_per_live_region = typeck.constraints.liveness_constraints.points(); + polonius_context.record_live_regions_per_point(num_regions, points_per_live_region); + } + MirTypeckResults { constraints, universal_region_relations, From 93527d25ddabbb1c241c3c9eb566cb43081e3d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 22 Dec 2024 23:32:15 +0000 Subject: [PATCH 095/113] liveness constraints: draw the rest of the owl --- .../src/polonius/liveness_constraints.rs | 174 +++++++++++++++++- compiler/rustc_borrowck/src/polonius/mod.rs | 77 +------- 2 files changed, 180 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs index 804a166014f0..950fef272869 100644 --- a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -2,11 +2,16 @@ use std::collections::BTreeMap; use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::SparseIntervalMatrix; +use rustc_middle::mir::{Body, Location}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeVisitable}; use rustc_mir_dataflow::points::PointIndex; -use super::{ConstraintDirection, PoloniusContext}; +use super::{ + ConstraintDirection, LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet, + PoloniusContext, +}; +use crate::region_infer::values::LivenessValues; use crate::universal_regions::UniversalRegions; impl PoloniusContext { @@ -46,6 +51,173 @@ impl PoloniusContext { } } +/// Propagate loans throughout the CFG: for each statement in the MIR, create localized outlives +/// constraints for loans that are propagated to the next statements. +pub(super) fn create_liveness_constraints<'tcx>( + body: &Body<'tcx>, + liveness: &LivenessValues, + live_regions: &SparseBitMatrix, + live_region_variances: &BTreeMap, + universal_regions: &UniversalRegions<'tcx>, + localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, +) { + for (block, bb) in body.basic_blocks.iter_enumerated() { + let statement_count = bb.statements.len(); + for statement_index in 0..=statement_count { + let current_location = Location { block, statement_index }; + let current_point = liveness.point_from_location(current_location); + + if statement_index < statement_count { + // Intra-block edges, straight line constraints from each point to its successor + // within the same block. + let next_location = Location { block, statement_index: statement_index + 1 }; + let next_point = liveness.point_from_location(next_location); + propagate_loans_between_points( + current_point, + next_point, + live_regions, + live_region_variances, + universal_regions, + localized_outlives_constraints, + ); + } else { + // Inter-block edges, from the block's terminator to each successor block's entry + // point. + for successor_block in bb.terminator().successors() { + let next_location = Location { block: successor_block, statement_index: 0 }; + let next_point = liveness.point_from_location(next_location); + propagate_loans_between_points( + current_point, + next_point, + live_regions, + live_region_variances, + universal_regions, + localized_outlives_constraints, + ); + } + } + } + } +} + +/// Propagate loans within a region between two points in the CFG, if that region is live at both +/// the source and target points. +fn propagate_loans_between_points( + current_point: PointIndex, + next_point: PointIndex, + live_regions: &SparseBitMatrix, + live_region_variances: &BTreeMap, + universal_regions: &UniversalRegions<'_>, + localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, +) { + // Universal regions are semantically live at all points. + // Note: we always have universal regions but they're not always (or often) involved in the + // subset graph. For now, we emit all their edges unconditionally, but some of these subgraphs + // will be disconnected from the rest of the graph and thus, unnecessary. + // + // FIXME: only emit the edges of universal regions that existential regions can reach. + for region in universal_regions.universal_regions_iter() { + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: current_point, + target: region, + to: next_point, + }); + } + + let Some(current_live_regions) = live_regions.row(current_point) else { + // There are no constraints to add: there are no live regions at the current point. + return; + }; + let Some(next_live_regions) = live_regions.row(next_point) else { + // There are no constraints to add: there are no live regions at the next point. + return; + }; + + for region in next_live_regions.iter() { + if !current_live_regions.contains(region) { + continue; + } + + // `region` is indeed live at both points, add a constraint between them, according to + // variance. + if let Some(&direction) = live_region_variances.get(®ion) { + add_liveness_constraint( + region, + current_point, + next_point, + direction, + localized_outlives_constraints, + ); + } else { + // Note: there currently are cases related to promoted and const generics, where we + // don't yet have variance information (possibly about temporary regions created when + // typeck sanitizes the promoteds). Until that is done, we conservatively fallback to + // maximizing reachability by adding a bidirectional edge here. This will not limit + // traversal whatsoever, and thus propagate liveness when needed. + // + // FIXME: add the missing variance information and remove this fallback bidirectional + // edge. + let fallback = ConstraintDirection::Bidirectional; + add_liveness_constraint( + region, + current_point, + next_point, + fallback, + localized_outlives_constraints, + ); + } + } +} + +/// Adds `LocalizedOutlivesConstraint`s between two connected points, according to the given edge +/// direction. +fn add_liveness_constraint( + region: RegionVid, + current_point: PointIndex, + next_point: PointIndex, + direction: ConstraintDirection, + localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, +) { + match direction { + ConstraintDirection::Forward => { + // Covariant cases: loans flow in the regular direction, from the current point to the + // next point. + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: current_point, + target: region, + to: next_point, + }); + } + ConstraintDirection::Backward => { + // Contravariant cases: loans flow in the inverse direction, from the next point to the + // current point. + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: next_point, + target: region, + to: current_point, + }); + } + ConstraintDirection::Bidirectional => { + // For invariant cases, loans can flow in both directions: we add both edges. + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: current_point, + target: region, + to: next_point, + }); + localized_outlives_constraints.push(LocalizedOutlivesConstraint { + source: region, + from: next_point, + target: region, + to: current_point, + }); + } + } +} + /// Extracts variances for regions contained within types. Follows the same structure as /// `rustc_infer`'s `Generalizer`: we try to relate a type with itself to track and extract the /// variances of regions. diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index 5a95ac758fd9..a853ff266a11 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -47,11 +47,11 @@ use rustc_mir_dataflow::points::PointIndex; pub(crate) use self::constraints::*; pub(crate) use self::dump::dump_polonius_mir; +use self::liveness_constraints::create_liveness_constraints; use crate::RegionInferenceContext; use crate::constraints::OutlivesConstraint; use crate::region_infer::values::LivenessValues; use crate::type_check::Locations; -use crate::universal_regions::UniversalRegions; /// This struct holds the data needed to create the Polonius localized constraints. pub(crate) struct PoloniusContext { @@ -98,9 +98,15 @@ impl PoloniusContext { regioncx.outlives_constraints(), &mut localized_outlives_constraints, ); + + let live_regions = self.live_regions.as_ref().expect( + "live regions per-point data should have been created at the end of MIR typeck", + ); create_liveness_constraints( body, regioncx.liveness_constraints(), + live_regions, + &self.live_region_variances, regioncx.universal_regions(), &mut localized_outlives_constraints, ); @@ -146,72 +152,3 @@ fn convert_typeck_constraints<'tcx>( } } } - -/// Propagate loans throughout the CFG: for each statement in the MIR, create localized outlives -/// constraints for loans that are propagated to the next statements. -pub(crate) fn create_liveness_constraints<'tcx>( - body: &Body<'tcx>, - liveness: &LivenessValues, - universal_regions: &UniversalRegions<'tcx>, - localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, -) { - for (block, bb) in body.basic_blocks.iter_enumerated() { - let statement_count = bb.statements.len(); - for statement_index in 0..=statement_count { - let current_location = Location { block, statement_index }; - let current_point = liveness.point_from_location(current_location); - - if statement_index < statement_count { - // Intra-block edges, straight line constraints from each point to its successor - // within the same block. - let next_location = Location { block, statement_index: statement_index + 1 }; - let next_point = liveness.point_from_location(next_location); - propagate_loans_between_points( - current_point, - next_point, - liveness, - universal_regions, - localized_outlives_constraints, - ); - } else { - // Inter-block edges, from the block's terminator to each successor block's entry - // point. - for successor_block in bb.terminator().successors() { - let next_location = Location { block: successor_block, statement_index: 0 }; - let next_point = liveness.point_from_location(next_location); - propagate_loans_between_points( - current_point, - next_point, - liveness, - universal_regions, - localized_outlives_constraints, - ); - } - } - } - } -} - -/// Propagate loans within a region between two points in the CFG, if that region is live at both -/// the source and target points. -fn propagate_loans_between_points( - current_point: PointIndex, - next_point: PointIndex, - _liveness: &LivenessValues, - universal_regions: &UniversalRegions<'_>, - localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet, -) { - // Universal regions are semantically live at all points. - // Note: we always have universal regions but they're not always (or often) involved in the - // subset graph. For now, we emit all their edges unconditionally, but some of these subgraphs - // will be disconnected from the rest of the graph and thus, unnecessary. - // FIXME: only emit the edges of universal regions that existential regions can reach. - for region in universal_regions.universal_regions_iter() { - localized_outlives_constraints.push(LocalizedOutlivesConstraint { - source: region, - from: current_point, - target: region, - to: next_point, - }); - } -} From 089c525df2410d3d2a99767c0fc93689a4432fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 29 Dec 2024 17:58:36 +0000 Subject: [PATCH 096/113] address review comments - add a FIXME when looking for the region variance of unexpected regions - drive-by: fix a doc comment link - drive-by: simplify the variance match using exported variants instead --- .../src/polonius/liveness_constraints.rs | 29 +++++++++++++++---- .../rustc_borrowck/src/universal_regions.rs | 2 +- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs index 950fef272869..75ee29c9d0d5 100644 --- a/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/liveness_constraints.rs @@ -231,17 +231,34 @@ struct VarianceExtractor<'a, 'tcx> { impl<'tcx> VarianceExtractor<'_, 'tcx> { fn record_variance(&mut self, region: ty::Region<'tcx>, variance: ty::Variance) { // We're only interested in the variance of vars and free regions. + // + // Note: even if we currently bail for two cases of unexpected region kinds here, missing + // variance data is not a soundness problem: the regions with missing variance will still be + // present in the constraint graph as they are live, and liveness edges construction has a + // fallback for this case. + // + // FIXME: that being said, we need to investigate these cases better to not ignore regions + // in general. + if region.is_bound() { + // We ignore these because they cannot be turned into the vids we need. + return; + } - if region.is_bound() || region.is_erased() { - // ignore these + if region.is_erased() { + // These cannot be turned into a vid either, and we also ignore them: the fact that they + // show up here looks like either an issue upstream or a combination with unexpectedly + // continuing compilation too far when we're in a tainted by errors situation. + // + // FIXME: investigate the `generic_const_exprs` test that triggers this issue, + // `ui/const-generics/generic_const_exprs/issue-97047-ice-2.rs` return; } let direction = match variance { - ty::Variance::Covariant => ConstraintDirection::Forward, - ty::Variance::Contravariant => ConstraintDirection::Backward, - ty::Variance::Invariant => ConstraintDirection::Bidirectional, - ty::Variance::Bivariant => { + ty::Covariant => ConstraintDirection::Forward, + ty::Contravariant => ConstraintDirection::Backward, + ty::Invariant => ConstraintDirection::Bidirectional, + ty::Bivariant => { // We don't add edges for bivariant cases. return; } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 1ac45cbea38f..3dc4569c57b9 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -337,7 +337,7 @@ impl<'tcx> UniversalRegions<'tcx> { self.indices.indices.iter().map(|(&r, &v)| (r, v)) } - /// See `UniversalRegionIndices::to_region_vid`. + /// See [UniversalRegionIndices::to_region_vid]. pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { self.indices.to_region_vid(r) } From 586a805d84630e068b77774f296f14cb29f69aff Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Sun, 29 Dec 2024 21:27:19 +0100 Subject: [PATCH 097/113] review fixes: Adjust whitespace --- compiler/rustc_codegen_ssa/src/back/archive.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index dc8774ff477d..58eb137c0687 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -493,6 +493,7 @@ impl<'a> ArArchiveBuilder<'a> { perms: 0o644, }) } + // Write to a temporary file first before atomically renaming to the final name. // This prevents programs (including rustc) from attempting to read a partial archive. // It also enables writing an archive with the same filename as a dependency on Windows as @@ -510,6 +511,7 @@ impl<'a> ArArchiveBuilder<'a> { let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a"); let archive_tmpfile = File::create_new(&archive_tmpfile_path) .map_err(|err| io_error_context("couldn't create the temp file", err))?; + let mut archive_tmpfile = BufWriter::new(archive_tmpfile); write_archive_to_stream( &mut archive_tmpfile, @@ -520,6 +522,7 @@ impl<'a> ArArchiveBuilder<'a> { )?; archive_tmpfile.flush()?; drop(archive_tmpfile); + let any_entries = !entries.is_empty(); drop(entries); // Drop src_archives to unmap all input archives, which is necessary if we want to write the From f4d215ea91e233d5208d687548222183d4d279d8 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 28 Dec 2024 23:28:41 +0000 Subject: [PATCH 098/113] Add tidy check for list of proc-macro crate transitive dependencies --- Cargo.lock | 28 ++++++-- src/bootstrap/src/utils/proc_macro_deps.rs | 71 ++++++++++++++++++++ src/tools/tidy/Cargo.toml | 2 +- src/tools/tidy/src/deps.rs | 75 +++++++++++++++++++++- src/tools/tidy/src/main.rs | 2 +- 5 files changed, 167 insertions(+), 11 deletions(-) create mode 100644 src/bootstrap/src/utils/proc_macro_deps.rs diff --git a/Cargo.lock b/Cargo.lock index eeb3c99a294a..8009451fcede 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,7 +367,7 @@ dependencies = [ name = "cargo-miri" version = "0.1.0" dependencies = [ - "cargo_metadata", + "cargo_metadata 0.18.1", "directories", "rustc-build-sysroot", "rustc_tools_util", @@ -399,6 +399,20 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cargo_metadata" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.9", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -533,7 +547,7 @@ name = "clippy" version = "0.1.85" dependencies = [ "anstream", - "cargo_metadata", + "cargo_metadata 0.18.1", "clippy_config", "clippy_lints", "clippy_utils", @@ -589,7 +603,7 @@ name = "clippy_lints" version = "0.1.85" dependencies = [ "arrayvec", - "cargo_metadata", + "cargo_metadata 0.18.1", "clippy_config", "clippy_utils", "itertools", @@ -1389,7 +1403,7 @@ name = "generate-copyright" version = "0.1.0" dependencies = [ "anyhow", - "cargo_metadata", + "cargo_metadata 0.18.1", "rinja", "serde", "serde_json", @@ -4750,7 +4764,7 @@ dependencies = [ "annotate-snippets 0.9.2", "anyhow", "bytecount", - "cargo_metadata", + "cargo_metadata 0.18.1", "clap", "clap-cargo", "diff", @@ -5344,7 +5358,7 @@ name = "tidy" version = "0.1.0" dependencies = [ "build_helper", - "cargo_metadata", + "cargo_metadata 0.19.1", "fluent-syntax", "ignore", "miropt-test-tools", @@ -5622,7 +5636,7 @@ dependencies = [ "anyhow", "bstr", "cargo-platform", - "cargo_metadata", + "cargo_metadata 0.18.1", "color-eyre", "colored", "comma", diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs new file mode 100644 index 000000000000..dbfd6f47dc67 --- /dev/null +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -0,0 +1,71 @@ +/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start + "annotate-snippets", + "anstyle", + "basic-toml", + "block-buffer", + "bumpalo", + "cfg-if", + "cpufeatures", + "crypto-common", + "darling", + "darling_core", + "derive_builder_core", + "digest", + "fluent-bundle", + "fluent-langneg", + "fluent-syntax", + "fnv", + "generic-array", + "heck", + "ident_case", + "intl-memoizer", + "intl_pluralrules", + "libc", + "log", + "memchr", + "mime", + "mime_guess", + "minimal-lexical", + "nom", + "num-conv", + "once_cell", + "pest", + "pest_generator", + "pest_meta", + "proc-macro2", + "quote", + "rinja_parser", + "rustc-hash", + "self_cell", + "serde", + "sha2", + "smallvec", + "stable_deref_trait", + "strsim", + "syn", + "synstructure", + "thiserror", + "time-core", + "tinystr", + "type-map", + "typenum", + "ucd-trie", + "unic-langid", + "unic-langid-impl", + "unic-langid-macros", + "unicase", + "unicode-ident", + "unicode-width", + "version_check", + "wasm-bindgen-backend", + "wasm-bindgen-macro-support", + "wasm-bindgen-shared", + "yoke", + "zerofrom", + "zerovec", + // tidy-alphabetical-end +]; diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index bc75787fb1ab..2f424a482b5b 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -6,7 +6,7 @@ autobins = false [dependencies] build_helper = { path = "../../build_helper" } -cargo_metadata = "0.18" +cargo_metadata = "0.19" regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } walkdir = "2" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index beeb33b46ff2..1794d0fbca78 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,12 +1,16 @@ //! Checks the licenses of third-party dependencies. use std::collections::HashSet; -use std::fs::read_dir; +use std::fs::{File, read_dir}; +use std::io::Write; use std::path::Path; use build_helper::ci::CiEnv; use cargo_metadata::{Metadata, Package, PackageId}; +#[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] +mod proc_macro_deps; + /// These are licenses that are allowed for all crates, including the runtime, /// rustc, tools, etc. #[rustfmt::skip] @@ -564,9 +568,11 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path /// to the cargo executable. -pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { +pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { let mut checked_runtime_licenses = false; + check_proc_macro_dep_list(root, cargo, bless, bad); + for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES { if has_missing_submodule(root, submodules) { continue; @@ -600,6 +606,71 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { assert!(checked_runtime_licenses); } +/// Ensure the list of proc-macro crate transitive dependencies is up to date +fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(cargo) + .manifest_path(root.join("Cargo.toml")) + .features(cargo_metadata::CargoOpt::AllFeatures) + .other_options(vec!["--locked".to_owned()]); + let metadata = t!(cmd.exec()); + let is_proc_macro_pkg = |pkg: &Package| pkg.targets.iter().any(|target| target.is_proc_macro()); + + let mut proc_macro_deps = HashSet::new(); + for pkg in metadata.packages.iter().filter(|pkg| is_proc_macro_pkg(*pkg)) { + deps_of(&metadata, &pkg.id, &mut proc_macro_deps); + } + // Remove the proc-macro crates themselves + proc_macro_deps.retain(|pkg| !is_proc_macro_pkg(&metadata[pkg])); + let proc_macro_deps_iter = proc_macro_deps.into_iter().map(|dep| metadata[dep].name.clone()); + + if bless { + let mut proc_macro_deps: Vec<_> = proc_macro_deps_iter.collect(); + proc_macro_deps.sort(); + proc_macro_deps.dedup(); + let mut file = File::create(root.join("src/bootstrap/src/utils/proc_macro_deps.rs")) + .expect("`proc_macro_deps` should exist"); + writeln!( + &mut file, + "/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start" + ) + .unwrap(); + for dep in proc_macro_deps { + writeln!(&mut file, " {dep:?},").unwrap(); + } + writeln!( + &mut file, + " // tidy-alphabetical-end +];" + ) + .unwrap(); + } else { + let proc_macro_deps: HashSet<_> = proc_macro_deps_iter.collect(); + let expected = + proc_macro_deps::CRATES.iter().map(|s| s.to_string()).collect::>(); + let old_bad = *bad; + for missing in proc_macro_deps.difference(&expected) { + tidy_error!( + bad, + "proc-macro crate dependency `{missing}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`", + ); + } + for extra in expected.difference(&proc_macro_deps) { + tidy_error!( + bad, + "`{extra}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", + ); + } + if *bad != old_bad { + eprintln!("Run `./x.py test tidy --bless` to regenerate the list"); + } + } +} + /// Used to skip a check if a submodule is not checked out, and not in a CI environment. /// /// This helps prevent enforcing developers to fetch submodules for tidy. diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 40608952c0b7..13a558fea48e 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -95,7 +95,7 @@ fn main() { check!(target_specific_tests, &tests_path); // Checks that are done on the cargo workspace. - check!(deps, &root_path, &cargo); + check!(deps, &root_path, &cargo, bless); check!(extdeps, &root_path); // Checks over tests. From f0734626cd177b7719b9b1d13edff2c9bab4b341 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 28 Dec 2024 23:31:16 +0000 Subject: [PATCH 099/113] bootstrap: Don't apply `-Ztls-model=initial-exec` to deps of proc-macros --- src/bootstrap/src/bin/rustc.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 88595ff7e519..610450675928 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -28,6 +28,9 @@ use shared_helpers::{ #[path = "../utils/shared_helpers.rs"] mod shared_helpers; +#[path = "../utils/proc_macro_deps.rs"] +mod proc_macro_deps; + fn main() { let orig_args = env::args_os().skip(1).collect::>(); let mut args = orig_args.clone(); @@ -167,7 +170,7 @@ fn main() { // issue https://github.com/rust-lang/rust/issues/100530 if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() && crate_type != Some("proc-macro") - && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) + && proc_macro_deps::CRATES.binary_search(&crate_name.unwrap_or_default()).is_err() { cmd.arg("-Ztls-model=initial-exec"); } From b0fc1d47d5dcffb5d516059d4a5af3b6843132d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 29 Dec 2024 23:14:22 +0000 Subject: [PATCH 100/113] fix a couple nits - remove unneeded type ascription - fix variable name - fix typo in comment - fix `var_origins` var and function name: these are `VarInfos` --- compiler/rustc_borrowck/src/lib.rs | 7 +++---- compiler/rustc_borrowck/src/nll.rs | 4 ++-- compiler/rustc_infer/src/infer/mod.rs | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8b968177c3c0..e99c7e033134 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -120,11 +120,10 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { return tcx.arena.alloc(result); } - let promoted: &IndexSlice<_, _> = &promoted.borrow(); - let opt_closure_req = do_mir_borrowck(tcx, input_body, promoted, None).0; + let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0; debug!("mir_borrowck done"); - tcx.arena.alloc(opt_closure_req) + tcx.arena.alloc(borrowck_result) } /// Perform the actual borrow checking. @@ -215,7 +214,7 @@ fn do_mir_borrowck<'tcx>( consumer_options, ); - // Dump MIR results into a file, if that is enabled. This let us + // Dump MIR results into a file, if that is enabled. This lets us // write unit-tests, as well as helping with debugging. nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set); diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 4428e6958447..5113ca063c6b 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -121,7 +121,7 @@ pub(crate) fn compute_regions<'a, 'tcx>( // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. - let var_origins = infcx.get_region_var_origins(); + let var_infos = infcx.get_region_var_infos(); // If requested, emit legacy polonius facts. polonius::legacy::emit_facts( @@ -137,7 +137,7 @@ pub(crate) fn compute_regions<'a, 'tcx>( let mut regioncx = RegionInferenceContext::new( infcx, - var_origins, + var_infos, constraints, universal_region_relations, elements, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c5a56005c063..1f7180fb80a0 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -945,7 +945,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Clone the list of variable regions. This is used only during NLL processing /// to put the set of region variables into the NLL region context. - pub fn get_region_var_origins(&self) -> VarInfos { + pub fn get_region_var_infos(&self) -> VarInfos { let inner = self.inner.borrow(); assert!(!UndoLogs::>::in_snapshot(&inner.undo_log)); let storage = inner.region_constraint_storage.as_ref().expect("regions already resolved"); From 50c152f34766b8624e18dbec2f3b3366456a79c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 29 Dec 2024 23:42:45 +0000 Subject: [PATCH 101/113] move `location` module to polonius legacy module this is specific to the old datalog implementation and wasn't noticed in the previous module move --- compiler/rustc_borrowck/src/consumers.rs | 2 +- compiler/rustc_borrowck/src/facts.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 3 +-- compiler/rustc_borrowck/src/nll.rs | 2 +- compiler/rustc_borrowck/src/polonius/legacy/accesses.rs | 2 +- .../rustc_borrowck/src/polonius/legacy/loan_invalidations.rs | 2 +- compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs | 2 +- compiler/rustc_borrowck/src/{ => polonius/legacy}/location.rs | 0 compiler/rustc_borrowck/src/polonius/legacy/mod.rs | 3 ++- compiler/rustc_borrowck/src/type_check/liveness/trace.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) rename compiler/rustc_borrowck/src/{ => polonius/legacy}/location.rs (100%) diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 74de766ba231..90ca4f7518c1 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -9,10 +9,10 @@ pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; pub use super::constraints::OutlivesConstraint; pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location}; pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts}; -pub use super::location::{LocationTable, RichLocation}; pub use super::nll::PoloniusOutput; pub use super::place_ext::PlaceExt; pub use super::places_conflict::{PlaceConflictBias, places_conflict}; +pub use super::polonius::legacy::{LocationTable, RichLocation}; pub use super::region_infer::RegionInferenceContext; /// Options determining the output behavior of [`get_body_with_borrowck_facts`]. diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index ef8e757a5478..8181616d4cfd 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::move_paths::MovePathIndex; use crate::BorrowIndex; -use crate::location::{LocationIndex, LocationTable}; +use crate::polonius::legacy::{LocationIndex, LocationTable}; #[derive(Copy, Clone, Debug)] pub struct RustcFacts; diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index e99c7e033134..a23348116d2d 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -53,11 +53,11 @@ use crate::borrow_set::{BorrowData, BorrowSet}; use crate::consumers::{BodyWithBorrowckFacts, ConsumerOptions}; use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows}; use crate::diagnostics::{AccessKind, IllegalMoveOriginKind, MoveError, RegionName}; -use crate::location::LocationTable; use crate::nll::PoloniusOutput; use crate::path_utils::*; use crate::place_ext::PlaceExt; use crate::places_conflict::{PlaceConflictBias, places_conflict}; +use crate::polonius::legacy::LocationTable; use crate::prefixes::PrefixSet; use crate::region_infer::RegionInferenceContext; use crate::renumber::RegionCtxt; @@ -70,7 +70,6 @@ mod dataflow; mod def_use; mod diagnostics; mod facts; -mod location; mod member_constraints; mod nll; mod path_utils; diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 5113ca063c6b..c75d92cd48ea 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -28,8 +28,8 @@ use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; use crate::diagnostics::RegionErrors; use crate::facts::{AllFacts, AllFactsExt, RustcFacts}; -use crate::location::LocationTable; use crate::polonius::LocalizedOutlivesConstraintSet; +use crate::polonius::legacy::LocationTable; use crate::region_infer::RegionInferenceContext; use crate::type_check::{self, MirTypeckResults}; use crate::universal_regions::UniversalRegions; diff --git a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs index 9c4aa8ea1edb..cc414b854a2a 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs @@ -4,9 +4,9 @@ use rustc_middle::ty::TyCtxt; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData}; use tracing::debug; +use super::{LocationIndex, LocationTable}; use crate::def_use::{self, DefUse}; use crate::facts::AllFacts; -use crate::location::{LocationIndex, LocationTable}; use crate::universal_regions::UniversalRegions; /// Emit polonius facts for variable defs, uses, drops, and path accesses. diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 178f70a67304..5e8a1bfe13ea 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -9,9 +9,9 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use tracing::debug; +use super::LocationTable; use crate::borrow_set::BorrowSet; use crate::facts::AllFacts; -use crate::location::LocationTable; use crate::path_utils::*; use crate::{ AccessDepth, Activation, ArtificialField, BorrowIndex, Deep, LocalMutationIsAllowed, Read, diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs index fdde9fa04762..55b06bc6b774 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs @@ -6,9 +6,9 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use tracing::debug; +use super::LocationTable; use crate::borrow_set::BorrowSet; use crate::facts::AllFacts; -use crate::location::LocationTable; use crate::places_conflict; /// Emit `loan_killed_at` and `cfg_edge` facts at the same time. diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/polonius/legacy/location.rs similarity index 100% rename from compiler/rustc_borrowck/src/location.rs rename to compiler/rustc_borrowck/src/polonius/legacy/location.rs diff --git a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs index 60fd2afe63e1..9a5f5c6c5665 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs @@ -14,7 +14,6 @@ use tracing::debug; use crate::borrow_set::BorrowSet; use crate::constraints::OutlivesConstraint; use crate::facts::{AllFacts, PoloniusRegionVid}; -use crate::location::LocationTable; use crate::type_check::MirTypeckRegionConstraints; use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::universal_regions::UniversalRegions; @@ -22,6 +21,8 @@ use crate::universal_regions::UniversalRegions; mod accesses; mod loan_invalidations; mod loan_kills; +mod location; +pub use self::location::*; /// When requested, emit most of the facts needed by polonius: /// - moves and assignments diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 2c658edc41cc..bd969ba96f2b 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -15,8 +15,8 @@ use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, TypeOpOutput}; use tracing::debug; -use crate::location::RichLocation; use crate::polonius; +use crate::polonius::legacy::RichLocation; use crate::region_infer::values::{self, LiveLoans}; use crate::type_check::liveness::local_use_map::LocalUseMap; use crate::type_check::{NormalizeLocation, TypeChecker}; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 3968900d0471..c4bd8ad28bbc 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -48,9 +48,9 @@ use crate::borrow_set::BorrowSet; use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet}; use crate::diagnostics::UniverseInfo; use crate::facts::AllFacts; -use crate::location::LocationTable; use crate::member_constraints::MemberConstraintSet; use crate::polonius::PoloniusContext; +use crate::polonius::legacy::LocationTable; use crate::region_infer::TypeTest; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; use crate::renumber::RegionCtxt; From fbf48c177bfa1034af688ae7050357523fe033aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 29 Dec 2024 23:54:57 +0000 Subject: [PATCH 102/113] simplify `add_extra_drop_facts` this is mostly to remove imports of the polonius legacy module also what is going on in this function, what the... --- compiler/rustc_borrowck/src/facts.rs | 2 +- .../src/polonius/legacy/location.rs | 9 ++++- .../src/type_check/liveness/trace.rs | 34 ++++++------------- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index 8181616d4cfd..17cb46700601 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -246,6 +246,6 @@ impl FactCell for RegionVid { impl FactCell for LocationIndex { fn to_string(&self, location_table: &LocationTable) -> String { - format!("{:?}", location_table.to_location(*self)) + format!("{:?}", location_table.to_rich_location(*self)) } } diff --git a/compiler/rustc_borrowck/src/polonius/legacy/location.rs b/compiler/rustc_borrowck/src/polonius/legacy/location.rs index fbe5f94ed42c..4cb1202033cb 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/location.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/location.rs @@ -65,7 +65,7 @@ impl LocationTable { LocationIndex::from_usize(start_index + statement_index * 2 + 1) } - pub fn to_location(&self, index: LocationIndex) -> RichLocation { + pub fn to_rich_location(&self, index: LocationIndex) -> RichLocation { let point_index = index.index(); // Find the basic block. We have a vector with the @@ -97,6 +97,13 @@ impl LocationTable { RichLocation::Mid(Location { block, statement_index }) } } + + pub fn to_location(&self, index: LocationIndex) -> Location { + match self.to_rich_location(index) { + RichLocation::Start(location) => location, + RichLocation::Mid(location) => location, + } + } } impl LocationIndex { diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index bd969ba96f2b..c7a2d32b31dc 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -16,7 +16,6 @@ use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, Type use tracing::debug; use crate::polonius; -use crate::polonius::legacy::RichLocation; use crate::region_infer::values::{self, LiveLoans}; use crate::type_check::liveness::local_use_map::LocalUseMap; use crate::type_check::{NormalizeLocation, TypeChecker}; @@ -211,7 +210,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { /// /// Add facts for all locals with free regions, since regions may outlive /// the function body only at certain nodes in the CFG. - fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> { + fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) { // This collect is more necessary than immediately apparent // because these facts go into `add_drop_live_facts_for()`, // which also writes to `all_facts`, and so this is genuinely @@ -221,41 +220,30 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { // and probably maybe plausibly does not need to go back in. // It may be necessary to just pick out the parts of // `add_drop_live_facts_for()` that make sense. + let Some(facts) = self.cx.typeck.all_facts.as_ref() else { return }; let facts_to_add: Vec<_> = { - let drop_used = &self.cx.typeck.all_facts.as_ref()?.var_dropped_at; - let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect(); - drop_used + facts + .var_dropped_at .iter() - .filter_map(|(local, location_index)| { - let local_ty = self.cx.body.local_decls[*local].ty; - if relevant_live_locals.contains(local) || !local_ty.has_free_regions() { + .filter_map(|&(local, location_index)| { + let local_ty = self.cx.body.local_decls[local].ty; + if relevant_live_locals.contains(&local) || !local_ty.has_free_regions() { return None; } - let location = match self.cx.typeck.location_table.to_location(*location_index) - { - RichLocation::Start(l) => l, - RichLocation::Mid(l) => l, - }; - - Some((*local, local_ty, location)) + let location = self.cx.typeck.location_table.to_location(location_index); + Some((local, local_ty, location)) }) .collect() }; - // FIXME: these locations seem to have a special meaning (e.g. everywhere, at the end, - // ...), but I don't know which one. Please help me rename it to something descriptive! - // Also, if this IntervalSet is used in many places, it maybe should have a newtype'd - // name with a description of what it means for future mortals passing by. - let locations = IntervalSet::new(self.cx.elements.num_points()); - + let live_at = IntervalSet::new(self.cx.elements.num_points()); for (local, local_ty, location) in facts_to_add { - self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations); + self.cx.add_drop_live_facts_for(local, local_ty, &[location], &live_at); } - Some(()) } /// Clear the value of fields that are "per local variable". From 4107a3ceb40a9f64e95004662bb0e5e74b9b6879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 30 Dec 2024 00:41:22 +0000 Subject: [PATCH 103/113] move `facts` module to polonius legacy module this is specific to the old datalog implementation and wasn't noticed in the previous module move --- compiler/rustc_borrowck/src/consumers.rs | 7 ++++--- compiler/rustc_borrowck/src/lib.rs | 4 +--- compiler/rustc_borrowck/src/nll.rs | 5 +---- compiler/rustc_borrowck/src/polonius/legacy/accesses.rs | 3 +-- compiler/rustc_borrowck/src/{ => polonius/legacy}/facts.rs | 6 ++++-- .../src/polonius/legacy/loan_invalidations.rs | 3 +-- compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs | 3 +-- compiler/rustc_borrowck/src/polonius/legacy/mod.rs | 3 ++- compiler/rustc_borrowck/src/region_infer/mod.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 3 +-- 10 files changed, 17 insertions(+), 22 deletions(-) rename compiler/rustc_borrowck/src/{ => polonius/legacy}/facts.rs (97%) diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 90ca4f7518c1..7e8c48a15513 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -8,11 +8,12 @@ use rustc_middle::ty::TyCtxt; pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; pub use super::constraints::OutlivesConstraint; pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location}; -pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts}; -pub use super::nll::PoloniusOutput; pub use super::place_ext::PlaceExt; pub use super::places_conflict::{PlaceConflictBias, places_conflict}; -pub use super::polonius::legacy::{LocationTable, RichLocation}; +pub use super::polonius::legacy::{ + AllFacts as PoloniusInput, LocationTable, PoloniusOutput, PoloniusRegionVid, RichLocation, + RustcFacts, +}; pub use super::region_infer::RegionInferenceContext; /// Options determining the output behavior of [`get_body_with_borrowck_facts`]. diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index a23348116d2d..b59bdc266484 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -53,11 +53,10 @@ use crate::borrow_set::{BorrowData, BorrowSet}; use crate::consumers::{BodyWithBorrowckFacts, ConsumerOptions}; use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows}; use crate::diagnostics::{AccessKind, IllegalMoveOriginKind, MoveError, RegionName}; -use crate::nll::PoloniusOutput; use crate::path_utils::*; use crate::place_ext::PlaceExt; use crate::places_conflict::{PlaceConflictBias, places_conflict}; -use crate::polonius::legacy::LocationTable; +use crate::polonius::legacy::{LocationTable, PoloniusOutput}; use crate::prefixes::PrefixSet; use crate::region_infer::RegionInferenceContext; use crate::renumber::RegionCtxt; @@ -69,7 +68,6 @@ mod constraints; mod dataflow; mod def_use; mod diagnostics; -mod facts; mod member_constraints; mod nll; mod path_utils; diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index c75d92cd48ea..49edb2813ec6 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -27,16 +27,13 @@ use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; use crate::diagnostics::RegionErrors; -use crate::facts::{AllFacts, AllFactsExt, RustcFacts}; use crate::polonius::LocalizedOutlivesConstraintSet; -use crate::polonius::legacy::LocationTable; +use crate::polonius::legacy::{AllFacts, AllFactsExt, LocationTable, PoloniusOutput}; use crate::region_infer::RegionInferenceContext; use crate::type_check::{self, MirTypeckResults}; use crate::universal_regions::UniversalRegions; use crate::{BorrowckInferCtxt, polonius, renumber}; -pub type PoloniusOutput = Output; - /// The output of `nll::compute_regions`. This includes the computed `RegionInferenceContext`, any /// closure requirements to propagate, and any generated errors. pub(crate) struct NllOutput<'tcx> { diff --git a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs index cc414b854a2a..4a0c8d9b4b46 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/accesses.rs @@ -4,9 +4,8 @@ use rustc_middle::ty::TyCtxt; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData}; use tracing::debug; -use super::{LocationIndex, LocationTable}; +use super::{AllFacts, LocationIndex, LocationTable}; use crate::def_use::{self, DefUse}; -use crate::facts::AllFacts; use crate::universal_regions::UniversalRegions; /// Emit polonius facts for variable defs, uses, drops, and path accesses. diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/polonius/legacy/facts.rs similarity index 97% rename from compiler/rustc_borrowck/src/facts.rs rename to compiler/rustc_borrowck/src/polonius/legacy/facts.rs index 17cb46700601..42c4e7332183 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/facts.rs @@ -4,18 +4,20 @@ use std::fs::{self, File}; use std::io::Write; use std::path::Path; -use polonius_engine::{AllFacts as PoloniusFacts, Atom}; +use polonius_engine::{AllFacts as PoloniusFacts, Atom, Output}; use rustc_macros::extension; use rustc_middle::mir::Local; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::move_paths::MovePathIndex; +use super::{LocationIndex, LocationTable}; use crate::BorrowIndex; -use crate::polonius::legacy::{LocationIndex, LocationTable}; #[derive(Copy, Clone, Debug)] pub struct RustcFacts; +pub type PoloniusOutput = Output; + rustc_index::newtype_index! { /// A (kinda) newtype of `RegionVid` so we can implement `Atom` on it. #[orderable] diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 5e8a1bfe13ea..bb6d593d0d88 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -9,9 +9,8 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use tracing::debug; -use super::LocationTable; +use super::{AllFacts, LocationTable}; use crate::borrow_set::BorrowSet; -use crate::facts::AllFacts; use crate::path_utils::*; use crate::{ AccessDepth, Activation, ArtificialField, BorrowIndex, Deep, LocalMutationIsAllowed, Read, diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs index 55b06bc6b774..0148e0b28696 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_kills.rs @@ -6,9 +6,8 @@ use rustc_middle::mir::{ use rustc_middle::ty::TyCtxt; use tracing::debug; -use super::LocationTable; +use super::{AllFacts, LocationTable}; use crate::borrow_set::BorrowSet; -use crate::facts::AllFacts; use crate::places_conflict; /// Emit `loan_killed_at` and `cfg_edge` facts at the same time. diff --git a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs index 9a5f5c6c5665..45bdbd1e9997 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/mod.rs @@ -13,7 +13,6 @@ use tracing::debug; use crate::borrow_set::BorrowSet; use crate::constraints::OutlivesConstraint; -use crate::facts::{AllFacts, PoloniusRegionVid}; use crate::type_check::MirTypeckRegionConstraints; use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::universal_regions::UniversalRegions; @@ -23,6 +22,8 @@ mod loan_invalidations; mod loan_kills; mod location; pub use self::location::*; +mod facts; +pub use self::facts::*; /// When requested, emit most of the facts needed by polonius: /// - moves and assignments diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index a71508c84f68..2150759d329e 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -30,7 +30,7 @@ use crate::constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstra use crate::dataflow::BorrowIndex; use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo}; use crate::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}; -use crate::nll::PoloniusOutput; +use crate::polonius::legacy::PoloniusOutput; use crate::region_infer::reverse_sccs::ReverseSccGraph; use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues, ToElementIndex}; use crate::type_check::free_region_relations::UniversalRegionRelations; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c4bd8ad28bbc..10fb8a399a26 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -47,10 +47,9 @@ use tracing::{debug, instrument, trace}; use crate::borrow_set::BorrowSet; use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet}; use crate::diagnostics::UniverseInfo; -use crate::facts::AllFacts; use crate::member_constraints::MemberConstraintSet; use crate::polonius::PoloniusContext; -use crate::polonius::legacy::LocationTable; +use crate::polonius::legacy::{AllFacts, LocationTable}; use crate::region_infer::TypeTest; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; use crate::renumber::RegionCtxt; From fbefa2e26722540c7641cc5c0ba8e29b243d8a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 30 Dec 2024 00:56:14 +0000 Subject: [PATCH 104/113] merge `diags` module into `diagnostics` it's a more natural place for diagnostics-related structures and functions --- .../rustc_borrowck/src/diagnostics/mod.rs | 138 +++++++++++++++- compiler/rustc_borrowck/src/lib.rs | 149 +----------------- compiler/rustc_borrowck/src/nll.rs | 4 +- 3 files changed, 142 insertions(+), 149 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 67be6ecdeb3d..c82f59730160 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1,6 +1,9 @@ //! Borrow checker diagnostics. +use std::collections::BTreeMap; + use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_data_structures::fx::FxIndexMap; use rustc_errors::{Applicability, Diag, MultiSpan}; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::{self as hir, CoroutineKind, LangItem}; @@ -17,10 +20,10 @@ use rustc_middle::mir::{ use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_middle::util::{CallDesugaringKind, call_kind}; -use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; +use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveOutIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Spanned; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{ @@ -68,6 +71,137 @@ pub(super) struct DescribePlaceOpt { pub(super) struct IncludingTupleField(pub(super) bool); +enum BufferedDiag<'infcx> { + Error(Diag<'infcx>), + NonError(Diag<'infcx, ()>), +} + +impl<'infcx> BufferedDiag<'infcx> { + fn sort_span(&self) -> Span { + match self { + BufferedDiag::Error(diag) => diag.sort_span, + BufferedDiag::NonError(diag) => diag.sort_span, + } + } +} + +pub(crate) struct BorrowckDiags<'infcx, 'tcx> { + /// This field keeps track of move errors that are to be reported for given move indices. + /// + /// There are situations where many errors can be reported for a single move out (see + /// #53807) and we want only the best of those errors. + /// + /// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the + /// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of + /// the `Place` of the previous most diagnostic. This happens instead of buffering the + /// error. Once all move errors have been reported, any diagnostics in this map are added + /// to the buffer to be emitted. + /// + /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary + /// when errors in the map are being re-added to the error buffer so that errors with the + /// same primary span come out in a consistent order. + buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, + + buffered_mut_errors: FxIndexMap, usize)>, + + /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. + buffered_diags: Vec>, +} + +impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { + pub(crate) fn new() -> Self { + BorrowckDiags { + buffered_move_errors: BTreeMap::new(), + buffered_mut_errors: Default::default(), + buffered_diags: Default::default(), + } + } + + pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { + self.buffered_diags.push(BufferedDiag::Error(diag)); + } + + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { + self.buffered_diags.push(BufferedDiag::NonError(diag)); + } +} + +impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { + pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { + self.diags.buffer_error(diag); + } + + pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { + self.diags.buffer_non_error(diag); + } + + pub(crate) fn buffer_move_error( + &mut self, + move_out_indices: Vec, + place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), + ) -> bool { + if let Some((_, diag)) = + self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) + { + // Cancel the old diagnostic so we don't ICE + diag.cancel(); + false + } else { + true + } + } + + pub(crate) fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { + // FIXME(#120456) - is `swap_remove` correct? + self.diags.buffered_mut_errors.swap_remove(&span) + } + + pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { + self.diags.buffered_mut_errors.insert(span, (diag, count)); + } + + pub(crate) fn emit_errors(&mut self) -> Option { + let mut res = self.infcx.tainted_by_errors(); + + // Buffer any move errors that we collected and de-duplicated. + for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) { + // We have already set tainted for this error, so just buffer it. + self.diags.buffer_error(diag); + } + for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) { + if count > 10 { + #[allow(rustc::diagnostic_outside_of_impl)] + #[allow(rustc::untranslatable_diagnostic)] + diag.note(format!("...and {} other attempted mutable borrows", count - 10)); + } + self.diags.buffer_error(diag); + } + + if !self.diags.buffered_diags.is_empty() { + self.diags.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); + for buffered_diag in self.diags.buffered_diags.drain(..) { + match buffered_diag { + BufferedDiag::Error(diag) => res = Some(diag.emit()), + BufferedDiag::NonError(diag) => diag.emit(), + } + } + } + + res + } + + pub(crate) fn has_buffered_diags(&self) -> bool { + self.diags.buffered_diags.is_empty() + } + + pub(crate) fn has_move_error( + &self, + move_out_indices: &[MoveOutIndex], + ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { + self.diags.buffered_move_errors.get(move_out_indices) + } +} + impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure /// is moved after being invoked. diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index b59bdc266484..6571fb5ddac4 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -16,14 +16,13 @@ // tidy-alphabetical-end use std::cell::RefCell; -use std::collections::BTreeMap; use std::marker::PhantomData; use std::ops::Deref; +use diagnostics::BorrowckDiags; use rustc_abi::FieldIdx; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_errors::Diag; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::{BitSet, MixedBitSet}; @@ -41,7 +40,7 @@ use rustc_mir_dataflow::impls::{ EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces, }; use rustc_mir_dataflow::move_paths::{ - InitIndex, InitLocation, LookupResult, MoveData, MoveOutIndex, MovePathIndex, + InitIndex, InitLocation, LookupResult, MoveData, MovePathIndex, }; use rustc_mir_dataflow::{Analysis, EntryStates, Results, ResultsVisitor, visit_results}; use rustc_session::lint::builtin::UNUSED_MUT; @@ -217,7 +216,7 @@ fn do_mir_borrowck<'tcx>( // We also have a `#[rustc_regions]` annotation that causes us to dump // information. - let diags = &mut diags::BorrowckDiags::new(); + let diags = &mut BorrowckDiags::new(); nll::dump_annotation(&infcx, body, ®ioncx, &opt_closure_req, &opaque_type_values, diags); let movable_coroutine = @@ -566,7 +565,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: &'a mut diags::BorrowckDiags<'infcx, 'tcx>, + diags: &'a mut BorrowckDiags<'infcx, 'tcx>, move_errors: Vec>, } @@ -2399,146 +2398,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { } } -mod diags { - use rustc_errors::ErrorGuaranteed; - - use super::*; - - enum BufferedDiag<'infcx> { - Error(Diag<'infcx>), - NonError(Diag<'infcx, ()>), - } - - impl<'infcx> BufferedDiag<'infcx> { - fn sort_span(&self) -> Span { - match self { - BufferedDiag::Error(diag) => diag.sort_span, - BufferedDiag::NonError(diag) => diag.sort_span, - } - } - } - - pub(crate) struct BorrowckDiags<'infcx, 'tcx> { - /// This field keeps track of move errors that are to be reported for given move indices. - /// - /// There are situations where many errors can be reported for a single move out (see - /// #53807) and we want only the best of those errors. - /// - /// The `report_use_of_moved_or_uninitialized` function checks this map and replaces the - /// diagnostic (if there is one) if the `Place` of the error being reported is a prefix of - /// the `Place` of the previous most diagnostic. This happens instead of buffering the - /// error. Once all move errors have been reported, any diagnostics in this map are added - /// to the buffer to be emitted. - /// - /// `BTreeMap` is used to preserve the order of insertions when iterating. This is necessary - /// when errors in the map are being re-added to the error buffer so that errors with the - /// same primary span come out in a consistent order. - buffered_move_errors: BTreeMap, (PlaceRef<'tcx>, Diag<'infcx>)>, - - buffered_mut_errors: FxIndexMap, usize)>, - - /// Buffer of diagnostics to be reported. A mixture of error and non-error diagnostics. - buffered_diags: Vec>, - } - - impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { - pub(crate) fn new() -> Self { - BorrowckDiags { - buffered_move_errors: BTreeMap::new(), - buffered_mut_errors: Default::default(), - buffered_diags: Default::default(), - } - } - - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.buffered_diags.push(BufferedDiag::Error(diag)); - } - - pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { - self.buffered_diags.push(BufferedDiag::NonError(diag)); - } - } - - impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.diags.buffer_error(diag); - } - - pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { - self.diags.buffer_non_error(diag); - } - - pub(crate) fn buffer_move_error( - &mut self, - move_out_indices: Vec, - place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), - ) -> bool { - if let Some((_, diag)) = - self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) - { - // Cancel the old diagnostic so we don't ICE - diag.cancel(); - false - } else { - true - } - } - - pub(crate) fn get_buffered_mut_error( - &mut self, - span: Span, - ) -> Option<(Diag<'infcx>, usize)> { - // FIXME(#120456) - is `swap_remove` correct? - self.diags.buffered_mut_errors.swap_remove(&span) - } - - pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { - self.diags.buffered_mut_errors.insert(span, (diag, count)); - } - - pub(crate) fn emit_errors(&mut self) -> Option { - let mut res = self.infcx.tainted_by_errors(); - - // Buffer any move errors that we collected and de-duplicated. - for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) { - // We have already set tainted for this error, so just buffer it. - self.diags.buffer_error(diag); - } - for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) { - if count > 10 { - #[allow(rustc::diagnostic_outside_of_impl)] - #[allow(rustc::untranslatable_diagnostic)] - diag.note(format!("...and {} other attempted mutable borrows", count - 10)); - } - self.diags.buffer_error(diag); - } - - if !self.diags.buffered_diags.is_empty() { - self.diags.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); - for buffered_diag in self.diags.buffered_diags.drain(..) { - match buffered_diag { - BufferedDiag::Error(diag) => res = Some(diag.emit()), - BufferedDiag::NonError(diag) => diag.emit(), - } - } - } - - res - } - - pub(crate) fn has_buffered_diags(&self) -> bool { - self.diags.buffered_diags.is_empty() - } - - pub(crate) fn has_move_error( - &self, - move_out_indices: &[MoveOutIndex], - ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { - self.diags.buffered_move_errors.get(move_out_indices) - } - } -} - /// The degree of overlap between 2 places for borrow-checking. enum Overlap { /// The places might partially overlap - in this case, we give diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 49edb2813ec6..6184f1484b56 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -26,7 +26,7 @@ use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; -use crate::diagnostics::RegionErrors; +use crate::diagnostics::{BorrowckDiags, RegionErrors}; use crate::polonius::LocalizedOutlivesConstraintSet; use crate::polonius::legacy::{AllFacts, AllFactsExt, LocationTable, PoloniusOutput}; use crate::region_infer::RegionInferenceContext; @@ -298,7 +298,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, opaque_type_values: &FxIndexMap>, - diags: &mut crate::diags::BorrowckDiags<'infcx, 'tcx>, + diags: &mut BorrowckDiags<'infcx, 'tcx>, ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); From 8c86e52ed7750e1f21ec8ce729cb5d4f20b073d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 30 Dec 2024 01:16:52 +0000 Subject: [PATCH 105/113] clean up `BorrowckDiags` - rename it to what it does, buffer diagnostics - remove single-use functions - use derives --- .../rustc_borrowck/src/diagnostics/mod.rs | 23 +++++-------------- compiler/rustc_borrowck/src/lib.rs | 9 ++++---- compiler/rustc_borrowck/src/nll.rs | 4 ++-- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c82f59730160..f1189617c02e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -85,7 +85,8 @@ impl<'infcx> BufferedDiag<'infcx> { } } -pub(crate) struct BorrowckDiags<'infcx, 'tcx> { +#[derive(Default)] +pub(crate) struct BorrowckDiagnosticsBuffer<'infcx, 'tcx> { /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see @@ -108,19 +109,7 @@ pub(crate) struct BorrowckDiags<'infcx, 'tcx> { buffered_diags: Vec>, } -impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { - pub(crate) fn new() -> Self { - BorrowckDiags { - buffered_move_errors: BTreeMap::new(), - buffered_mut_errors: Default::default(), - buffered_diags: Default::default(), - } - } - - pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.buffered_diags.push(BufferedDiag::Error(diag)); - } - +impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> { pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { self.buffered_diags.push(BufferedDiag::NonError(diag)); } @@ -128,7 +117,7 @@ impl<'infcx, 'tcx> BorrowckDiags<'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.diags.buffer_error(diag); + self.diags.buffered_diags.push(BufferedDiag::Error(diag)); } pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { @@ -166,7 +155,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Buffer any move errors that we collected and de-duplicated. for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) { // We have already set tainted for this error, so just buffer it. - self.diags.buffer_error(diag); + self.buffer_error(diag); } for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) { if count > 10 { @@ -174,7 +163,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { #[allow(rustc::untranslatable_diagnostic)] diag.note(format!("...and {} other attempted mutable borrows", count - 10)); } - self.diags.buffer_error(diag); + self.buffer_error(diag); } if !self.diags.buffered_diags.is_empty() { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 6571fb5ddac4..51053a41d43b 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -19,7 +19,6 @@ use std::cell::RefCell; use std::marker::PhantomData; use std::ops::Deref; -use diagnostics::BorrowckDiags; use rustc_abi::FieldIdx; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; @@ -51,7 +50,9 @@ use tracing::{debug, instrument}; use crate::borrow_set::{BorrowData, BorrowSet}; use crate::consumers::{BodyWithBorrowckFacts, ConsumerOptions}; use crate::dataflow::{BorrowIndex, Borrowck, BorrowckDomain, Borrows}; -use crate::diagnostics::{AccessKind, IllegalMoveOriginKind, MoveError, RegionName}; +use crate::diagnostics::{ + AccessKind, BorrowckDiagnosticsBuffer, IllegalMoveOriginKind, MoveError, RegionName, +}; use crate::path_utils::*; use crate::place_ext::PlaceExt; use crate::places_conflict::{PlaceConflictBias, places_conflict}; @@ -216,7 +217,7 @@ fn do_mir_borrowck<'tcx>( // We also have a `#[rustc_regions]` annotation that causes us to dump // information. - let diags = &mut BorrowckDiags::new(); + let diags = &mut BorrowckDiagnosticsBuffer::default(); nll::dump_annotation(&infcx, body, ®ioncx, &opt_closure_req, &opaque_type_values, diags); let movable_coroutine = @@ -565,7 +566,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: &'a mut BorrowckDiags<'infcx, 'tcx>, + diags: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, move_errors: Vec>, } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 6184f1484b56..08a81417eba7 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -26,7 +26,7 @@ use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; -use crate::diagnostics::{BorrowckDiags, RegionErrors}; +use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors}; use crate::polonius::LocalizedOutlivesConstraintSet; use crate::polonius::legacy::{AllFacts, AllFactsExt, LocationTable, PoloniusOutput}; use crate::region_infer::RegionInferenceContext; @@ -298,7 +298,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, opaque_type_values: &FxIndexMap>, - diags: &mut BorrowckDiags<'infcx, 'tcx>, + diags: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); From 099b80923b86c21a46523e3dfa99a09a4fc39ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 30 Dec 2024 01:21:48 +0000 Subject: [PATCH 106/113] rename `diags` field --- .../rustc_borrowck/src/diagnostics/mod.rs | 24 +++++++++---------- compiler/rustc_borrowck/src/lib.rs | 17 +++++++++---- compiler/rustc_borrowck/src/nll.rs | 4 ++-- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index f1189617c02e..180046ca2562 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -117,11 +117,11 @@ impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> { impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) { - self.diags.buffered_diags.push(BufferedDiag::Error(diag)); + self.diags_buffer.buffered_diags.push(BufferedDiag::Error(diag)); } pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) { - self.diags.buffer_non_error(diag); + self.diags_buffer.buffer_non_error(diag); } pub(crate) fn buffer_move_error( @@ -130,7 +130,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { place_and_err: (PlaceRef<'tcx>, Diag<'infcx>), ) -> bool { if let Some((_, diag)) = - self.diags.buffered_move_errors.insert(move_out_indices, place_and_err) + self.diags_buffer.buffered_move_errors.insert(move_out_indices, place_and_err) { // Cancel the old diagnostic so we don't ICE diag.cancel(); @@ -142,22 +142,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pub(crate) fn get_buffered_mut_error(&mut self, span: Span) -> Option<(Diag<'infcx>, usize)> { // FIXME(#120456) - is `swap_remove` correct? - self.diags.buffered_mut_errors.swap_remove(&span) + self.diags_buffer.buffered_mut_errors.swap_remove(&span) } pub(crate) fn buffer_mut_error(&mut self, span: Span, diag: Diag<'infcx>, count: usize) { - self.diags.buffered_mut_errors.insert(span, (diag, count)); + self.diags_buffer.buffered_mut_errors.insert(span, (diag, count)); } pub(crate) fn emit_errors(&mut self) -> Option { let mut res = self.infcx.tainted_by_errors(); // Buffer any move errors that we collected and de-duplicated. - for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) { + for (_, (_, diag)) in std::mem::take(&mut self.diags_buffer.buffered_move_errors) { // We have already set tainted for this error, so just buffer it. self.buffer_error(diag); } - for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) { + for (_, (mut diag, count)) in std::mem::take(&mut self.diags_buffer.buffered_mut_errors) { if count > 10 { #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] @@ -166,9 +166,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.buffer_error(diag); } - if !self.diags.buffered_diags.is_empty() { - self.diags.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); - for buffered_diag in self.diags.buffered_diags.drain(..) { + if !self.diags_buffer.buffered_diags.is_empty() { + self.diags_buffer.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span()); + for buffered_diag in self.diags_buffer.buffered_diags.drain(..) { match buffered_diag { BufferedDiag::Error(diag) => res = Some(diag.emit()), BufferedDiag::NonError(diag) => diag.emit(), @@ -180,14 +180,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } pub(crate) fn has_buffered_diags(&self) -> bool { - self.diags.buffered_diags.is_empty() + self.diags_buffer.buffered_diags.is_empty() } pub(crate) fn has_move_error( &self, move_out_indices: &[MoveOutIndex], ) -> Option<&(PlaceRef<'tcx>, Diag<'infcx>)> { - self.diags.buffered_move_errors.get(move_out_indices) + self.diags_buffer.buffered_move_errors.get(move_out_indices) } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 51053a41d43b..b061a450c83f 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -217,8 +217,15 @@ fn do_mir_borrowck<'tcx>( // We also have a `#[rustc_regions]` annotation that causes us to dump // information. - let diags = &mut BorrowckDiagnosticsBuffer::default(); - nll::dump_annotation(&infcx, body, ®ioncx, &opt_closure_req, &opaque_type_values, diags); + let diags_buffer = &mut BorrowckDiagnosticsBuffer::default(); + nll::dump_annotation( + &infcx, + body, + ®ioncx, + &opt_closure_req, + &opaque_type_values, + diags_buffer, + ); let movable_coroutine = // The first argument is the coroutine type passed by value @@ -257,7 +264,7 @@ fn do_mir_borrowck<'tcx>( next_region_name: RefCell::new(1), polonius_output: None, move_errors: Vec::new(), - diags, + diags_buffer, }; MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body); promoted_mbcx.report_move_errors(); @@ -296,7 +303,7 @@ fn do_mir_borrowck<'tcx>( next_region_name: RefCell::new(1), polonius_output, move_errors: Vec::new(), - diags, + diags_buffer, }; // Compute and report region errors, if any. @@ -566,7 +573,7 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { /// Results of Polonius analysis. polonius_output: Option>, - diags: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, + diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, move_errors: Vec>, } diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 08a81417eba7..968b6d383c1b 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -298,7 +298,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, opaque_type_values: &FxIndexMap>, - diags: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, + diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, ) { let tcx = infcx.tcx; let base_def_id = tcx.typeck_root_def_id(body.source.def_id()); @@ -344,7 +344,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}")); } - diags.buffer_non_error(err); + diagnostics_buffer.buffer_non_error(err); } fn for_each_region_constraint<'tcx>( From 4c279fb7af22ac24833464a5d7ffa56ca79a251d Mon Sep 17 00:00:00 2001 From: Horu <73709188+HigherOrderLogic@users.noreply.github.com> Date: Mon, 30 Dec 2024 14:56:21 +0700 Subject: [PATCH 107/113] chore: fix typos --- src/bootstrap/src/core/build_steps/test.rs | 2 +- src/bootstrap/src/lib.rs | 2 +- src/bootstrap/src/utils/tarball.rs | 2 +- src/ci/scripts/install-clang.sh | 2 +- src/tools/linkchecker/main.rs | 2 +- src/tools/nix-dev-shell/envrc-flake | 2 +- src/tools/nix-dev-shell/envrc-shell | 2 +- tests/ui/associated-types/associated-types-eq-2.rs | 2 +- tests/ui/associated-types/project-defer-unification.rs | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index fe2dd9cc5f3e..6aa6e4e277d4 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2637,7 +2637,7 @@ fn prepare_cargo_test( ) -> BootstrapCommand { let mut cargo = cargo.into(); - // Propegate `--bless` if it has not already been set/unset + // Propagate `--bless` if it has not already been set/unset // Any tools that want to use this should bless if `RUSTC_BLESS` is set to // anything other than `0`. if builder.config.cmd.bless() && !cargo.get_envs().any(|v| v.0 == "RUSTC_BLESS") { diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index eff259212c58..4cc812829f9b 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1691,7 +1691,7 @@ Executed at: {executed_at}"#, } } if let Ok(()) = fs::hard_link(&src, dst) { - // Attempt to "easy copy" by creating a hard link (symlinks are priviledged on windows), + // Attempt to "easy copy" by creating a hard link (symlinks are privileged on windows), // but if that fails just fall back to a slow `copy` operation. } else { if let Err(e) = fs::copy(&src, dst) { diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 3c6c7a7fa180..843ea65e8386 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -1,7 +1,7 @@ //! Facilitates the management and generation of tarballs. //! //! Tarballs efficiently hold Rust compiler build artifacts and -//! capture a snapshot of each boostrap stage. +//! capture a snapshot of each bootstrap stage. //! In uplifting, a tarball from Stage N captures essential components //! to assemble Stage N + 1 compiler. diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index 6103aa61248a..5522095e3049 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -15,7 +15,7 @@ LLVM_VERSION="18.1.4" if isMacOS; then # FIXME: This is the latest pre-built version of LLVM that's available for - # x86_64 MacOS. We may want to consider bulding our own LLVM binaries + # x86_64 MacOS. We may want to consider building our own LLVM binaries # instead, or set `USE_XCODE_CLANG` like AArch64 does. LLVM_VERSION="15.0.7" diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 833e41df5370..570b2c374c0e 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -8,7 +8,7 @@ //! //! Currently uses a combination of HTML parsing to //! extract the `href` and `id` attributes, -//! and regex search on the orignal markdown to handle intra-doc links. +//! and regex search on the original markdown to handle intra-doc links. //! //! These values are then translated to file URLs if possible and then the //! destination is asserted to exist. diff --git a/src/tools/nix-dev-shell/envrc-flake b/src/tools/nix-dev-shell/envrc-flake index 849ed1f4fc56..f3e5442b86b2 100644 --- a/src/tools/nix-dev-shell/envrc-flake +++ b/src/tools/nix-dev-shell/envrc-flake @@ -1,4 +1,4 @@ -# If you want to use this as an .envrc file to create a shell with necessery components +# If you want to use this as an .envrc file to create a shell with necessary components # to develop rustc, use the following command in the root of the rusr checkout: # # ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc && nix flake update --flake ./src/tools/nix-dev-shell diff --git a/src/tools/nix-dev-shell/envrc-shell b/src/tools/nix-dev-shell/envrc-shell index d8f900fe86a6..4080d7d53840 100644 --- a/src/tools/nix-dev-shell/envrc-shell +++ b/src/tools/nix-dev-shell/envrc-shell @@ -1,4 +1,4 @@ -# If you want to use this as an .envrc file to create a shell with necessery components +# If you want to use this as an .envrc file to create a shell with necessary components # to develop rustc, use the following command in the root of the rusr checkout: # # ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc diff --git a/tests/ui/associated-types/associated-types-eq-2.rs b/tests/ui/associated-types/associated-types-eq-2.rs index 88eb29810610..9d2860d1b309 100644 --- a/tests/ui/associated-types/associated-types-eq-2.rs +++ b/tests/ui/associated-types/associated-types-eq-2.rs @@ -33,7 +33,7 @@ fn baz(_x: &>::A) {} trait Tr2 { } -// Test for when wrongly specifed equality constraint's ident +// Test for when wrongly specified equality constraint's ident // matches some generic param's ident // (Note: E0229 is emitted only for the first erroneous equality // constraint (T2) not for any subequent ones (e.g. T3)) diff --git a/tests/ui/associated-types/project-defer-unification.rs b/tests/ui/associated-types/project-defer-unification.rs index cec088496fd3..b51228ef4117 100644 --- a/tests/ui/associated-types/project-defer-unification.rs +++ b/tests/ui/associated-types/project-defer-unification.rs @@ -93,7 +93,7 @@ where Pix: Pixel + 'static, let mut indices: ImageBuffer<_,Vec<_>> = loop { }; for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) { - // failured occurred here ^^ because we were requiring that we + // failure occurred here ^^ because we were requiring that we // could project Pixel or Subpixel from `T_indices` (type of // `indices`), but the type is insufficiently constrained // until we reach the return below. From 92e8e84e7d85a17e8c32a9c6874fa5e655c16872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 30 Dec 2024 05:55:57 +0800 Subject: [PATCH 108/113] tests: add basic test coverage for cli flag `--crate-type` --- .../crate-type-flag.empty_crate_type.stderr | 2 + ...ate-type-flag.proc_underscore_macro.stderr | 2 + .../invalid-compile-flags/crate-type-flag.rs | 61 +++++++++++++++++++ .../crate-type-flag.unknown.stderr | 2 + 4 files changed, 67 insertions(+) create mode 100644 tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr create mode 100644 tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr create mode 100644 tests/ui/invalid-compile-flags/crate-type-flag.rs create mode 100644 tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr new file mode 100644 index 000000000000..0f8772024dfa --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr @@ -0,0 +1,2 @@ +error: unknown crate type: `` + diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr new file mode 100644 index 000000000000..a4a974169964 --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr @@ -0,0 +1,2 @@ +error: unknown crate type: `proc_macro` + diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/invalid-compile-flags/crate-type-flag.rs new file mode 100644 index 000000000000..42bd72cbfbf5 --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.rs @@ -0,0 +1,61 @@ +//! Check that `rustc`'s `--crate-type` flag accepts `--crate-type=` as well as the +//! multi-value version `--crate-type=,`. +//! +//! This test does not try to check if the output artifacts are valid. + +// FIXME(#132309): add a proper `supports-crate-type` directive. + +// Single valid crate types should pass +//@ revisions: lib rlib staticlib dylib cdylib bin proc_dash_macro + +//@[lib] compile-flags: --crate-type=lib +//@[lib] check-pass + +//@[rlib] compile-flags: --crate-type=rlib +//@[rlib] check-pass + +//@[staticlib] compile-flags: --crate-type=staticlib +//@[staticlib] check-pass + +//@[dylib] ignore-musl (dylibs are not supported) +//@[dylib] ignore-wasm (dylibs are not supported) +//@[dylib] compile-flags: --crate-type=dylib +//@[dylib] check-pass + +//@[cdylib] ignore-musl (cdylibs are not supported) +//@[cdylib] compile-flags: --crate-type=cdylib +//@[cdylib] check-pass + +//@[bin] compile-flags: --crate-type=bin +//@[bin] check-pass + +//@[proc_dash_macro] ignore-wasm (proc-macro is not supported) +//@[proc_dash_macro] compile-flags: --crate-type=proc-macro +//@[proc_dash_macro] check-pass + +//@ revisions: multivalue multivalue_combined + +//@[multivalue] compile-flags: --crate-type=lib,rlib,staticlib +//@[multivalue] check-pass + +//@[multivalue_combined] ignore-musl (dylibs are not supported) +//@[multivalue_combined] ignore-wasm (dylibs are not supported) +//@[multivalue_combined] compile-flags: --crate-type=lib,rlib,staticlib --crate-type=dylib +//@[multivalue_combined] check-pass + +// `proc-macro` is accepted, but `proc_macro` is not. +//@ revisions: proc_underscore_macro +//@[proc_underscore_macro] compile-flags: --crate-type=proc_macro +//@[proc_underscore_macro] error-pattern: "unknown crate type: `proc_macro`" + +// Empty `--crate-type` not accepted. +//@ revisions: empty_crate_type +//@[empty_crate_type] compile-flags: --crate-type= +//@[empty_crate_type] error-pattern: "unknown crate type: ``" + +// Random unknown crate type. Also check that we can handle non-ASCII. +//@ revisions: unknown +//@[unknown] compile-flags: --crate-type=🤡 +//@[unknown] error-pattern: "unknown crate type: `🤡`" + +fn main() {} diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr b/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr new file mode 100644 index 000000000000..7fb0f09a1afb --- /dev/null +++ b/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr @@ -0,0 +1,2 @@ +error: unknown crate type: `🤡` + From a0b3452fb5809fab08b6c10fc778abbe6f3e0abf Mon Sep 17 00:00:00 2001 From: ericlehong <193237094+ericlehong@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:43:22 +0800 Subject: [PATCH 109/113] Fix typos Signed-off-by: ericlehong <193237094+ericlehong@users.noreply.github.com> --- src/etc/test-float-parse/README.md | 2 +- src/etc/test-float-parse/src/lib.rs | 8 ++++---- src/tools/suggest-tests/src/static_suggestions.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/etc/test-float-parse/README.md b/src/etc/test-float-parse/README.md index 21b20d0a072d..5e2c43d1cad6 100644 --- a/src/etc/test-float-parse/README.md +++ b/src/etc/test-float-parse/README.md @@ -3,7 +3,7 @@ These are tests designed to test decimal to float conversions (`dec2flt`) used by the standard library. -It consistes of a collection of test generators that each generate a set of +It consists of a collection of test generators that each generate a set of patterns intended to test a specific property. In addition, there are exhaustive tests (for <= `f32`) and fuzzers (for anything that can't be run exhaustively). diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs index 71b1aa066710..3c71b0dc32e7 100644 --- a/src/etc/test-float-parse/src/lib.rs +++ b/src/etc/test-float-parse/src/lib.rs @@ -35,7 +35,7 @@ const DEFAULT_MAX_FAILURES: u64 = 20; /// Register exhaustive tests only for <= 32 bits. No more because it would take years. const MAX_BITS_FOR_EXHAUUSTIVE: u32 = 32; -/// If there are more tests than this threashold, the test will be defered until after all +/// If there are more tests than this threshold, the test will be deferred until after all /// others run (so as to avoid thread pool starvation). They also can be excluded with /// `--skip-huge`. const HUGE_TEST_CUTOFF: u64 = 5_000_000; @@ -109,7 +109,7 @@ pub fn run(cfg: Config, include: &[String], exclude: &[String]) -> ExitCode { ui::finish(&tests, elapsed, &cfg) } -/// Enumerate tests to run but don't actaully run them. +/// Enumerate tests to run but don't actually run them. pub fn register_tests(cfg: &Config) -> Vec { let mut tests = Vec::new(); @@ -120,7 +120,7 @@ pub fn register_tests(cfg: &Config) -> Vec { tests.sort_unstable_by_key(|t| (t.float_name, t.gen_name)); for i in 0..(tests.len() - 1) { if tests[i].gen_name == tests[i + 1].gen_name { - panic!("dupliate test name {}", tests[i].gen_name); + panic!("duplicate test name {}", tests[i].gen_name); } } @@ -295,7 +295,7 @@ enum Update { fail: CheckFailure, /// String for which parsing was attempted. input: Box, - /// The parsed & decomposed `FloatRes`, aleady stringified so we don't need generics here. + /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here. float_res: Box, }, /// Exited with an unexpected condition. diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs index b216138cf9a5..d363d583b546 100644 --- a/src/tools/suggest-tests/src/static_suggestions.rs +++ b/src/tools/suggest-tests/src/static_suggestions.rs @@ -2,7 +2,7 @@ use std::sync::OnceLock; use crate::{Suggestion, sug}; -// FIXME: perhaps this could use `std::lazy` when it is stablizied +// FIXME: perhaps this could use `std::lazy` when it is stabilized macro_rules! static_suggestions { ($( [ $( $glob:expr ),* $(,)? ] => [ $( $suggestion:expr ),* $(,)? ] ),* $(,)? ) => { pub(crate) fn static_suggestions() -> &'static [(Vec<&'static str>, Vec)] From ac3ffccf37a4eefb50844c01919da935ca668431 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:45:49 +0100 Subject: [PATCH 110/113] Add illumos target documentation --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 4 +- src/doc/rustc/src/platform-support/illumos.md | 42 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/illumos.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 9743b3ba442a..f0c3720eae14 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -56,6 +56,7 @@ - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md) - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md) - [hexagon-unknown-none-elf](platform-support/hexagon-unknown-none-elf.md) + - [illumos](platform-support/illumos.md) - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) - [loongarch\*-unknown-none\*](platform-support/loongarch-none.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 00ab61051c3c..b82e371ebfba 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -102,7 +102,7 @@ target | notes [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17) [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit amd64 FreeBSD -`x86_64-unknown-illumos` | illumos +[`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 @@ -261,7 +261,7 @@ target | std | host | notes [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit -`aarch64-unknown-illumos` | ✓ | ✓ | ARM64 illumos +[`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD diff --git a/src/doc/rustc/src/platform-support/illumos.md b/src/doc/rustc/src/platform-support/illumos.md new file mode 100644 index 000000000000..dd2ae90f6741 --- /dev/null +++ b/src/doc/rustc/src/platform-support/illumos.md @@ -0,0 +1,42 @@ +# `aarch64-unknown-illumos` and `x86_64-unknown-illumos` + +**Tier: 2/3** + +[illumos](https://www.illumos.org/), is a Unix operating system which provides next-generation features for downstream distributions, +including advanced system debugging, next generation filesystem, networking, and virtualization options. + +## Target maintainers + +- Joshua M. Clulow ([@jclulow](https://github.com/jclulow)) +- Patrick Mooney ([@pfmooney](https://github.com/pfmooney)) + +## Requirements + +The target supports host tools. + +The illumos target supports `std` and uses the standard ELF file format. + +`x86_64-unknown-illumos` is a tier 2 target with host tools. +`aarch64-unknown-illumos` is a tier 3 target. + +## Building the target + +These targets can be built by adding `aarch64-unknown-illumos` and +`x86_64-unknown-illumos` as targets in the rustc list. + +## Building Rust programs + +Rust ships pre-compiled artifacts for the `x86_64-unknown-illumos` target. +Rust does not ship pre-compiled artifacts for `aarch64-unknown-illumos`, +it requires building the target either as shown above or using `-Zbuild-std`. + +## Testing + +Tests can be run in the same way as a regular binary. + +## Cross-compilation toolchains and C code + +The target supports C code. + +The illumos project makes available [prebuilt sysroot artefacts](https://github.com/illumos/sysroot) which can be used for cross compilation. +The official Rust binaries are cross-compiled using these artefacts. From b4d14ceae7d33da6deb8cc4e96ca8e467db614a3 Mon Sep 17 00:00:00 2001 From: ranger-ross Date: Tue, 31 Dec 2024 00:28:58 +0900 Subject: [PATCH 111/113] ci: Cleanup docker build logs in CI --- src/ci/docker/run.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index a0adf60b6b2c..d1bc0519bc1e 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -76,8 +76,9 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then # Include cache version. Can be used to manually bust the Docker cache. echo "2" >> $hash_key - echo "Image input" + echo "::group::Image checksum input" cat $hash_key + echo "::endgroup::" cksum=$(sha512sum $hash_key | \ awk '{print $1}') From 3c0c1386878812780349be38080470c0b4fcdda2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 30 Dec 2024 19:30:08 +0100 Subject: [PATCH 112/113] fmt Co-authored-by: scottmcm --- .../miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs index d5a72ea8612d..f5f9c7efbe4a 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs @@ -7,8 +7,8 @@ use std::ptr::addr_of_mut; fn invalid_scalar() { // We run the test twice, with either the left or the right side being invalid. - let mut a = if cfg!(left) { 2_u8} else { 1_u8 }; - let mut b = if cfg!(right) { 3_u8} else { 1_u8 }; + let mut a = if cfg!(left) { 2_u8 } else { 1_u8 }; + let mut b = if cfg!(right) { 3_u8 } else { 1_u8 }; unsafe { let a = addr_of_mut!(a).cast::(); let b = addr_of_mut!(b).cast::(); From 5079acc060b1c7225de95ee3cdd84b5719ff189c Mon Sep 17 00:00:00 2001 From: Frank King Date: Wed, 25 Dec 2024 14:54:49 +0800 Subject: [PATCH 113/113] Implement `use` associated items of traits --- .../src/error_codes/E0253.md | 12 ++-- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_resolve/src/diagnostics.rs | 6 +- compiler/rustc_resolve/src/imports.rs | 14 ++++- compiler/rustc_resolve/src/lib.rs | 11 ++-- compiler/rustc_span/src/symbol.rs | 1 + tests/ui/error-codes/E0253.rs | 4 +- tests/ui/error-codes/E0253.stderr | 6 +- ...-gate-import-trait-associated-functions.rs | 63 +++++++++++++++++++ ...e-import-trait-associated-functions.stderr | 53 ++++++++++++++++ tests/ui/imports/import-trait-method.rs | 4 +- tests/ui/imports/import-trait-method.stderr | 21 +++++-- ...d.import_trait_associated_functions.stderr | 39 ++++++++++++ ...thod.stderr => fn-to-method.normal.stderr} | 6 +- tests/ui/suggestions/fn-to-method.rs | 8 ++- .../import_trait_associated_functions-2015.rs | 61 ++++++++++++++++++ .../use/import_trait_associated_functions.rs | 61 ++++++++++++++++++ tests/ui/use/use-from-trait-xc.rs | 4 +- tests/ui/use/use-from-trait-xc.stderr | 18 ++++-- tests/ui/use/use-from-trait.rs | 4 +- tests/ui/use/use-from-trait.stderr | 18 ++++-- 21 files changed, 374 insertions(+), 42 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs create mode 100644 tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr create mode 100644 tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr rename tests/ui/suggestions/{fn-to-method.stderr => fn-to-method.normal.stderr} (96%) create mode 100644 tests/ui/use/import_trait_associated_functions-2015.rs create mode 100644 tests/ui/use/import_trait_associated_functions.rs diff --git a/compiler/rustc_error_codes/src/error_codes/E0253.md b/compiler/rustc_error_codes/src/error_codes/E0253.md index aea51d402382..705d1bfc53e5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0253.md +++ b/compiler/rustc_error_codes/src/error_codes/E0253.md @@ -1,19 +1,19 @@ -Attempt was made to import an unimportable value. This can happen when trying -to import a method from a trait. +Attempt was made to import an unimportable type. This can happen when trying +to import a type from a trait. Erroneous code example: ```compile_fail,E0253 mod foo { pub trait MyTrait { - fn do_something(); + type SomeType; } } -use foo::MyTrait::do_something; -// error: `do_something` is not directly importable +use foo::MyTrait::SomeType; +// error: `SomeType` is not directly importable fn main() {} ``` -It's invalid to directly import methods belonging to a trait or concrete type. +It's invalid to directly import types belonging to a trait. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index d40823d2ed62..8b5cecc3e4fe 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -519,6 +519,8 @@ declare_features! ( (unstable, impl_trait_in_bindings, "1.64.0", Some(63065)), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)), + /// Allows `use` associated functions from traits. + (unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995)), /// Allow anonymous constants from an inline `const` block in pattern position diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9795299ed6d5..dc26d4de57a7 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1183,7 +1183,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let in_module_is_extern = !in_module.def_id().is_local(); in_module.for_each_child(self, |this, ident, ns, name_binding| { // avoid non-importable candidates - if !name_binding.is_importable() { + if !name_binding.is_importable() + // FIXME(import_trait_associated_functions): remove this when `import_trait_associated_functions` is stable + || name_binding.is_assoc_const_or_fn() + && !this.tcx.features().import_trait_associated_functions() + { return; } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 5b1d8d622bdd..cad45d3c2931 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -17,9 +17,10 @@ use rustc_session::lint::builtin::{ AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS, }; +use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::LocalExpnId; -use rustc_span::{Ident, Span, Symbol, kw}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use smallvec::SmallVec; use tracing::debug; @@ -829,6 +830,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Don't update the resolution, because it was never added. Err(Determined) if target.name == kw::Underscore => {} Ok(binding) if binding.is_importable() => { + if binding.is_assoc_const_or_fn() + && !this.tcx.features().import_trait_associated_functions() + { + feature_err( + this.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } let imported_binding = this.import(binding, import); target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cc9ed566edac..8e457e68eecf 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -920,10 +920,13 @@ impl<'ra> NameBindingData<'ra> { } fn is_importable(&self) -> bool { - !matches!( - self.res(), - Res::Def(DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy, _) - ) + !matches!(self.res(), Res::Def(DefKind::AssocTy, _)) + } + + // FIXME(import_trait_associated_functions): associate `const` or `fn` are not importable unless + // the feature `import_trait_associated_functions` is enable + fn is_assoc_const_or_fn(&self) -> bool { + matches!(self.res(), Res::Def(DefKind::AssocConst | DefKind::AssocFn, _)) } fn macro_kind(&self) -> Option { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4ecc4201f89d..6c2dd1fc5796 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1093,6 +1093,7 @@ symbols! { import, import_name_type, import_shadowing, + import_trait_associated_functions, imported_main, in_band_lifetimes, include, diff --git a/tests/ui/error-codes/E0253.rs b/tests/ui/error-codes/E0253.rs index 284b16da8f22..8284f791c648 100644 --- a/tests/ui/error-codes/E0253.rs +++ b/tests/ui/error-codes/E0253.rs @@ -1,10 +1,10 @@ mod foo { pub trait MyTrait { - fn do_something(); + type SomeType; } } -use foo::MyTrait::do_something; +use foo::MyTrait::SomeType; //~^ ERROR E0253 fn main() {} diff --git a/tests/ui/error-codes/E0253.stderr b/tests/ui/error-codes/E0253.stderr index 4ee36b70fe51..954dbc816939 100644 --- a/tests/ui/error-codes/E0253.stderr +++ b/tests/ui/error-codes/E0253.stderr @@ -1,8 +1,8 @@ -error[E0253]: `do_something` is not directly importable +error[E0253]: `SomeType` is not directly importable --> $DIR/E0253.rs:7:5 | -LL | use foo::MyTrait::do_something; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly +LL | use foo::MyTrait::SomeType; + | ^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs new file mode 100644 index 000000000000..aec13fb02028 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.rs @@ -0,0 +1,63 @@ +//@ edition:2018 +use std::collections::HashMap; + +use A::{DEFAULT, new}; +//~^ ERROR `use` associated items of traits is unstable [E0658] +//~| ERROR `use` associated items of traits is unstable [E0658] +use Default::default; +//~^ ERROR `use` associated items of traits is unstable [E0658] + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + //~^ ERROR `use` associated items of traits is unstable [E0658] + //~| ERROR `use` associated items of traits is unstable [E0658] + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr new file mode 100644 index 000000000000..d342f5bd5512 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-import-trait-associated-functions.stderr @@ -0,0 +1,53 @@ +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:4:9 + | +LL | use A::{DEFAULT, new}; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:4:18 + | +LL | use A::{DEFAULT, new}; + | ^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:7:5 + | +LL | use Default::default; + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:27:26 + | +LL | use super::A::{self, DEFAULT, new}; + | ^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `use` associated items of traits is unstable + --> $DIR/feature-gate-import-trait-associated-functions.rs:27:35 + | +LL | use super::A::{self, DEFAULT, new}; + | ^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/imports/import-trait-method.rs b/tests/ui/imports/import-trait-method.rs index 97dd68f1e76e..a24b3a136444 100644 --- a/tests/ui/imports/import-trait-method.rs +++ b/tests/ui/imports/import-trait-method.rs @@ -2,6 +2,6 @@ trait Foo { fn foo(); } -use Foo::foo; //~ ERROR not directly importable +use Foo::foo; //~ ERROR `use` associated items of traits is unstable [E0658] -fn main() { foo(); } +fn main() { foo(); } //~ ERROR type annotations needed diff --git a/tests/ui/imports/import-trait-method.stderr b/tests/ui/imports/import-trait-method.stderr index 9786eb52d354..8fe774111b96 100644 --- a/tests/ui/imports/import-trait-method.stderr +++ b/tests/ui/imports/import-trait-method.stderr @@ -1,9 +1,22 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/import-trait-method.rs:5:5 | LL | use Foo::foo; - | ^^^^^^^^ cannot be imported directly + | ^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 1 previous error +error[E0283]: type annotations needed + --> $DIR/import-trait-method.rs:7:13 + | +LL | fn main() { foo(); } + | ^^^^^ cannot infer type + | + = note: cannot satisfy `_: Foo` -For more information about this error, try `rustc --explain E0253`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0283, E0658. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr new file mode 100644 index 000000000000..593a90d728fa --- /dev/null +++ b/tests/ui/suggestions/fn-to-method.import_trait_associated_functions.stderr @@ -0,0 +1,39 @@ +error[E0425]: cannot find function `cmp` in this scope + --> $DIR/fn-to-method.rs:12:13 + | +LL | let x = cmp(&1, &2); + | ^^^ not found in this scope + | +help: consider importing one of these associated functions + | +LL + use std::cmp::Ord::cmp; + | +LL + use std::iter::Iterator::cmp; + | + +error[E0425]: cannot find function `len` in this scope + --> $DIR/fn-to-method.rs:16:13 + | +LL | let y = len([1, 2, 3]); + | ^^^ not found in this scope + | +help: consider importing this associated function + | +LL + use std::iter::ExactSizeIterator::len; + | + +error[E0425]: cannot find function `bar` in this scope + --> $DIR/fn-to-method.rs:20:13 + | +LL | let z = bar(Foo); + | ^^^ not found in this scope + | +help: use the `.` operator to call the method `bar` on `Foo` + | +LL - let z = bar(Foo); +LL + let z = Foo.bar(); + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/suggestions/fn-to-method.stderr b/tests/ui/suggestions/fn-to-method.normal.stderr similarity index 96% rename from tests/ui/suggestions/fn-to-method.stderr rename to tests/ui/suggestions/fn-to-method.normal.stderr index 36c17e60d357..502be79481ac 100644 --- a/tests/ui/suggestions/fn-to-method.stderr +++ b/tests/ui/suggestions/fn-to-method.normal.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find function `cmp` in this scope - --> $DIR/fn-to-method.rs:8:13 + --> $DIR/fn-to-method.rs:12:13 | LL | let x = cmp(&1, &2); | ^^^ not found in this scope @@ -10,7 +10,7 @@ LL | let x = (&1).cmp(&2); | ~ ~~~~~~~~~ error[E0425]: cannot find function `len` in this scope - --> $DIR/fn-to-method.rs:12:13 + --> $DIR/fn-to-method.rs:16:13 | LL | let y = len([1, 2, 3]); | ^^^ not found in this scope @@ -22,7 +22,7 @@ LL + let y = [1, 2, 3].len(); | error[E0425]: cannot find function `bar` in this scope - --> $DIR/fn-to-method.rs:16:13 + --> $DIR/fn-to-method.rs:20:13 | LL | let z = bar(Foo); | ^^^ not found in this scope diff --git a/tests/ui/suggestions/fn-to-method.rs b/tests/ui/suggestions/fn-to-method.rs index 9a35c3efc41b..619ac4446494 100644 --- a/tests/ui/suggestions/fn-to-method.rs +++ b/tests/ui/suggestions/fn-to-method.rs @@ -1,4 +1,8 @@ +//@ revisions: normal import_trait_associated_functions +#![cfg_attr(import_trait_associated_functions, feature(import_trait_associated_functions))] struct Foo; +//[import_trait_associated_functions]~^ HELP consider importing one of these associated functions +//[import_trait_associated_functions]~| HELP consider importing this associated function impl Foo { fn bar(self) {} @@ -7,11 +11,11 @@ impl Foo { fn main() { let x = cmp(&1, &2); //~^ ERROR cannot find function `cmp` in this scope - //~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` + //[normal]~| HELP use the `.` operator to call the method `Ord::cmp` on `&{integer}` let y = len([1, 2, 3]); //~^ ERROR cannot find function `len` in this scope - //~| HELP use the `.` operator to call the method `len` on `&[{integer}]` + //[normal]~| HELP use the `.` operator to call the method `len` on `&[{integer}]` let z = bar(Foo); //~^ ERROR cannot find function `bar` in this scope diff --git a/tests/ui/use/import_trait_associated_functions-2015.rs b/tests/ui/use/import_trait_associated_functions-2015.rs new file mode 100644 index 000000000000..3177aeefb097 --- /dev/null +++ b/tests/ui/use/import_trait_associated_functions-2015.rs @@ -0,0 +1,61 @@ +//@ edition:2015 +//@ check-pass +#![feature(import_trait_associated_functions)] + +use std::collections::HashMap; + +use A::{DEFAULT, new}; +use std::default::Default::default; + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/use/import_trait_associated_functions.rs b/tests/ui/use/import_trait_associated_functions.rs new file mode 100644 index 000000000000..4dc473404dbd --- /dev/null +++ b/tests/ui/use/import_trait_associated_functions.rs @@ -0,0 +1,61 @@ +//@ edition:2018 +//@ check-pass +#![feature(import_trait_associated_functions)] + +use std::collections::HashMap; + +use A::{DEFAULT, new}; +use Default::default; + +struct S { + a: HashMap, +} + +impl S { + fn new() -> S { + S { a: default() } + } +} + +trait A: Sized { + const DEFAULT: Option = None; + fn new() -> Self; + fn do_something(&self); +} + +mod b { + use super::A::{self, DEFAULT, new}; + + struct B(); + + impl A for B { + const DEFAULT: Option = Some(B()); + fn new() -> Self { + B() + } + + fn do_something(&self) {} + } + + fn f() { + let b: B = new(); + b.do_something(); + let c: B = DEFAULT.unwrap(); + } +} + +impl A for S { + fn new() -> Self { + S::new() + } + + fn do_something(&self) {} +} + +fn f() { + let s: S = new(); + s.do_something(); + let t: Option = DEFAULT; +} + +fn main() {} diff --git a/tests/ui/use/use-from-trait-xc.rs b/tests/ui/use/use-from-trait-xc.rs index b7b9c834b327..b030892aa269 100644 --- a/tests/ui/use/use-from-trait-xc.rs +++ b/tests/ui/use/use-from-trait-xc.rs @@ -3,13 +3,13 @@ extern crate use_from_trait_xc; use use_from_trait_xc::Trait::foo; -//~^ ERROR `foo` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Trait::Assoc; //~^ ERROR `Assoc` is not directly importable use use_from_trait_xc::Trait::CONST; -//~^ ERROR `CONST` is not directly importable +//~^ ERROR `use` associated items of traits is unstable [E0658] use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private //~^ ERROR unresolved import `use_from_trait_xc::Foo` diff --git a/tests/ui/use/use-from-trait-xc.stderr b/tests/ui/use/use-from-trait-xc.stderr index 4c4c2f6225f1..0f8440aa5307 100644 --- a/tests/ui/use/use-from-trait-xc.stderr +++ b/tests/ui/use/use-from-trait-xc.stderr @@ -1,8 +1,12 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:5:5 | LL | use use_from_trait_xc::Trait::foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0253]: `Assoc` is not directly importable --> $DIR/use-from-trait-xc.rs:8:5 @@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable LL | use use_from_trait_xc::Trait::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly -error[E0253]: `CONST` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait-xc.rs:11:5 | LL | use use_from_trait_xc::Trait::CONST; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0432]: unresolved import `use_from_trait_xc::Foo` --> $DIR/use-from-trait-xc.rs:14:24 @@ -66,5 +74,5 @@ LL | struct Foo; error: aborting due to 9 previous errors -Some errors have detailed explanations: E0253, E0432, E0603. +Some errors have detailed explanations: E0253, E0432, E0603, E0658. For more information about an error, try `rustc --explain E0253`. diff --git a/tests/ui/use/use-from-trait.rs b/tests/ui/use/use-from-trait.rs index eab4bb6e3b5b..89b7aaa4ba38 100644 --- a/tests/ui/use/use-from-trait.rs +++ b/tests/ui/use/use-from-trait.rs @@ -1,6 +1,6 @@ -use Trait::foo; //~ ERROR `foo` is not directly importable +use Trait::foo; //~ ERROR `use` associated items of traits is unstable [E0658] use Trait::Assoc; //~ ERROR `Assoc` is not directly importable -use Trait::C; //~ ERROR `C` is not directly importable +use Trait::C; //~ ERROR `use` associated items of traits is unstable [E0658] use Foo::new; //~ ERROR unresolved import `Foo` [E0432] diff --git a/tests/ui/use/use-from-trait.stderr b/tests/ui/use/use-from-trait.stderr index a5b0e356b34c..2dd78a354529 100644 --- a/tests/ui/use/use-from-trait.stderr +++ b/tests/ui/use/use-from-trait.stderr @@ -1,8 +1,12 @@ -error[E0253]: `foo` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:1:5 | LL | use Trait::foo; - | ^^^^^^^^^^ cannot be imported directly + | ^^^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0253]: `Assoc` is not directly importable --> $DIR/use-from-trait.rs:2:5 @@ -10,11 +14,15 @@ error[E0253]: `Assoc` is not directly importable LL | use Trait::Assoc; | ^^^^^^^^^^^^ cannot be imported directly -error[E0253]: `C` is not directly importable +error[E0658]: `use` associated items of traits is unstable --> $DIR/use-from-trait.rs:3:5 | LL | use Trait::C; - | ^^^^^^^^ cannot be imported directly + | ^^^^^^^^ + | + = note: see issue #134691 for more information + = help: add `#![feature(import_trait_associated_functions)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0432]: unresolved import `Foo` --> $DIR/use-from-trait.rs:5:5 @@ -30,5 +38,5 @@ LL | use Foo::C2; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0253, E0432. +Some errors have detailed explanations: E0253, E0432, E0658. For more information about an error, try `rustc --explain E0253`.